summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-30 15:36:11 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-30 15:36:11 +0000
commitea1ac559daec84a01077e4c7b0eccf8db70d7507 (patch)
treefe3e684ea383fae6e8ffa9fdc7fb53096a47d83e /gcc/combine.c
parent754ccb76764048ae0de4458a8684c3ab7a63e492 (diff)
downloadgcc-ea1ac559daec84a01077e4c7b0eccf8db70d7507.tar.gz
* combine.c (simplify_shift_const, case XOR): Be careful when
commuting XOR with ASHIFTRT. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76965 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 9137076ad30..130bda9c429 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -9568,6 +9568,11 @@ simplify_shift_const (rtx x, enum rtx_code code,
(and (shift)) insns. */
if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+ /* We can't do this if we have (ashiftrt (xor)) and the
+ constant has its sign bit set in shift_mode. */
+ && !(code == ASHIFTRT && GET_CODE (varop) == XOR
+ && 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
+ shift_mode))
&& (new = simplify_binary_operation (code, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
@@ -9581,18 +9586,22 @@ simplify_shift_const (rtx x, enum rtx_code code,
/* If we can't do that, try to simplify the shift in each arm of the
logical expression, make a new logical expression, and apply
- the inverse distributive law. */
- {
- rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
- XEXP (varop, 0), count);
- rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
- XEXP (varop, 1), count);
+ the inverse distributive law. This also can't be done
+ for some (ashiftrt (xor)). */
+ if (code != ASHIFTRT || GET_CODE (varop)!= XOR
+ || 0 <= trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
+ shift_mode))
+ {
+ rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
+ XEXP (varop, 0), count);
+ rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
+ XEXP (varop, 1), count);
- varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
- varop = apply_distributive_law (varop);
+ varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
+ varop = apply_distributive_law (varop);
- count = 0;
- }
+ count = 0;
+ }
break;
case EQ: