On 12/23/23 17:49, Roger Sayle wrote:

Hi YunQiang (and Jeff),

MIPS claims TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode)) ==
true based on that the hard register is always sign-extended, but
here the hard register is polluted by zero_extract.

I suspect that the bug here is that the MIPS backend shouldn't be
returning true for TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode).
It's true that the backend stores SImode values in DImode registers
by sign extending them, but this doesn't mean that any DImode pseudo
register can be truncated to an SImode pseudo just by SUBREG/register
naming.  As you point out, if the high bits of a DImode value are
random, truncation isn't a no-op, and requires an explicit
sign-extension instruction.
What's exceedingly weird is T_N_T_M_P (DImode, SImode) isn't actually a truncation! The output precision is first, the input precision is second. The docs explicitly state the output precision should be smaller than the input precision (which makes sense for truncation).

That's where I'd start with trying to untangle this mess.




I agree with Jeff there's an invariant that isn't correctly being
modelled by the MIPS machine description.  A machine description
probably shouldn't define an addsi3  pattern if what it actually
supports is (sign_extend:DI (truncate:SI (plus:DI (reg:DI x) (reg:DI
y)))) Trying to model this as SImode addition plus a SUBREG_PROMOTED
flag is less than ideal.
It's less than ideal, but we ended up taking a similar approach in the RV world. We actually have a subset of 32bit instructions in rv64, including a 32bit add.

The semantics are that it's a (sign_extend:DI (plus:SI (op1) (op2)))

Modeling it that way was actually critical in eliminating redundant sign extensions.

But regardless, it looks like there's something weird going on in the MIPS port.

jeff

Reply via email to