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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the issue is that veclower gets to see

-  _3 = { 8, 8 };
-  _4 = _3 != { 0, 0 };
   _5 = VEC_COND_EXPR <_4, { -1, -1 }, { 0, 0 }>;

while ISEL sees

+  _4 = { -1, -1 };
   _5 = VEC_COND_EXPR <_4, { -1, -1 }, { 0, 0 }>;

now, the issue is the target doesn't support the _4 < {0, 0} we fake
but it would support _4 != { 0, 0 }.  The expansion code already handles
this, but only for literal constants:

  icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
  if (icode == CODE_FOR_nothing)
    {
      if (tcode == LT_EXPR
          && op0a == op0
          && TREE_CODE (op0) == VECTOR_CST)
        {
          /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR
             into a constant when only get_vcond_eq_icode is supported.
             Verify < 0 and != 0 behave the same and change it to NE_EXPR.  */
...

I'm not sure why the code is restrictive as it is - we always will have
a vector boolean operand for the mask which means the only valid values
are -1 and 0 and thus using NE_EXPR should be always valid.  In fact the
verification code will ICE when we cannot use NE_EXPR so it should also
work for non-constant ops.

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index b330cf4c20e..97922632afd 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -138,22 +138,11 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
   if (icode == CODE_FOR_nothing)
     {
       if (tcode == LT_EXPR
-         && op0a == op0
-         && TREE_CODE (op0) == VECTOR_CST)
+         && op0a == op0)
        {
          /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR
             into a constant when only get_vcond_eq_icode is supported.
-            Verify < 0 and != 0 behave the same and change it to NE_EXPR.  */
-         unsigned HOST_WIDE_INT nelts;
-         if (!VECTOR_CST_NELTS (op0).is_constant (&nelts))
-           {
-             if (VECTOR_CST_STEPPED_P (op0))
-               gcc_unreachable ();
-             nelts = vector_cst_encoded_nelts (op0);
-           }
-         for (unsigned int i = 0; i < nelts; ++i)
-           if (tree_int_cst_sgn (vector_cst_elt (op0, i)) == 1)
-             gcc_unreachable ();
+            Try changing it to NE_EXPR.  */
          tcode = NE_EXPR;
        }
       if (tcode == EQ_EXPR || tcode == NE_EXPR)

fixes the testcase.

Reply via email to