re PR middle-end/91623 (-msse4.1 -O3 segfault in /usr/lib/gcc/x86_64-pc-linux-gnu...
authorJakub Jelinek <jakub@redhat.com>
Sun, 1 Sep 2019 11:57:10 +0000 (13:57 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sun, 1 Sep 2019 11:57:10 +0000 (13:57 +0200)
PR middle-end/91623
* optabs.c (expand_vec_cond_expr): If op0 is a VECTOR_CST and only
EQ_EXPR/NE_EXPR is supported, verify that op0 only contains
zeros or negative elements and use NE_EXPR instead of LT_EXPR against
zero vector.

* gcc.target/i386/pr91623.c: New test.

From-SVN: r275267

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr91623.c [new file with mode: 0644]

index d684c76..6c43782 100644 (file)
@@ -1,5 +1,11 @@
 2019-09-01  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/91623
+       * optabs.c (expand_vec_cond_expr): If op0 is a VECTOR_CST and only
+       EQ_EXPR/NE_EXPR is supported, verify that op0 only contains
+       zeros or negative elements and use NE_EXPR instead of LT_EXPR against
+       zero vector.
+
        PR lto/91572
        * tree.c (find_decls_types_in_node): Also walk TREE_PURPOSE of
        GIMPLE_ASM TREE_LIST operands.
index 9e54dda..cdd07f3 100644 (file)
@@ -5868,6 +5868,25 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
   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.  */
+         unsigned HOST_WIDE_INT nelts;
+         if (!VECTOR_CST_NELTS (op0).is_constant (&nelts))
+           {
+             if (VECTOR_CST_STEPPED_P (op0))
+               return 0;
+             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)
+             return 0;
+         tcode = NE_EXPR;
+       }
       if (tcode == EQ_EXPR || tcode == NE_EXPR)
        icode = get_vcond_eq_icode (mode, cmp_op_mode);
       if (icode == CODE_FOR_nothing)
index acb729d..aa73312 100644 (file)
@@ -1,5 +1,8 @@
 2019-09-01  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/91623
+       * gcc.target/i386/pr91623.c: New test.
+
        PR lto/91572
        * g++.dg/lto/pr91572_0.C: New test.
 
diff --git a/gcc/testsuite/gcc.target/i386/pr91623.c b/gcc/testsuite/gcc.target/i386/pr91623.c
new file mode 100644 (file)
index 0000000..94de4f9
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR middle-end/91623 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -msse4.1 -mno-sse4.2" } */
+
+typedef long long V __attribute__((__vector_size__(16)));
+V e, h;
+int d;
+const int i;
+
+void foo (void);
+
+void
+bar (int k, int l)
+{
+  if (d && 0 <= k - 1 && l)
+    foo ();
+}
+
+void
+baz (void)
+{
+  V n = (V) { 1 };
+  V g = (V) {};
+  V o = g;
+  for (int f = 0; f < i; ++f)
+    {
+      V a = o == n;
+      h = a;
+      bar (f, i);
+      o = e;
+    }
+}