re PR tree-optimization/70740 (ICE when compiling the Linux kernel (net/wireless...
authorRichard Biener <rguenther@suse.de>
Fri, 22 Apr 2016 06:59:32 +0000 (06:59 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 22 Apr 2016 06:59:32 +0000 (06:59 +0000)
2016-04-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/70740
* tree-ssa-phiprop.c (propagate_with_phi): Handle inserted
VDEF.

* gcc.dg/torture/pr70740.c: New testcase.

From-SVN: r235359

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr70740.c [new file with mode: 0644]
gcc/tree-ssa-phiprop.c

index 06ff30c..d0aeef4 100644 (file)
@@ -1,3 +1,9 @@
+2016-04-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/70740
+       * tree-ssa-phiprop.c (propagate_with_phi): Handle inserted
+       VDEF.
+
 2016-04-21  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/70750
index 38b18c9..e5eff26 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/70740
+       * gcc.dg/torture/pr70740.c: New testcase.
+
 2016-04-21  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/70750
diff --git a/gcc/testsuite/gcc.dg/torture/pr70740.c b/gcc/testsuite/gcc.dg/torture/pr70740.c
new file mode 100644 (file)
index 0000000..5bf8e4a
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+
+extern int foo (void);
+extern void *memcpy (void *, const void *, __SIZE_TYPE__);
+
+struct
+{
+  char a[6];
+} d;
+struct
+{
+  int a1[0];
+  int a2[0];
+  int a3[0];
+  int a4[];
+} a, c;
+int b;
+
+int *
+bar ()
+{
+  if (b)
+    return a.a4;
+  return a.a2;
+}
+
+void
+baz ()
+{
+  int *e, *f;
+  if (foo ())
+    e = c.a3;
+  else
+    e = c.a1;
+  memcpy (d.a, e, 6);
+  f = bar ();
+  memcpy (d.a, f, 1);
+}
index 97e5663..80d2fc4 100644 (file)
@@ -327,13 +327,15 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
        continue;
 
       /* Check if we can move the loads.  The def stmt of the virtual use
-        needs to be in a different basic block dominating bb.  */
+        needs to be in a different basic block dominating bb.  When the
+        def is an edge-inserted one we know it dominates us.  */
       vuse = gimple_vuse (use_stmt);
       def_stmt = SSA_NAME_DEF_STMT (vuse);
       if (!SSA_NAME_IS_DEFAULT_DEF (vuse)
          && (gimple_bb (def_stmt) == bb
-             || !dominated_by_p (CDI_DOMINATORS,
-                                 bb, gimple_bb (def_stmt))))
+             || (gimple_bb (def_stmt)
+                 && !dominated_by_p (CDI_DOMINATORS,
+                                     bb, gimple_bb (def_stmt)))))
        goto next;
 
       /* Found a proper dereference with an aggregate copy.  Just