]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR rtl-optimization/51767 (ICE with degenerated asm goto)
authorJakub Jelinek <jakub@redhat.com>
Thu, 9 Feb 2012 21:36:54 +0000 (22:36 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 9 Feb 2012 21:36:54 +0000 (22:36 +0100)
Backported from mainline
2012-01-05  Jakub Jelinek  <jakub@redhat.com>

PR rtl-optimization/51767
* cfgrtl.c (force_nonfallthru_and_redirect): Force addition
of jump_block and add an extra edge for degenerated asm gotos.

* gcc.c-torture/compile/pr51767.c: New test.

From-SVN: r184072

gcc/ChangeLog
gcc/cfgrtl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr51767.c [new file with mode: 0644]

index b71e79facaf3a2f400320039d4488ab58cdb57ce..fe4c69ef8ae9663bd3e801886a1d4fe14b06ca2d 100644 (file)
@@ -3,6 +3,10 @@
        Backported from mainline
        2012-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/51767
+       * cfgrtl.c (force_nonfallthru_and_redirect): Force addition
+       of jump_block and add an extra edge for degenerated asm gotos.
+
        PR middle-end/51768
        * stmt.c (check_unique_operand_names): Don't ICE during error
        reporting if i is from labels chain.
index db2c56e7ae61bf5598b0ead550ad66369588f601..814ad7846f42c5e51fec4c973c1875e87ea9f485 100644 (file)
@@ -1116,6 +1116,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
   rtx note;
   edge new_edge;
   int abnormal_edge_flags = 0;
+  bool asm_goto_edge = false;
   int loc;
 
   /* In the case the last instruction is conditional jump to the next
@@ -1195,8 +1196,28 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
        }
     }
 
-  if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags)
+  /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
+     don't point to target label.  */
+  if (JUMP_P (BB_END (e->src))
+      && target != EXIT_BLOCK_PTR
+      && e->dest == target
+      && (e->flags & EDGE_FALLTHRU)
+      && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
     {
+      int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+
+      for (i = 0; i < n; ++i)
+       if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
+         {
+           asm_goto_edge = true;
+           break;
+         }
+    }
+
+  if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
+    {
+      gcov_type count = e->count;
+      int probability = e->probability;
       /* Create the new structures.  */
 
       /* If the old block ended with a tablejump, skip its table
@@ -1207,7 +1228,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
       note = NEXT_INSN (note);
 
       jump_block = create_basic_block (note, NULL, e->src);
-      jump_block->count = e->count;
+      jump_block->count = count;
       jump_block->frequency = EDGE_FREQUENCY (e);
       jump_block->loop_depth = target->loop_depth;
 
@@ -1223,13 +1244,27 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
 
       /* Wire edge in.  */
       new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
-      new_edge->probability = e->probability;
-      new_edge->count = e->count;
+      new_edge->probability = probability;
+      new_edge->count = count;
 
       /* Redirect old edge.  */
       redirect_edge_pred (e, jump_block);
       e->probability = REG_BR_PROB_BASE;
 
+      /* If asm goto has any label refs to target's label,
+        add also edge from asm goto bb to target.  */
+      if (asm_goto_edge)
+       {
+         new_edge->probability /= 2;
+         new_edge->count /= 2;
+         jump_block->count /= 2;
+         jump_block->frequency /= 2;
+         new_edge = make_edge (new_edge->src, target,
+                               e->flags & ~EDGE_FALLTHRU);
+         new_edge->probability = probability - probability / 2;
+         new_edge->count = count - count / 2;
+       }
+
       new_bb = jump_block;
     }
   else
index 9f0b74bd688398c12fd302754f15d9d30d1bff89..1c950d84b858801f98eb4c442e16abe24390a1a7 100644 (file)
@@ -3,6 +3,9 @@
        Backported from mainline
        2012-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/51767
+       * gcc.c-torture/compile/pr51767.c: New test.
+
        PR middle-end/51768
        * c-c++-common/pr51768.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51767.c b/gcc/testsuite/gcc.c-torture/compile/pr51767.c
new file mode 100644 (file)
index 0000000..62a192d
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/51767 */
+
+extern void fn1 (void), fn2 (void);
+
+static inline __attribute__((always_inline)) int
+foo (int *x, long y)
+{
+  asm goto ("" : : "r" (x), "r" (y) : "memory" : lab);
+  return 0;
+lab:
+  return 1;
+}
+
+void
+bar (int *x)
+{
+  if (foo (x, 23))
+    fn1 ();
+  else
+    fn2 ();
+
+  foo (x, 2);
+}