combine.c (force_to_mode): Convert subtraction from a constant to NEG or NOT when...
authorRichard Henderson <rth@cygnus.com>
Mon, 29 May 2000 07:40:51 +0000 (00:40 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 29 May 2000 07:40:51 +0000 (00:40 -0700)
        * combine.c (force_to_mode) [MINUS]: Convert subtraction from
        a constant to NEG or NOT when conditions allow.

From-SVN: r34248

gcc/ChangeLog
gcc/combine.c

index 11cfe533520fe756c29b5ff311ad3b07080524b5..d49783c626cc2c383a3e4fb57c75066db9b80b37 100644 (file)
@@ -1,5 +1,8 @@
 2000-05-29  Richard Henderson  <rth@cygnus.com>
 
+       * combine.c (force_to_mode) [MINUS]: Convert subtraction from
+       a constant to NEG or NOT when conditions allow.
+
        * combine.c (combine_simplify_rtx): Don't create an if_then_else
        unless both args are general_operand.  Don't canonicalize plus
        to ior unless it helps.
index d4af90e54ebc29a0637344995def1a8698b907a5..47642f3d42f0012f3e7f23ce48040b9ad1f175f7 100644 (file)
@@ -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