re PR tree-optimization/87546 (Gcc miscompiles at -O3 on valid code)
authorJakub Jelinek <jakub@redhat.com>
Sat, 17 Nov 2018 15:10:48 +0000 (16:10 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 17 Nov 2018 15:10:48 +0000 (16:10 +0100)
PR tree-optimization/87546
* tree-vect-patterns.c (vect_look_through_possible_promotion): Add
min_precision variable, initially set it to orig_precision, only does
something if op_type's precision is <= min_precision and update
min_precision whenever calling set_op.

* gcc.dg/vect/O3-pr87546.c: New test.

From-SVN: r266237

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/O3-pr87546.c [new file with mode: 0644]
gcc/tree-vect-patterns.c

index a6097fde67c29099fd0fa16567fdd9974f7f8bf5..3392f8f498a0e7b50dd98c63c004a5ea4563c873 100644 (file)
@@ -1,3 +1,11 @@
+2018-11-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/87546
+       * tree-vect-patterns.c (vect_look_through_possible_promotion): Add
+       min_precision variable, initially set it to orig_precision, only does
+       something if op_type's precision is <= min_precision and update
+       min_precision whenever calling set_op.
+
 2018-11-16  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/87957
index d0a237beca36a72549c001df3f0128927175b99a..30386c6fa8949c999316213ca22d593e29353ccb 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/87546
+       * gcc.dg/vect/O3-pr87546.c: New test.
+
 2018-11-17  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
        PR middle-end/87854
diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr87546.c b/gcc/testsuite/gcc.dg/vect/O3-pr87546.c
new file mode 100644 (file)
index 0000000..0d3b714
--- /dev/null
@@ -0,0 +1,29 @@
+#include "tree-vect.h"
+
+int a;
+long b, f;
+signed char c, g;
+short int d = 219;
+int e[64];
+
+__attribute__((noipa)) void
+foo (void)
+{
+  asm volatile ("" : : "g" (&a), "g" (&d) : "memory");
+  for (c = 0; c < 64; c++)
+    {
+      g = d < 0 ? d : d >> a;
+      f = g + b;
+      e[c] = f;
+    }
+  if (e[1] != (signed char) d)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  check_vect ();
+  foo ();
+  return 0;
+}
index 3053642b24108350d092fb6955beb5f9752086ca..2b56d85afc5962df3939befb40f7d81bc121ef7b 100644 (file)
@@ -367,6 +367,7 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op,
   tree res = NULL_TREE;
   tree op_type = TREE_TYPE (op);
   unsigned int orig_precision = TYPE_PRECISION (op_type);
+  unsigned int min_precision = orig_precision;
   stmt_vec_info caster = NULL;
   while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type))
     {
@@ -385,7 +386,7 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op,
         This copes with cases such as the result of an arithmetic
         operation being truncated before being stored, and where that
         arithmetic operation has been recognized as an over-widened one.  */
-      if (TYPE_PRECISION (op_type) <= orig_precision)
+      if (TYPE_PRECISION (op_type) <= min_precision)
        {
          /* Use OP as the UNPROM described above if we haven't yet
             found a promotion, or if using the new input preserves the
@@ -393,7 +394,10 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op,
          if (!res
              || TYPE_PRECISION (unprom->type) == orig_precision
              || TYPE_SIGN (unprom->type) == TYPE_SIGN (op_type))
-           unprom->set_op (op, dt, caster);
+           {
+             unprom->set_op (op, dt, caster);
+             min_precision = TYPE_PRECISION (op_type);
+           }
          /* Stop if we've already seen a promotion and if this
             conversion does more than change the sign.  */
          else if (TYPE_PRECISION (op_type)