Bernd Schmidt <ber...@codesourcery.com> writes:
> On 04/27/2013 10:39 AM, Richard Sandiford wrote:
>> Argh, that's unfortunate.  The point of that change was to make
>> simplify_gen_unary (TRUNCATE, ...) no worse than using a subreg.
>> Would the equivalent lowpart simplify_gen_subreg call succeed
>> (return nonnull)?  If so, I think we want truncate to do the same.
>> 
>> What simplification is this blocking, and why does it lead to
>> reload failures?
>
> There's an explicit (set (reg:PSI) (truncate:PSI (reg:SI)) insn which
> currently gets changed to (set (reg:PSI) (subreg:PSI (reg:SI)) during
> cse1. Reload fails because the subreg gets propagated into a memory
> address, which requires a class of A_REGS, but A_REGS can only hold
> PSImode values, not SImode.  This shows that the truncation is not
> always a no-op: in this case it involves a register move, but there's no
> way to describe this using TRULY_NOOP_TRUNCATION.

Hmm, but isn't this a reload bug?  We have:

(insn 53 51 54 10 (set (reg:HI 0 r0 [orig:26 D.2817 ] [26])
        (zero_extend:HI (mem/u/j:QI (plus:PSI (subreg:PSI (reg:SI 44 [ D.2818 
]) 0)
                    (symbol_ref:PSI ("__clz_tab") [flags 0x40]  <var_decl 
0x7f2c253d42f8 __clz_tab>)) [0 __clz_tab S1 A8]))) 
/home/richards/gcc/HEAD/gcc/libgcc/libgcc2.c:520 115 {zero_extendqihi2}
     (expr_list:REG_DEAD (reg:SI 44 [ D.2818 ])
        (nil)))

Reloads for insn # 53
Reload 0: reload_in (SI) = (reg:SI 44 [ D.2818 ])
        A_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0)
        reload_in_reg: (reg:SI 44 [ D.2818 ])

find_reloads_address_1 is reloading the SUBREG_REG rather than the
SUBREG itself, even though SImode is not valid for BASE_REGS == A_REGS:

        if (GET_CODE (op0) == SUBREG)
          {
            op0 = SUBREG_REG (op0);
            code0 = GET_CODE (op0);
            if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
              op0 = gen_rtx_REG (word_mode,
                                 (REGNO (op0) +
                                  subreg_regno_offset (REGNO (SUBREG_REG 
(orig_op0)),
                                                       GET_MODE (SUBREG_REG 
(orig_op0)),
                                                       SUBREG_BYTE (orig_op0),
                                                       GET_MODE (orig_op0))));
          }

push_reloads would specifically not convert a SUBREG reload to a
REG reload in this case.  In principle, I think address subregs
should be handled in the same way.

So is the problem really that (subreg:PSI (reg:SI ...)) isn't a valid
truncation on m32c?  Without TRULY_NOOP_TRUNCATION, I don't see what
forces most code to use (truncate:PSI (reg:SI ...)) instead.  Many places
would call gen_lowpart directly.

Sorry for missing the truncation patterns, I should have grepped more
than m32c.md.  They look a lot like normal moves though.  Is truncation
really not a noop, or are the patterns there to work around something
(probably this :-))?

Richard

Reply via email to