This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Bootstrap failure on sh-linux target (PR 13567)
Jim Wilson <wilson@specifixinc.com> wrote:
> This is a no-conflict block. It is generated by emit_no_conflict_block
> in optabs.c. If you look at the comments before that function, it tells
> you what a no-conflict block looks like. One of the things it says is
> that the last instruction is a no-op move that moves the target to
> itself. So this no-conflict block is already broken here, probably by
> cse. I suspect we need to teach cse not to modify the dest of the last
> instruction of a no-conflict block. Or else, if it does modify the dest
> of the last insn, it must also change all other uses of the old dest to
> use the new dest. However, since cse only looks at one insn at a time,
> this probably means that we can't make the replacement at all.
Surely cse changes the last insn of the no-conflict block. Before
cse, it was
(insn 31 29 33 3 (set (reg:DI 166 [ sz ])
(reg:DI 166 [ sz ])) -1 (nil)
(insn_list:REG_RETVAL 30 (expr_list:REG_EQUAL (sign_extend:DI (reg/v:SI 163 [ sz ]))
(nil))))
and
(insn 31 29 33 1 (set (reg:DI 169 [ sz ])
(reg:DI 166 [ sz ])) 136 {*movdi_i} (nil)
(insn_list:REG_RETVAL 30 (expr_list:REG_EQUAL (sign_extend:DI (reg/v:SI 163 [ sz ]))
(nil))))
after cse.
> There is another question here of why we have a no-conflict block in the
> first place. This is used when the target can't handle a multi-register
> move whose source and dest do not conflict (and thus can be allocated to
> the same register pair). But gcse is simplifying the no-conflict block
> into a DImode move, so it was never necessary here in the first place.
> Perhaps we can avoid the problem by not generating no-conflict blocks
> when we don't need them. Then gcse won't be able to optimize them away
> like this, and perhaps the problem can't appear anymore. We probably
> still need to fix cse though to be safe, so it isn't clear if this
> approach is helpful.
I see. Thanks for your explanations.
I've tried several another architectures and found that such block
is generated against my testcase only when the target has no
extendsidi2 pattern. Non 64-bit mips is an example of such target
and after cse there is a no-conflict block
(insn 29 27 26 1 (clobber (reg:DI 189 [ sz ])) -1 (nil)
(insn_list:REG_LIBCALL 30 (nil)))
(insn 26 29 28 1 (set (subreg:SI (reg:DI 189 [ sz ]) 4)
(reg/v:SI 186 [ sz ])) 179 {movsi_internal} (nil)
(expr_list:REG_NO_CONFLICT (reg/v:SI 186 [ sz ])
(nil)))
(insn 28 26 30 1 (set (subreg:SI (reg:DI 189 [ sz ]) 0)
(reg:SI 190)) 179 {movsi_internal} (nil)
(expr_list:REG_NO_CONFLICT (reg/v:SI 186 [ sz ])
(nil)))
(insn 30 28 32 1 (set (reg:DI 192 [ sz ])
(reg:DI 189 [ sz ])) 174 {movdi_internal} (nil)
(insn_list:REG_RETVAL 29 (expr_list:REG_EQUAL (sign_extend:DI (reg/v:SI 186 [ sz ]))
(nil))))
...
for a slightly different testcase on mips-elf. So 32-bit mips might hit
a similar problem.
Regards,
kaz