This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Add missing TRULY_NOOP_TRUNCATION
Roger Sayle writes:
>
> On Mon, 2 Jan 2006, Adam Nemet wrote:
> > gcc.c-torture/execute/20000605-1.c with -mabi=eab or -mabi=64:
> > (plus:SI (subreg:SI (reg:DI)) (subreg:SI (reg:DI)))
> > (sign_extend:DI)
> >
> > // apply_distributive_law:
> > -> (subreg:SI (plus:DI (reg:DI) (reg:DI)))
> > (sign_extend:DI)
> >
> > // expand_compound_operation:
> > -> (ashr:DI (ashl:DI (plus:DI (reg:DI) (reg:DI)) 32) 32)
> >
> > // make_extraction (without the fix):
> > -> (sign_extend:DI (plus:SI (subreg:SI (reg:DI)) (subreg:SI (reg:DI))))
> >
> > The last transformation is not valid if we can't prove that the
> > reg:DIs contain valid SI values.
>
> Are you sure? It seems that all of these transformations are correct,
> even when the highparts of the DImode regsiters are filled with random
> bits. You'll notice that the last RTX above is identical to the first,
> where the result of the first instruction has been inserted into the
> second.
Sure it is valid if you know what we started with that is if you know
that the DI registers contain valid SI values. But the way compound
operations are combined now, by the time you try to recover them we no
longer have that information.
Or with previous example in make_extraction (or actually in
make_compound_operation) we see:
(ashr:DI (ashl:DI (plus:DI (reg:DI) (reg:DI)) 32) 32)
and we have no way of assuming that (subreg:SI (reg:DI)) is a valid SI
value since on MIPS64 SI values have to be properly sign-extended into
64 bits.
I was going to hold this for the force_to_mode patch but it is a great
illustration that we can arrive to the same RTL as above and not have
correct SI values. The testcase is:
long long
g (long long a, long long b)
{
return ((a + b) << 32) >> 32;
}
On MIPS64 we produce
j $31
addu $2,$5,$4
for this function right now which is incorrect. addu is a 32-bit
operation and is unpredictable according to the MIPS64 reference
manual if the operands are not sign-extended 32-bit values.
We produce this due to the same transformation:
(ashiftrt:DI (ashift:DI (plus:DI (reg:DI 5 $5 [ b ])
(reg:DI 4 $4 [ a ]))
(const_int 32 [0x20]))
(const_int 32 [0x20]))
->
(sign_extend:DI (plus:SI (reg:SI 5 $5 [ b+4 ])
(reg:SI 4 $4 [ a+4 ])))
Adam