[PATCH] Simplifying RTL shifts to narrower modes
Roger Sayle
roger@eyesopen.com
Fri Jan 7 00:57:00 GMT 2005
On Thu, 6 Jan 2005, Richard Henderson wrote:
> Indeed it should.
> > * simplify-rtx.c (simplify_subreg): Simplify truncations of shifts
> > of sign or zero extended values.
>
> Ok, but
Thanks.
> > + /* Simplify (subreg:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C), 0) into
> > + to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
> > + the outer subreg is effectively a truncation to the original mode. */
> > + if ((GET_CODE (op) == LSHIFTRT
> > + || GET_CODE (op) == ASHIFTRT)
> > + && SCALAR_INT_MODE_P (outermode)
> > + && (2 * GET_MODE_BITSIZE (outermode)) <= GET_MODE_BITSIZE (innermode)
>
> Could do with a word or two about this last line. Took me a moment
> or five to figure it out.
Hehe :).
I've now committed the patch with the following additional comment
that should make it much clearer why in this one case we test for
"2 * BITSIZE (outer) <= BITSIZE (inner)" instead of the more obvious
"BITSIZE (outer) < BITSIZE (inner)" used in the other two clauses.
+ /* Simplify (subreg:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C), 0) into
+ to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
+ the outer subreg is effectively a truncation to the original mode. */
+ if ((GET_CODE (op) == LSHIFTRT
+ || GET_CODE (op) == ASHIFTRT)
+ && SCALAR_INT_MODE_P (outermode)
+ /* Ensure that INNERMODE is at least twice as wide as the OUTERMODE
+ to avoid the possibility that an outer LSHIFTRT shifts by more
+ than the sign extension's sign_bit_copies and introduces zeros
+ into the high bits of the result. */
+ && (2 * GET_MODE_BITSIZE (outermode)) <= GET_MODE_BITSIZE (innermode)
...
I thought it better to use a single "at least twice as wide" test, which
shouldn't normally make a difference for typical integer machine modes,
than duplicate or specialize this test for LSHIFTRT and ASHIFTRT.
Thanks again,
Roger
--
More information about the Gcc-patches
mailing list