aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2004-01-30 15:36:11 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2004-01-30 10:36:11 -0500
commit39a44a4e393e7fd5ea60fa9b19eedbeacefe9862 (patch)
treefe3e684ea383fae6e8ffa9fdc7fb53096a47d83e /gcc/combine.c
parent63823931f932280d827aeeae504603b499cfb1b5 (diff)
downloadgcc-39a44a4e393e7fd5ea60fa9b19eedbeacefe9862.zip
gcc-39a44a4e393e7fd5ea60fa9b19eedbeacefe9862.tar.gz
gcc-39a44a4e393e7fd5ea60fa9b19eedbeacefe9862.tar.bz2
combine.c (simplify_shift_const, case XOR): Be careful when commuting XOR with ASHIFTRT.
* combine.c (simplify_shift_const, case XOR): Be careful when commuting XOR with ASHIFTRT. From-SVN: r76965
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 9137076..130bda9 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: