This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch 79279] combine/simplify_set issue
On Thu, Feb 02, 2017 at 11:27:12AM +0100, Aurelien Buhrig wrote:
> > Hrm, maybe you can show the RTL before and after this transform?
> RTL before combine:
> (set (reg:SI 31 (lshiftt:SI (reg:SI 29) (const_int 16))))
> (set (reg:HI 1 "r1") (reg:HI 25))
> (set (reg:HI 0 "r0") (subreg:HI (reg:SI 31) 0)) ; LE target
>
> r0 and r1 are HI regs
>
> RTL after combining 1 --> 3:
> (set (reg:HI 1 "r1") (reg:HI 25))
> (set (reg:SI 0 "r0") (lshift:SI (reg:SI 29) (const_int 16)))
> and r1 is clobbered by last insn.
Ah, much clearer now, thanks!
There is this test:
&& (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1))
/ UNITS_PER_WORD)
== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
On most targets the size of a register is (at least) UNITS_PER_WORD, so
this works there. But this code should really use can_change_dest_mode,
at least for hard registers, which does
if (regno < FIRST_PSEUDO_REGISTER)
return (HARD_REGNO_MODE_OK (regno, mode)
&& REG_NREGS (x) >= hard_regno_nregs[regno][mode]);
i.e. it tests the new mode does not use more hard registers than the
old one did, which indeed would be bad.
Segher