[patch, ARM] Fix minipool ICE
Jakub Jelinek
jakub@redhat.com
Wed Mar 2 11:58:00 GMT 2011
On Mon, Feb 28, 2011 at 11:40:21PM +0800, Chung-Lin Tang wrote:
> > This is wrong. Neither the predicate nor the constraint accept an
> > immediate, so these should never need to generate mini-pool entries. If
> > reload is letting these through, then that's a bug in reload IMO. If
No. arm backend asked for it by defining LOAD_EXTEND_OP.
> > it's not reload, then that needs investigating further too.
>
> To re-cap some of the discussion Bernd, Ramana, and I had off-list: we
> are seeing in some cases, IRA/reload ending up with insns with constant
> pool references (not generated from ARM reorg):
> (insn 262 92 94 3 (set (reg:HI 4 r4 [orig:328 iftmp.6 ] [328])
> (mem/u/c/i:HI (symbol_ref/u:SI ("*.LC0") [flags 0x2]) [2 S2
> A16])) k.c:11 177 {*movhi_insn_arch4}
> (expr_list:REG_EQUAL (const_int 2047 [0x7ff])
> (nil)))
>
> It looks like IRA spilled a register which is a constant. Probably
> because 2047 is not a valid ARM movable constant, it gets turned into a
> constant pool reference.
>
>
> After postreload, the above insn gets turned into:
> (insn 262 92 94 3 (set (reg:SI 4 r4)
> (zero_extend:SI (mem/u/c/i:HI (symbol_ref/u:SI ("*.LC0") [flags
> 0x2]) [2 S2 A16]))) k.c:11 148 {*arm_zero_extendhisi2_v6}
> (expr_list:REG_EQUAL (const_int 2047 [0x7ff])
> (nil)))
>
> Thus arm.c:note_invalid_constants() kicks in, then ICEing later
>
> I haven't yet investigated where exactly postreload produces that
> zero_extend (maybe someone here can be quick to point out where), but if
> it's correct behavior, then I guess the pool range attributes have to be
> there...
The zero_extend is created because arm defines LOAD_EXTEND_OP.
reload_cse_simplify_operands has:
#ifdef LOAD_EXTEND_OP
if (MEM_P (op)
&& GET_MODE_BITSIZE (GET_MODE (op)) < BITS_PER_WORD
&& LOAD_EXTEND_OP (GET_MODE (op)) != UNKNOWN)
{
...
/* If this is a straight load, make the extension explicit. */
else if (REG_P (SET_DEST (set))
&& recog_data.n_operands == 2
&& SET_SRC (set) == op
&& SET_DEST (set) == recog_data.operand[1-i])
{
validate_change (insn, recog_data.operand_loc[i],
gen_rtx_fmt_e (LOAD_EXTEND_OP (GET_MODE (op)),
word_mode, op),
1);
validate_change (insn, recog_data.operand_loc[1-i],
gen_rtx_REG (word_mode, REGNO (SET_DEST (set))),
1);
if (! apply_change_group ())
return 0;
This isn't particularly new code, it was added for PR11864 more than 7 years
ago.
Jakub
More information about the Gcc-patches
mailing list