This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] Fix 961206-1.c regression in simplify-rtx.c
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jeffrey A Law <law at redhat dot com>
- Date: Thu, 2 Mar 2006 22:51:18 -0700 (MST)
- Subject: [Committed] Fix 961206-1.c regression in simplify-rtx.c
The following patch fixes the regression of the testsuite test
gcc.c-torture/execute/961206-1.c on i686-pc-linux-gnu caused by
a recent patch of mine. Many thanks to Jeff Law for analysing
the problem. The problem didn't affect x86_64-unknown-linux-gnu
and therefore wasn't discovered during development/testing.
The problem concerns the optimization of (neg (lt X 0)) into
either (ashiftrt X C) or (lshiftrt X C) where C is one less
than the bit width of X. The oversight is that the mode of the
result of the comparison "lt", and therefore of the negation need
not be the same as the mode of X. In these cases where mode !=
GET_MODE (X), we need to either truncate or extend the result
of the shift to the desired mode. For the ASHIFTRT case, we use
SIGN_EXTEND and the for LSHIFTRT case, we can use ZERO_EXTEND.
These corrections are implemented by the patch below.
The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures, and the
resolution of the 961206-1.c execution tests at -O1 and -O2.
Committed to mainline as revision 111671.
My apologies for any inconvenience.
2006-03-02 Roger Sayle <roger@eyesopen.com>
* simplify-rtx.c (simplify_unary_operation): When simplifying
(neg (lt X 0)) into (ashiftrt X C) or (lshiftrt X C), make sure
that we perform the right shift in the appropriate mode, and
then extend or truncate the result to the requested mode.
Index: simplify-rtx.c
===================================================================
*** simplify-rtx.c (revision 111645)
--- simplify-rtx.c (working copy)
*************** simplify_unary_operation_1 (enum rtx_cod
*** 590,601 ****
if (GET_CODE (op) == LT
&& XEXP (op, 1) == const0_rtx)
{
if (STORE_FLAG_VALUE == 1)
! return simplify_gen_binary (ASHIFTRT, mode, XEXP (op, 0),
! GEN_INT (GET_MODE_BITSIZE (mode) - 1));
else if (STORE_FLAG_VALUE == -1)
! return simplify_gen_binary (LSHIFTRT, mode, XEXP (op, 0),
! GEN_INT (GET_MODE_BITSIZE (mode) - 1));
}
break;
--- 590,617 ----
if (GET_CODE (op) == LT
&& XEXP (op, 1) == const0_rtx)
{
+ enum machine_mode inner = GET_MODE (XEXP (op, 0));
+ int isize = GET_MODE_BITSIZE (inner);
if (STORE_FLAG_VALUE == 1)
! {
! temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
! GEN_INT (isize - 1));
! if (mode == inner)
! return temp;
! if (GET_MODE_BITSIZE (mode) > isize)
! return simplify_gen_unary (SIGN_EXTEND, mode, temp, inner);
! return simplify_gen_unary (TRUNCATE, mode, temp, inner);
! }
else if (STORE_FLAG_VALUE == -1)
! {
! temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
! GEN_INT (isize - 1));
! if (mode == inner)
! return temp;
! if (GET_MODE_BITSIZE (mode) > isize)
! return simplify_gen_unary (ZERO_EXTEND, mode, temp, inner);
! return simplify_gen_unary (TRUNCATE, mode, temp, inner);
! }
}
break;
Roger
--