RISC-V: Mask values before initializing bitmask vector [PR119114].
In the somewhat convoluted vector code of PR119114 we extract a <signed-boolean:1> mask value from a vector mask. After some middle-end simplifications we end up with a value of -2. Its lowest bit is correctly unset representing "false". When initializing a bitmak vector from values we compare the full value/register against zero instead of just the last bit. This causes erroneous mask values. This patch masks the values by & 0x1 before comparing against 0. PR target/119114 gcc/ChangeLog: * config/riscv/autovec.md: Apply & 0x1 mask when initializing bitmask vector. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr119114.c: New test.
This commit is contained in:
parent
f4f7216c56
commit
b58a0af4e2
2 changed files with 50 additions and 1 deletions
|
@ -405,16 +405,28 @@
|
|||
|
||||
;; Provide a vec_init for mask registers by initializing
|
||||
;; a QImode vector and comparing it against 0.
|
||||
;; As we need to ignore all but the lowest bit apply an AND mask
|
||||
;; before doing the comparison.
|
||||
(define_expand "vec_init<mode>qi"
|
||||
[(match_operand:VB 0 "register_operand")
|
||||
(match_operand 1 "")]
|
||||
"TARGET_VECTOR"
|
||||
{
|
||||
/* Expand into a QImode vector. */
|
||||
machine_mode qimode = riscv_vector::get_vector_mode
|
||||
(QImode, GET_MODE_NUNITS (<MODE>mode)).require ();
|
||||
rtx tmp = gen_reg_rtx (qimode);
|
||||
riscv_vector::expand_vec_init (tmp, operands[1]);
|
||||
riscv_vector::expand_vec_cmp (operands[0], NE, tmp, CONST0_RTX (qimode));
|
||||
|
||||
/* & 0x1. */
|
||||
insn_code icode = code_for_pred (AND, qimode);
|
||||
rtx tmp2 = gen_reg_rtx (qimode);
|
||||
rtx ones = gen_const_vec_duplicate (qimode, GEN_INT (1));
|
||||
rtx ops[] = {tmp2, tmp, ones};
|
||||
riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops);
|
||||
|
||||
/* Compare against zero. */
|
||||
riscv_vector::expand_vec_cmp (operands[0], NE, tmp2, CONST0_RTX (qimode));
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
|
37
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr119114.c
Normal file
37
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr119114.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target riscv_v_ok } */
|
||||
/* { dg-require-effective-target rv64 } */
|
||||
/* { dg-add-options riscv_v } */
|
||||
/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -std=gnu99 -fwhole-program -mrvv-vector-bits=zvl" } */
|
||||
|
||||
_Bool a;
|
||||
short b[18];
|
||||
long long al;
|
||||
_Bool e;
|
||||
char f = 010;
|
||||
short t[18];
|
||||
unsigned short w[8][18][18][18];
|
||||
|
||||
void
|
||||
c (_Bool e, char f, short t[], unsigned short w[][18][18][18])
|
||||
{
|
||||
for (int ae = 1; ae < f + 5; ae += 2)
|
||||
{
|
||||
a -= (_Bool) (t[ae - 1] & t[ae + 3]);
|
||||
for (short af = 0; af < 18; af += 2)
|
||||
for (_Bool ah = 0; ah < (w[e][1][af][0] > 0); ah = 5)
|
||||
b[af] |= 9;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
for (int ad = 0; ad < 18; ad++)
|
||||
t[ad] = 3;
|
||||
|
||||
c (e, f, t, w);
|
||||
al = a;
|
||||
if (al != 0)
|
||||
__builtin_abort ();
|
||||
}
|
Loading…
Add table
Reference in a new issue