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