https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109592

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2023-04-24
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
           Keywords|                            |missed-optimization

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jeffrey A. Law from comment #0)
> This is a trivial sign extension:
> 
> int sextb32(int x)
> { return (x << 24) >> 24; }

Btw, during the various attempts at GIMPLE narrowing/widening passes we
thought it might be interesting to add {S,Z}EXT_EXPR to GIMPLE.  For
ZEXT_EXPR the canonical variant is currently a BIT_AND_EXPR with an
appropriate mask, so ZEXT_EXPR wouldn't be any shorter (thus I'm not sure
we want to add it).  For SEXT_EXPR the canonical form is
truncation to signed and then a sign extending cast - thus two conversions.
But at least I don't see the above being canonicalized to that (not sure
if it would help RTL expansion).

We fail to simplify

int sextb32(int x)
{ return (x << 24) >> 24 == (int)(signed char)x; }

because of the missed canonicalization.  Note for (x << 27) >> 27 we'd
end up with bit-precision casts which is ugly and likely unwanted.
A SEXT_EXPR (x, 8) (the extend-from bit position would be required constant)
would be a simplification.

I suspect most ISAs cannot sign-extend from arbitrary bit positions but
only handle QI, HI and SImode though.

Without SEXT_EXPR the bit-precision cases might instead argue for the
shift sequence to be canonical (but generally conversions are easier
to combine with, and conversions have implementation defined behavior
while shifts of signed values have undefinedness issues).

Reply via email to