Hi!

The following testcase ICEs on arm, because ifcvt decides to conditionalize
a frame related instruction that restores a call saved register and adjusts
stack pointer (== CFA) in order to merge shrink-wrapped and
non-shrink-wrapped basic blocks.  I don't see a way how to conditionalize
DW_CFA_restore in DWARF[234] unwind info, and while for the CFA adjustment
one perhaps could emit conditional expression, not sure if the condition
register is easily expressible in unwind info and whether it won't be
clobbered by later instructions.

So, this patch just refuses to put COND_EXEC on frame related instructions.

Kyrill has kindly bootstrapped/regtested this on arm, ok for trunk?

2014-01-30  Jakub Jelinek  <ja...@redhat.com>

        PR target/59923
        * ifcvt.c (cond_exec_process_insns): Don't conditionalize
        frame related instructions.

        * gcc.target/arm/pr59923.c: New test.

--- gcc/ifcvt.c.jj      2014-01-09 08:20:55.000000000 +0100
+++ gcc/ifcvt.c 2014-01-29 17:16:29.912259159 +0100
@@ -338,6 +338,10 @@ cond_exec_process_insns (ce_if_block *ce
 
       gcc_assert (NONJUMP_INSN_P (insn) || CALL_P (insn));
 
+      /* dwarf2out can't coope with conditional unwind info.  */
+      if (reload_completed && RTX_FRAME_RELATED_P (insn))
+       return FALSE;
+
       /* Remove USE insns that get in the way.  */
       if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
        {
--- gcc/testsuite/gcc.target/arm/pr59923.c.jj   2014-01-29 17:39:32.355116229 
+0100
+++ gcc/testsuite/gcc.target/arm/pr59923.c      2014-01-29 17:39:10.000000000 
+0100
@@ -0,0 +1,24 @@
+/* PR target/59923 */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2 -mcpu=cortex-a15 -fno-strict-aliasing -mthumb -g" } */
+
+struct S
+{
+  void *s;
+  struct T { unsigned short a; unsigned char b[4], c[4]; } *t;
+} s;
+void bar (void *);
+
+void
+foo (struct S *x, int *y)
+{
+  if (*y > 0)
+    return;
+  else if (x->t->b[0] == 0x43 && x->t->b[1] == 0x6d && x->t->c[0] == 1)
+    x->s = &s;
+  else
+    *y = 16384;
+  if (*y > 0)
+    bar (x);
+}

        Jakub

Reply via email to