aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-05-29 00:40:51 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-05-29 00:40:51 -0700
commitd41638e4c5e0ad186c72cc8af1786b5319c684f6 (patch)
treeb2aed1ebcca2488360c1ebd0d03f0c01bbc73d10 /gcc/combine.c
parent085f17143f3444e9fedce6501e21d28bedac8702 (diff)
downloadgcc-d41638e4c5e0ad186c72cc8af1786b5319c684f6.zip
gcc-d41638e4c5e0ad186c72cc8af1786b5319c684f6.tar.gz
gcc-d41638e4c5e0ad186c72cc8af1786b5319c684f6.tar.bz2
combine.c (force_to_mode): Convert subtraction from a constant to NEG or NOT when conditions allow.
* combine.c (force_to_mode) [MINUS]: Convert subtraction from a constant to NEG or NOT when conditions allow. From-SVN: r34248
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index d4af90e..47642f3 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -6846,7 +6846,6 @@ force_to_mode (x, mode, mask, reg, just_select)
/* ... fall through ... */
- case MINUS:
case MULT:
/* For PLUS, MINUS and MULT, we need any bits less significant than the
most significant bit in MASK since carries from those bits will
@@ -6854,6 +6853,28 @@ force_to_mode (x, mode, mask, reg, just_select)
mask = fuller_mask;
goto binop;
+ case MINUS:
+ /* If X is (minus C Y) where C's least set bit is larger than any bit
+ in the mask, then we may replace with (neg Y). */
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ && (INTVAL (XEXP (x, 0)) & -INTVAL (XEXP (x, 0))) > mask)
+ {
+ x = gen_unary (NEG, GET_MODE (x), GET_MODE (x), XEXP (x, 1));
+ return force_to_mode (x, mode, mask, reg, next_select);
+ }
+
+ /* Similarly, if C contains every bit in the mask, then we may
+ replace with (not Y). */
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ && (INTVAL (XEXP (x, 0)) | mask) == INTVAL (XEXP (x, 0)))
+ {
+ x = gen_unary (NOT, GET_MODE (x), GET_MODE (x), XEXP (x, 1));
+ return force_to_mode (x, mode, mask, reg, next_select);
+ }
+
+ mask = fuller_mask;
+ goto binop;
+
case IOR:
case XOR:
/* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and