Patchwork [rtl-optimization] : Fix PR 54455, [4.7/4.8 Regression] ICE: RTL check: expected elt 3 type 'B', have '0' (rtx barrier) in compute_bb_for_insn, at cfgrtl.c:418

login
register
mail settings
Submitter Uros Bizjak
Date Sept. 2, 2012, 11:22 a.m.
Message ID <CAFULd4YGx4G0n_mB3vYW8kZVkuDcdLXRQV=poW47MVp_QOxy8g@mail.gmail.com>
Download mbox | patch
Permalink /patch/181179/
State New
Headers show

Comments

Uros Bizjak - Sept. 2, 2012, 11:22 a.m.
Hello!

Attached patch prevents compute_bb_for_insn to calculate BB for
barrier RTXes. This is in fact the same approach all other
*_bb_for_insn use.

The patch is bordering on obvious.

2012-09-02  Uros Bizjak  <ubizjak@gmail.com>

	PR rtl-optimization/54455
	* cfgrtl.c (compute_bb_for_insn): Do not compute BB for barrier RTXes.

testsuite/ChangeLog:

2012-09-02  Uros Bizjak  <ubizjak@gmail.com>

	PR rtl-optimization/54455
	* gcc.target/i386/pr54455.c: New test.

Bootstrapped and regression tested on x86_64-pc-linux-gnu {-m32}.

OK for mainline and 4.7?

Uros.
Steven Bosscher - Sept. 2, 2012, 11:38 a.m.
On Sun, Sep 2, 2012 at 1:22 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> Hello!
>
> Attached patch prevents compute_bb_for_insn to calculate BB for
> barrier RTXes. This is in fact the same approach all other
> *_bb_for_insn use.
>
> The patch is bordering on obvious.

It is anything _but_ obvious. The code looks like this:

void
compute_bb_for_insn (void)
{
  basic_block bb;

  FOR_EACH_BB (bb)
    {
      rtx end = BB_END (bb);
      rtx insn;

      for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
        {
          BLOCK_FOR_INSN (insn) = bb;
          if (insn == end)
            break;
        }
    }
}

This could (&should) actually be written as:

void
compute_bb_for_insn (void)
{
  basic_block bb;
  rtx insn;

  FOR_EACH_BB (bb)
    FOR_BB_INSNS (bb, insn)
      BLOCK_FOR_INSN (insn) = bb;
}

What is happening for you, is that you're seeing a BARRIER between
BB_HEAD(bb) and BB_END(bb), which is not possible. The barrier is
mis-placed.

The patch is not OK.

Ciao!
Steven
Uros Bizjak - Sept. 2, 2012, 11:46 a.m.
On Sun, Sep 2, 2012 at 1:38 PM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> On Sun, Sep 2, 2012 at 1:22 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> Hello!
>>
>> Attached patch prevents compute_bb_for_insn to calculate BB for
>> barrier RTXes. This is in fact the same approach all other
>> *_bb_for_insn use.

> What is happening for you, is that you're seeing a BARRIER between
> BB_HEAD(bb) and BB_END(bb), which is not possible. The barrier is
> mis-placed.

Please see how the dump looks:

(insn 12 11 28 3 (set (reg:SI 1 dx [63])
        (const_int 2 [0x2])) pr54455.c:5 65 {*movsi_internal}
     (nil))
(note 28 12 29 3 NOTE_INSN_EPILOGUE_BEG)
(insn/f 29 28 30 3 (set (reg/f:DI 6 bp)
        (mem:DI (post_inc:DI (reg/f:DI 7 sp)) [0 S8 A8])) pr54455.c:13 -1
     (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI 7 sp)
            (const_int 8 [0x8]))
        (nil)))
(jump_insn 30 29 31 3 (simple_return) pr54455.c:13 -1
     (nil)
 -> simple_return)
(barrier 31 30 15)
(note 15 31 21 ("lab") NOTE_INSN_DELETED_LABEL 3)
(note 21 15 24 NOTE_INSN_DELETED)
(note 24 21 0 NOTE_INSN_DELETED)

Please note that we have a bunch of notes at the end, and barrier
above them. There are no active insns between barrer and BB_END. Where
should this RTX go?

Uros.
Steven Bosscher - Sept. 2, 2012, 11:49 a.m.
On Sun, Sep 2, 2012 at 1:46 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Sun, Sep 2, 2012 at 1:38 PM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
>> On Sun, Sep 2, 2012 at 1:22 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>> Hello!
>>>
>>> Attached patch prevents compute_bb_for_insn to calculate BB for
>>> barrier RTXes. This is in fact the same approach all other
>>> *_bb_for_insn use.
>
>> What is happening for you, is that you're seeing a BARRIER between
>> BB_HEAD(bb) and BB_END(bb), which is not possible. The barrier is
>> mis-placed.
>
> Please see how the dump looks:
>
> (insn 12 11 28 3 (set (reg:SI 1 dx [63])
>         (const_int 2 [0x2])) pr54455.c:5 65 {*movsi_internal}
>      (nil))
> (note 28 12 29 3 NOTE_INSN_EPILOGUE_BEG)
> (insn/f 29 28 30 3 (set (reg/f:DI 6 bp)
>         (mem:DI (post_inc:DI (reg/f:DI 7 sp)) [0 S8 A8])) pr54455.c:13 -1
>      (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI 7 sp)
>             (const_int 8 [0x8]))
>         (nil)))
> (jump_insn 30 29 31 3 (simple_return) pr54455.c:13 -1
>      (nil)
>  -> simple_return)
> (barrier 31 30 15)
> (note 15 31 21 ("lab") NOTE_INSN_DELETED_LABEL 3)
> (note 21 15 24 NOTE_INSN_DELETED)
> (note 24 21 0 NOTE_INSN_DELETED)
>
> Please note that we have a bunch of notes at the end, and barrier
> above them. There are no active insns between barrer and BB_END. Where
> should this RTX go?

It doesn't have to be the barrier that has to move. It could also be
that the barrier is inserted in the right place but BB_END wasn't
updated to point to the jump insn.

Ciao!
Steven
Uros Bizjak - Sept. 2, 2012, 11:52 a.m.
On Sun, Sep 2, 2012 at 1:49 PM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:

>>>> Attached patch prevents compute_bb_for_insn to calculate BB for
>>>> barrier RTXes. This is in fact the same approach all other
>>>> *_bb_for_insn use.
>>
>>> What is happening for you, is that you're seeing a BARRIER between
>>> BB_HEAD(bb) and BB_END(bb), which is not possible. The barrier is
>>> mis-placed.
>>
>> Please see how the dump looks:
>>
>> (insn 12 11 28 3 (set (reg:SI 1 dx [63])
>>         (const_int 2 [0x2])) pr54455.c:5 65 {*movsi_internal}
>>      (nil))
>> (note 28 12 29 3 NOTE_INSN_EPILOGUE_BEG)
>> (insn/f 29 28 30 3 (set (reg/f:DI 6 bp)
>>         (mem:DI (post_inc:DI (reg/f:DI 7 sp)) [0 S8 A8])) pr54455.c:13 -1
>>      (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI 7 sp)
>>             (const_int 8 [0x8]))
>>         (nil)))
>> (jump_insn 30 29 31 3 (simple_return) pr54455.c:13 -1
>>      (nil)
>>  -> simple_return)
>> (barrier 31 30 15)
>> (note 15 31 21 ("lab") NOTE_INSN_DELETED_LABEL 3)
>> (note 21 15 24 NOTE_INSN_DELETED)
>> (note 24 21 0 NOTE_INSN_DELETED)
>>
>> Please note that we have a bunch of notes at the end, and barrier
>> above them. There are no active insns between barrer and BB_END. Where
>> should this RTX go?
>
> It doesn't have to be the barrier that has to move. It could also be
> that the barrier is inserted in the right place but BB_END wasn't
> updated to point to the jump insn.

It looks that NOTE_INSN_DELETED_LABEL interferes with barrier.

Uros.

Patch

Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 190857)
+++ cfgrtl.c	(working copy)
@@ -415,7 +415,8 @@  compute_bb_for_insn (void)
 
       for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
 	{
-	  BLOCK_FOR_INSN (insn) = bb;
+	  if (!BARRIER_P (insn))
+	    BLOCK_FOR_INSN (insn) = bb;
 	  if (insn == end)
 	    break;
 	}
Index: testsuite/gcc.target/i386/pr54455.c
===================================================================
--- testsuite/gcc.target/i386/pr54455.c	(revision 0)
+++ testsuite/gcc.target/i386/pr54455.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fschedule-insns -fselective-scheduling --param max-sched-extend-regions-iters=8" } */
+
+static inline void
+__attribute__ ((always_inline))
+foo (void)
+{
+  asm goto ("" : : "r" (1), "r" (2) : "memory" : lab);
+  lab:;
+}
+
+void bar (void)
+{
+  foo ();
+  foo ();
+}