re PR tree-optimization/80620 (gcc produces wrong code with -O3)
authorRichard Biener <rguenther@suse.de>
Tue, 18 Jul 2017 07:35:40 +0000 (07:35 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 18 Jul 2017 07:35:40 +0000 (07:35 +0000)
2017-07-18  Richard Biener  <rguenther@suse.de>

PR tree-optimization/80620
PR tree-optimization/81403
* tree-ssa-pre.c (phi_translate_1): Clear range and points-to
info when re-using a VN table entry.

* gcc.dg/torture/pr80620.c: New testcase.
* gcc.dg/torture/pr81403.c: Likewise.

From-SVN: r250297

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr80620.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr81403.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index dab4a95222998c3f01caf2750bf9fd37c8126e93..c6e118f1b95daebee4ee7d7aee657cbfc4edad33 100644 (file)
@@ -1,4 +1,11 @@
-2017-06-18  Richard Biener  <rguenther@suse.de>
+2017-07-18  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/80620
+       PR tree-optimization/81403
+       * tree-ssa-pre.c (phi_translate_1): Clear range and points-to
+       info when re-using a VN table entry.
+
+2017-07-18  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81418
        * tree-vect-loop.c (vectorizable_reduction): Properly compute
index 10951f51d4ada1f406795c44e6748c36b3a58100..e80871890076a34e00502f44d4bdf5c228d385dd 100644 (file)
@@ -1,4 +1,11 @@
-2017-06-18  Richard Biener  <rguenther@suse.de>
+2017-07-18  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/80620
+       PR tree-optimization/81403
+       * gcc.dg/torture/pr80620.c: New testcase.
+       * gcc.dg/torture/pr81403.c: Likewise.
+
+2017-07-18  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81418
        * gcc.dg/torture/pr81418.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr80620.c b/gcc/testsuite/gcc.dg/torture/pr80620.c
new file mode 100644 (file)
index 0000000..ef56eed
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+long long int a = -465274079317386463LL;
+int b = 856872806;
+int c = -1940894202;
+int d = 1718449211;
+int e = -392681565;
+unsigned long long int f = 13521452247506316486ULL;
+int g = -13194608;
+
+__attribute__((noinline, noclone))
+void foo ()
+{
+  if (!a - a)
+    c = b = 0;
+  else
+    d = 3UL * a == 0;
+  if (g / a)
+    e = 0 < -a + 500849970701012771LL + (unsigned long) -a;
+  else
+    f = 4081116982543369LL & a;
+}
+
+int
+main ()
+{
+  asm volatile ("" : : : "memory");
+  foo ();
+  if (f != 2818598057803777LL)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr81403.c b/gcc/testsuite/gcc.dg/torture/pr81403.c
new file mode 100644 (file)
index 0000000..5fca4d4
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+short var_9 = 19581;
+unsigned char var_33 = 21;
+long long int var_55 = 286697804684061197LL;
+long long int var_59 = -1962393262513510540LL;
+long long int var_71 = 4731868609112929952LL;
+long long int var_773 = -4784633456247777769LL;
+short var_776 = 5894;
+long long int var_1321 = 7573221950916697355LL;
+unsigned char uc = 217;
+
+void foo()
+{
+  if (var_55)
+    var_71 = 0;
+  if (var_9 != ~(0 < uc))
+    var_773 = 0;
+  else
+    var_776 = 1 / ~var_9 * -1;
+  if (var_33)
+    var_59 = ~var_9 & 10393;
+  var_1321 = ~var_9;
+}
+int main()
+{
+  foo();
+  if (var_59 != 8320)
+    __builtin_abort ();
+  return 0;
+}
index 2a431c96f7fe9e57b7097431fdf4ef24227a791c..0ec3d3c7f7e0b80c3bd706134f2e09df2fe73844 100644 (file)
@@ -1489,6 +1489,45 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
                PRE_EXPR_NARY (expr) = nary;
                new_val_id = nary->value_id;
                get_or_alloc_expression_id (expr);
+               /* When we end up re-using a value number make sure that
+                  doesn't have unrelated (which we can't check here)
+                  range or points-to info on it.  */
+               if (result
+                   && INTEGRAL_TYPE_P (TREE_TYPE (result))
+                   && SSA_NAME_RANGE_INFO (result)
+                   && ! SSA_NAME_IS_DEFAULT_DEF (result))
+                 {
+                   if (! VN_INFO (result)->info.range_info)
+                     {
+                       VN_INFO (result)->info.range_info
+                         = SSA_NAME_RANGE_INFO (result);
+                       VN_INFO (result)->range_info_anti_range_p
+                         = SSA_NAME_ANTI_RANGE_P (result);
+                     }
+                   if (dump_file && (dump_flags & TDF_DETAILS))
+                     {
+                       fprintf (dump_file, "clearing range info of ");
+                       print_generic_expr (dump_file, result);
+                       fprintf (dump_file, "\n");
+                     }
+                   SSA_NAME_RANGE_INFO (result) = NULL;
+                 }
+               else if (result
+                        && POINTER_TYPE_P (TREE_TYPE (result))
+                        && SSA_NAME_PTR_INFO (result)
+                        && ! SSA_NAME_IS_DEFAULT_DEF (result))
+                 {
+                   if (! VN_INFO (result)->info.ptr_info)
+                     VN_INFO (result)->info.ptr_info
+                       = SSA_NAME_PTR_INFO (result);
+                   if (dump_file && (dump_flags & TDF_DETAILS))
+                     {
+                       fprintf (dump_file, "clearing points-to info of ");
+                       print_generic_expr (dump_file, result);
+                       fprintf (dump_file, "\n");
+                     }
+                   SSA_NAME_PTR_INFO (result) = NULL;
+                 }
              }
            else
              {