re PR tree-optimization/86076 (ICE: verify_gimple failed (error: location references...
authorRichard Biener <rguenther@suse.de>
Fri, 15 Jun 2018 07:25:13 +0000 (07:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 15 Jun 2018 07:25:13 +0000 (07:25 +0000)
2018-06-15  Richard Biener  <rguenther@suse.de>

PR middle-end/86076
* tree-cfg.c (move_stmt_op): unshare invariant addresses
before adjusting their block.

* gcc.dg/pr86076.c: New testcase.

From-SVN: r261620

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr86076.c [new file with mode: 0644]
gcc/tree-cfg.c

index e9499b24d7965d10bd7caabe00198e22b72cf4e0..8f95eb582f77dc675ec891424aa217c34c6d967c 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-15  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/86076
+       * tree-cfg.c (move_stmt_op): unshare invariant addresses
+       before adjusting their block.
+
 2018-06-15  Sebastian Huber  <sebastian.huber@embedded-brains.de>
 
        * config.gcc (riscv*-*-elf* | riscv*-*-rtems*): Use custom
index 94c4fcaa11f6e5c3c29bce2aecce866d7c47c11c..04278c6dcf0fd0087df9361153f60f31baf65c57 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-15  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/86076
+       * gcc.dg/pr86076.c: New testcase.
+
 2018-06-14  Marek Polacek  <polacek@redhat.com>
 
        PR c++/86063
diff --git a/gcc/testsuite/gcc.dg/pr86076.c b/gcc/testsuite/gcc.dg/pr86076.c
new file mode 100644 (file)
index 0000000..019ced3
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fno-tree-dce -fno-tree-pre -fno-tree-vrp --param max-loop-header-insns=1" } */
+
+int __attribute__ ((noinline))
+lv (int tm)
+{
+  (void) tm;
+
+  return 0;
+}
+
+void
+o7 (int uu)
+{
+  while (uu < 1)
+    while (uu != 0)
+      {
+       short int ca;
+
+       ca = lv (0);
+       (void) ca;
+       ++uu;
+      }
+
+  lv (lv (0));
+}
index 21b3fdffa59382280fa99c1276c1252c88a7e75d..78d80b00045ed6ffb61765f519b9fc1029af2a07 100644 (file)
@@ -6745,7 +6745,16 @@ move_stmt_op (tree *tp, int *walk_subtrees, void *data)
        ;
       else if (block == p->orig_block
               || p->orig_block == NULL_TREE)
-       TREE_SET_BLOCK (t, p->new_block);
+       {
+         /* tree_node_can_be_shared says we can share invariant
+            addresses but unshare_expr copies them anyways.  Make sure
+            to unshare before adjusting the block in place - we do not
+            always see a copy here.  */
+         if (TREE_CODE (t) == ADDR_EXPR
+             && is_gimple_min_invariant (t))
+           *tp = t = unshare_expr (t);
+         TREE_SET_BLOCK (t, p->new_block);
+       }
       else if (flag_checking)
        {
          while (block && TREE_CODE (block) == BLOCK && block != p->orig_block)