;; 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;
}
)
--- /dev/null
+/* { 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 ();
+}