[PR67828] don't unswitch on default defs of non-parms
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 9 Oct 2015 12:18:24 +0000 (12:18 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 9 Oct 2015 12:18:24 +0000 (12:18 +0000)
for  gcc/ChangeLog

PR rtl-optimizatoin/67828
* tree-ssa-loop-unswitch.c: Include tree-ssa.h.
(tree_may_unswitch_on): Don't unswitch on expressions
involving undefined values.

for  gcc/testsuite/ChangeLog

PR rtl-optimization/67828
* gcc.dg/torture/pr67828.c: New.

From-SVN: r228650

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr67828.c [new file with mode: 0644]
gcc/tree-ssa-loop-unswitch.c

index 11c3b47b9d949acfb4ca6033fb231bd887ad249f..e31c1800002bd48236cffd6b581690142fcbf440 100644 (file)
@@ -1,3 +1,10 @@
+2015-10-09  Alexandre Oliva <aoliva@redhat.com>
+
+       PR rtl-optimization/67828
+       * tree-ssa-loop-unswitch.c: Include tree-ssa.h.
+       (tree_may_unswitch_on): Don't unswitch on expressions
+       involving undefined values.
+
 2015-10-09  Richard Biener  <rguenther@suse.de>
 
        * genmatch.c (print_operand): Fix formatting.
index 84720481b177ccd5d9576661b865d82541bc5857..e5673bd184621ad752ddab99c73e6c26937a0798 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-09  Alexandre Oliva <aoliva@redhat.com>
+
+       PR rtl-optimization/67828
+       * gcc.dg/torture/pr67828.c: New.
+
 2015-10-09  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        PR target/67366
diff --git a/gcc/testsuite/gcc.dg/torture/pr67828.c b/gcc/testsuite/gcc.dg/torture/pr67828.c
new file mode 100644 (file)
index 0000000..c7b6965
--- /dev/null
@@ -0,0 +1,43 @@
+/* Check that we don't misoptimize the final value of d.  We used to
+   apply loop unswitching on if(j), introducing undefined behavior
+   that the original code wouldn't exercise, and this undefined
+   behavior would get later passes to misoptimize the loop.  */
+
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int x;
+
+int __attribute__ ((noinline, noclone))
+xprintf (int d) {
+  if (d)
+    {
+      if (x)
+       printf ("%d", d);
+      abort ();
+    }
+}
+
+int a, b;
+short c;
+
+int
+main ()
+{
+  int j, d = 1;
+  for (; c >= 0; c++)
+    {
+      a = d;
+      d = 0;
+      if (b)
+       {
+         xprintf (0);
+         if (j)
+           xprintf (0);
+       }
+    }
+  xprintf (d);
+  exit (0);
+}
index 4328d6ae6de2393acbae223ebf70769dae64f47e..d6faa378ba824f4fd5035c27734aaeac77809085 100644 (file)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "internal-fn.h"
 #include "gimplify.h"
 #include "tree-cfg.h"
+#include "tree-ssa.h"
 #include "tree-ssa-loop-niter.h"
 #include "tree-ssa-loop.h"
 #include "tree-into-ssa.h"
@@ -139,6 +140,10 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop)
   /* Condition must be invariant.  */
   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
     {
+      /* Unswitching on undefined values would introduce undefined
+        behavior that the original program might never exercise.  */
+      if (ssa_undefined_value_p (use, true))
+       return NULL_TREE;
       def = SSA_NAME_DEF_STMT (use);
       def_bb = gimple_bb (def);
       if (def_bb