diff mbox

PATCH [10/n]: Prepare x32: PR rtl-optimization/49114: Reload failed to handle (set reg:X (plus:X (subreg:X (reg:Y) 0) (const

Message ID BANLkTimRLxohdFCgHHZ5xHLweyxLbEmhxg@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu June 27, 2011, 9:35 p.m. UTC
On Mon, Jun 27, 2011 at 1:42 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Jun 27, 2011 at 11:59 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
>> H.J. Lu wrote:
>>
>>> Reloads for insn # 588
>>> Reload 0: reload_in (DI) =3D (reg/v/f:DI 182 [ b ])
>>>         GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum =3D 0)
>>>         reload_in_reg: (reg/v/f:DI 182 [ b ])
>>>         reload_reg_rtx: (reg:DI 1 dx)
>>> Reload 1: reload_in (DI) =3D (zero_extend:DI (plus:SI (subreg:SI (reg/v/f:D=
>>> I 182
>>> [ b ]) 0)
>>>                                                         (const_int 8 [0x8])=
>>> ))
>>>         GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum =3D 0)
>>>         reload_in_reg: (zero_extend:DI (plus:SI (subreg:SI (reg/v/f:DI 182 =
>>> [ b
>>> ]) 0)
>>>                                                         (const_int 8 [0x8])=
>>> ))
>>>         reload_reg_rtx: (reg:DI 1 dx)
>>> Reload 2: reload_out (DF) =3D (mem:DF (zero_extend:DI (plus:SI (subreg:SI
>>> (reg/v/f:DI 182 [ b ]) 0)
>>>                                                             (const_int 8
>>> [0x8]))) [4 MEM[base: b_96(D), index: D.15020_278, step: 8, offset: 0B]+0 S8
>>> A64])
>>>         NO_REGS, RELOAD_FOR_OUTPUT (opnum =3D 0), optional
>>>         reload_out_reg: (mem:DF (zero_extend:DI (plus:SI (subreg:SI (reg/v/=
>>> f:DI
>>> 182 [ b ]) 0)
>>>                                                             (const_int 8
>>> [0x8]))) [4 MEM[base: b_96(D), index: D.15020_278, step: 8, offset: 0B]+0 S8
>>> A64])
>>>
>>> leads to
>>>
>>
>>> (insn 1017 587 1020 34 (set (reg:DI 1 dx)
>>>         (mem/c:DI (plus:DI (reg/f:DI 7 sp)
>>>                 (const_int 112 [0x70])) [5 %sfp+-208 S8 A64])) spooles.c:29=
>>> 1 62
>>> {*movdi_internal_rex64}
>>>      (nil))
>>
>> So this is the reload insn generated from reload 0.  So far so good.
>>
>>> (insn 1020 1017 1022 34 (set (reg:SI 1 dx)
>>>         (const_int 8 [0x8])) spooles.c:291 64 {*movsi_internal}
>>>      (nil))
>>>
>>> (insn 1022 1020 1023 34 (set (reg:SI 1 dx)
>>>         (reg:SI 1 dx)) spooles.c:291 64 {*movsi_internal}
>>>      (nil))
>>>
>>> (insn 1023 1022 1024 34 (set (reg:SI 1 dx)
>>>         (plus:SI (reg:SI 1 dx)
>>>             (const_int 8 [0x8]))) spooles.c:291 248 {*lea_1_x32}
>>>      (expr_list:REG_EQUIV (plus:SI (subreg:SI (reg:DI 1 dx) 0)
>>>             (const_int 8 [0x8]))
>>>         (nil)))
>>>
>>> (insn 1024 1023 588 34 (set (reg:DI 1 dx)
>>>         (zero_extend:DI (reg:SI 1 dx))) spooles.c:291 112
>>> {*zero_extendsidi2_rex64}
>>>      (expr_list:REG_EQUIV (zero_extend:DI (plus:SI (subreg:SI (reg:DI 1 dx)=
>>>  0)
>>>                 (const_int 8 [0x8])))
>>>         (nil)))
>>
>> All these reload insns are generated from reload 1.
>>
>>> (insn 588 1024 589 34 (set (mem:DF (reg:DI 1 dx) [4 MEM[base: b_96(D), inde=
>>> x:
>>> D.15020_278, step: 8, offset: 0B]+0 S8 A64])
>>>         (reg:DF 0 ax [orig:340 D.14980 ] [340])) spooles.c:291 106
>>> {*movdf_internal_rex64}
>>>      (nil))
>>
>> This is the original reloaded insn.
>>
>>> Reload 0 puts (reg/v/f:DI 182 [ b ]) in  (reg:DI 1 dx) for input.
>>> However, reload 2
>>> puts (reg/v/f:DI 182 [ b ]) in  (reg:DI 1 dx) for output.without checking w=
>>> hat
>>> reload 0 did.
>>
>> Reload 2 is an optional reload which reload chose not to utilize, so this
>> is not really relevant here in any case.  There is no output reload.
>>
>> The wrong code above originates from how reload 1 is handled:
>>
>> gen_reload is called to load the ZERO_EXTEND into (reg:DI 1).  This triggers
>> the "unary predicate" path, which recurses into gen_reload to load the operand
>> of the ZERO_EXTEND (reg:SI 1), and subsequently generates insn 1024.
>>
>> The recursive call loads (plus:SI (subreg:SI (reg:DI 1)) (const_int 8)) into
>> (reg:SI 1).  It attempts to do that in a single SET and fails (for some
>> reason).  It then attempts to load the constant (const_int 8) into the
>> destination register (insn 1020) [** which is broken **], and re-tries.
>> This still fails, so it falls through to the last attempt, which is to
>> instead copy the subreg to the destination (which results in insn 1022
>> as the subreg is optimized away at this point), followed by adding the
>> constant.
>>
>> Note that the point marked with "[** which is broken **]" is the place
>> I pointed out in the previous mail.
>>
>
> reload generates:
>
> (insn 914 912 0 (set (reg:SI 0 ax)
>        (plus:SI (subreg:SI (reg/v/f:DI 182 [ b ]) 0)
>            (const_int 8 [0x8]))) 248 {*lea_1_x32}
>     (nil))
>
> from
>
> insn = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
>
> Since (reg/v/f:DI 182 [ b ]) is a pseudo register, it is
> rejected by
>
>      if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
>          || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
>        /* Base is not valid.  */
>        return false;
>
> in ix86_legitimate_address_p.
>

Even if I added

+;; Use by reload
+(define_insn "*lea_0_x32"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+  (plus:SI
+    (match_operand:SI 1 "register_operand" "r")
+    (match_operand:SI 2 "immediate_operand" "Yl")))]
+  "TARGET_X32"
+  "lea{l}\t{%a1, %0|%0, %a1}"
+  [(set_attr "type" "lea")
+   (set_attr "mode" "SI")])

to generate

(insn 914 912 0 (set (reg:SI 0 ax)
       (plus:SI (subreg:SI (reg/v/f:DI 182 [ b ]) 0)
           (const_int 8 [0x8]))) 248 {*lea_0_x32}
    (nil))

It is still rejected by constrain_operands unless I apply
diff mbox

Patch

diff --git a/gcc/recog.c b/gcc/recog.c
index 0c26c0d..358238f 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -2636,7 +2636,7 @@  constrain_operands (int strict)
        if (cl != NO_REGS)
          {
            if (strict < 0
-          || (strict == 0
+          || ((strict == 0 || reload_in_progress)
               && REG_P (op)
               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
           || (strict == 0 && GET_CODE (op) == SCRATCH)