https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97085

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
#1  0x00000000015c8944 in gimple_expand_vec_cond_expr (gsi=0x7fffffffda50, 
    vec_cond_ssa_name_uses=0x7fffffffda20)
    at ../../src/trunk/gcc/gimple-isel.cc:133
133       gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE
(cmp_op_mode))
(gdb) p mode
$2 = E_VNx8BImode
(gdb) p cmp_op_mode
$3 = E_VNx8HImode
(gdb) p debug_gimple_stmt (stmt)
mask__31.28_102 = VEC_COND_EXPR <mask__23.26_97, { 0, ... }, { -1, ... }>;

So veclower got to see

  vect_cst__96 = { 5, ... };
  vect_cst__98 = { 1, ... };
  vect_cst__99 = { 0, ... };
...
  mask__23.26_97 = vect__50.25_95 == vect_cst__96;
  vect_patt_61.27_100 = VEC_COND_EXPR <mask__23.26_97, vect_cst__98,
vect_cst__99>;
  mask__31.28_102 = vect_patt_61.27_100 == vect_cst__101;

and in VRP2 we fold this to

  mask__31.28_102 = VEC_COND_EXPR <mask__23.26_97, { 0, ... }, { -1, ... }>;

feeding

  vect_patt_63.29_105 = VEC_COND_EXPR <mask__31.28_102, { 1, ... }, { 0, ...
}>;

so it seems to me we're missing to fold the mask__31.28_102 def to a
mask negation (it's of type vector([8,8]) <signed-boolean:2> mask__31.28).

At least we're not at all expecting to have a VEC_COND_EXPR where
the comparison feeding the mask has different operand modes than the
VEC_COND_EXPR result mode.  But we don't really expect a VEC_COND_EXPR
to have VECTOR_BOOLEAN_TYPE ...

So we could either handle this specially and ISEL it to a compare or a
mask inversion or avoid such folding.  For example

diff --git a/gcc/match.pd b/gcc/match.pd
index 7d63bb973cb..ff19b1cbeb4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3465,22 +3465,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (op (vec_cond:s @0 @1 @2))
   (vec_cond @0 (op! @1) (op! @2))))

-/* Sink binary operation to branches, but only if we can fold it.  */
+/* Sink binary operation to branches, but only if we can fold it.  Avoid
+   VEC_COND_EXPRs with boolean vector result.  */
 (for op (tcc_comparison plus minus mult bit_and bit_ior bit_xor
         rdiv trunc_div ceil_div floor_div round_div
         trunc_mod ceil_mod floor_mod round_mod min max)
-/* (c ? a : b) op (c ? d : e)  -->  c ? (a op d) : (b op e) */
- (simplify
-  (op (vec_cond:s @0 @1 @2) (vec_cond:s @0 @3 @4))
-  (vec_cond @0 (op! @1 @3) (op! @2 @4)))
+ (if (!VECTOR_BOOLEAN_TYPE_P (type))
+  /* (c ? a : b) op (c ? d : e)  -->  c ? (a op d) : (b op e) */
+  (simplify
+   (op (vec_cond:s @0 @1 @2) (vec_cond:s @0 @3 @4))
+   (vec_cond @0 (op! @1 @3) (op! @2 @4)))

-/* (c ? a : b) op d  -->  c ? (a op d) : (b op d) */
- (simplify
-  (op (vec_cond:s @0 @1 @2) @3)
-  (vec_cond @0 (op! @1 @3) (op! @2 @3)))
- (simplify
-  (op @3 (vec_cond:s @0 @1 @2))
-  (vec_cond @0 (op! @3 @1) (op! @3 @2))))
+  /* (c ? a : b) op d  -->  c ? (a op d) : (b op d) */
+  (simplify
+   (op (vec_cond:s @0 @1 @2) @3)
+   (vec_cond @0 (op! @1 @3) (op! @2 @3)))
+  (simplify
+   (op @3 (vec_cond:s @0 @1 @2))
+   (vec_cond @0 (op! @3 @1) (op! @3 @2)))))
 #endif

fixes this particular testcase (but there are more patterns producing
vec_cond exprs).  We'd also want to add verification if we do not want
VECTOR_BOOLEAN_TYPE_P VEC_COND_EXPR.

Reply via email to