This is the mail archive of the
mailing list for the GCC project.
Re: Paradoxical subreg reload issue
04/05/2012 09:37, Aurelien Buhrig :
> 03/05/2012 14:14, Aurelien Buhrig :
>> 02/05/2012 21:36, Eric Botcazou :
>>>> I have an issue (gcc 4.6.3, private bacakend) when reloading operands of
>>>> this insn:
>>>> (set (subreg:SI (reg:QI 21 [ iftmp.1 ]) 0)
>>>> (lshiftrt:SI (reg/v:SI 24 [ w ]) (const_int 31 [0x1f]))
>>>> The register 21 is reloaded into
>>>> (reg:QI 0 r0 [orig:21 iftmp.1 ] ), which is a HI-wide hw register.
>>>> Since it is a BIG_ENDIAN target, the SI subreg regno is then -1.
>>>> Note that word_mode is SImode, whereas the class r0 belongs to is
>>>> HI-wide. I don't know if this matters when reloading.
>>>> I have no idea how to debug this, if it is a backend or a reload bug.
>>> RA/reload is known to have issues with word-mode paradoxical subregs on
>>> big-endian machines. For example, on SPARC 64-bit, we run into similar
>>> problems for FP regs, which are 32-bit. Likewise on HP-PA 64-bit I think.
>>> So we have kludges in the back-end:
>>> #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
>>> (TARGET_ARCH64 \
>>> && GET_MODE_SIZE (FROM) == 4 \
>>> && GET_MODE_SIZE (TO) != 4 \
>>> ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
>> I modified CANNOT_CHANGE_MODE_CLASS as you suggested. But strange as it
>> may seem, it has no effect on such a reload, and I can't find a way to
>> make it work...
>> BTW, has this bug already been filed?
>> Do you have an idea how deep is this bug in the reload, how complex it
>> is and which part in the reload it is related to?
> It seems the paradoxical subreg information is not available from
> ira_allocno_t nor ira_object_t when choosing the hw reg.
> I finally changed word_mode to the smallest hw reg size (HImode) to work
> around this bug.
I have another issue in DCE pass after changing word_mode from SImode to
Indeed, in subreg1 pass, SI moves such as
(insn 42 41 43 (set (reg:SI 85) (reg/f:SI 83))
(insn 46 45 47 (set (reg:SI 8 a1) (reg:SI 85))
are split into HImode word moves:
(insn 98 97 99 2 (set (subreg:HI (reg:SI 106) 0) (reg:HI 104))
(insn 99 98 100 2 (set (subreg:HI (reg:SI 106) 2) (reg:HI 105 [+2 ]))
(insn 100 99 47 2 (set (reg:SI 8 a1) (reg:SI 106))
Looking at DCE pass in (dce_process_block), it seems that when reverse
parsing the block insns for dead set eliminations, the liveness of reg
106 which is set when parsing insn 100, is removed when parsing insn 99.
So the insn 98 is deleted because the reg 106 is not seen live anymore...
Is it a bug, or is it because it is not possible to have hardware
registers which are not splittable in word_mode? Any thoughts?