This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
simplify_shift_const() breaks sign extraction of wider sign-extension
- To: gcc-patches at gcc dot gnu dot org
- Subject: simplify_shift_const() breaks sign extraction of wider sign-extension
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 01 Jan 2001 10:44:26 -0200
- Organization: GCC Team, Red Hat
When combine attempts to combine:
(set (reg:DI B) (sign_extend:DI (reg:HI A)))
(set (reg:SI C) (lshiftrt:SI (subreg:SI (reg:DI B))
(const_int 31)))
It eventually asks simplify_shift_const() to simplify the LSHIFTRT.
It ends up transforming varop in:
(ashiftrt:DI (ashift:DI (subreg:DI (reg:HI A) 0) (const_int 48))
(const_int 48))
And it discards the ashiftrt because the enclosing lshiftrt is
extracting just the sign bit. However, it shouldn't do this if the
mode of varop is wider than that of the result, because then the
enclosed operation may not have the appropriate sign bit. In this
case, the whole thing would be optimized to zero, because the left
shift would leave all the lower 32-bits as zero (because reg C would
eventually be truncated to HImode).
This patch fixes this problem. Ok to install?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* combine.c (simplify_shift_const): Even if we're sign-extracting,
don't discard an ASHIFTRT if we're shifting in a wider mode.
Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.171
diff -u -p -r1.171 combine.c
--- gcc/combine.c 2000/12/21 18:48:24 1.171
+++ gcc/combine.c 2001/01/01 12:28:08
@@ -9132,7 +9132,9 @@ simplify_shift_const (x, code, result_mo
case ASHIFTRT:
/* If we are extracting just the sign bit of an arithmetic right
shift, that shift is not needed. */
- if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1)
+ if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1
+ && (GET_MODE_BITSIZE (result_mode)
+ >= GET_MODE_BITSIZE (GET_MODE (varop))))
{
varop = XEXP (varop, 0);
continue;
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me