LRA and CANNOT_CHANGE_MODE_CLASS
Vladimir Makarov
vmakarov@redhat.com
Fri Jan 16 17:47:00 GMT 2015
On 2015-01-16 12:30 PM, Andreas Krebbel wrote:
> Hi,
>
> on S/390 I see invalid subregs being generated by LRA although CANNOT_CHANGE_MODE_CLASS is supposed
> to prevent these. The reason appears to be the code you've added with:
>
> commit c6a6cdaaea571860c94f9a9fe0f98c597fef7c81
> Author: vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date: Tue Oct 23 15:51:41 2012 +0000
>
> ...
> int
> simplify_subreg_regno (unsigned int xregno, machine_mode xmode,
> unsigned int offset, machine_mode ymode)
> {
> struct subreg_info info;
> unsigned int yregno;
>
> #ifdef CANNOT_CHANGE_MODE_CLASS
> /* Give the backend a chance to disallow the mode change. */
> if (GET_MODE_CLASS (xmode) != MODE_COMPLEX_INT
> && GET_MODE_CLASS (xmode) != MODE_COMPLEX_FLOAT
> && REG_CANNOT_CHANGE_MODE_P (xregno, xmode, ymode)
> /* We can use mode change in LRA for some transformations. */ <---
> && ! lra_in_progress) <---
> return -1;
>
> ...
>
> In my testcase it is a subreg which is wrapped into a strict_low_part:
>
> ira:
> (insn 295 294 296 39 (set (strict_low_part (subreg:SI (reg/v:TI 252 [ g ]) 4))
> (reg:SI 108 [ D.99773 ])) /home3/andreas/patched/../gcc/gcc/ipa-icf.h:391 882 {movstrictsi}
> (nil))
>
> reload:
> (insn 295 930 931 39 (set (strict_low_part (reg:SI 16 %f0 [ g+4 ]))
> (reg:SI 0 %r0 [orig:108 D.99773 ] [108])) /home3/andreas/patched/../gcc/gcc/ipa-icf.h:391 882
> {movstrictsi}
> (nil))
>
> Assigning an FPR here is wrong due to the differing endianess of GPRs vs FRPs.
>
> From what I've seen there does not seem to be code after that in LRA which would repair this. Do you
> have a hint how I can get this working again?
Originally the condition ! lra_in_progress was added to deal with
situation of matching reloads of operands with different modes for x86.
LRA temporarily generates illegal subregs of pseudos to deal with such
situation. Later such subregs started to be marked by LRA_SUBREG_P.
You could try to change condition !lra_in_progress to (!lra_in_progress
|| ! LRA_SUBREG_P (original_pseudo)). You need to pass original_pseudo
somehow too. Let me know if it does not work.
More information about the Gcc
mailing list