(fold_rtx, case PLUS): If we have (plus A B), A is equivalent to a
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Dec 1993 12:55:11 +0000 (12:55 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Dec 1993 12:55:11 +0000 (12:55 +0000)
negative constant, and the negated constant is in register, convert to
(minus A C) where C is the register containing the negated constant.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@6326 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cse.c

index f37912d..d1fc015 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5350,6 +5350,27 @@ fold_rtx (x, insn)
                  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0))
                return XEXP (y, 0);
            }
+
+         /* If second operand is a register equivalent to a negative
+            CONST_INT, see if we can find a register equivalent to the
+            positive constant.  Make a MINUS if so.  Don't do this for
+            a negative constant since we might then alternate between
+            chosing positive and negative constants.  Having the positive
+            constant previously-used is the more common case.  */
+         if (const_arg1 && GET_CODE (const_arg1) == CONST_INT
+             && INTVAL (const_arg1) < 0 && GET_CODE (folded_arg1) == REG)
+           {
+             rtx new_const = GEN_INT (- INTVAL (const_arg1));
+             struct table_elt *p
+               = lookup (new_const, safe_hash (new_const, mode) % NBUCKETS,
+                         mode);
+
+             if (p)
+               for (p = p->first_same_value; p; p = p->next_same_value)
+                 if (GET_CODE (p->exp) == REG)
+                   return cse_gen_binary (MINUS, mode, folded_arg0,
+                                          canon_reg (p->exp, NULL_RTX));
+           }
          goto from_plus;
 
        case MINUS: