PR optimization/12260
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Oct 2003 21:06:19 +0000 (21:06 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Oct 2003 21:06:19 +0000 (21:06 +0000)
* simplify-rtx.c (simplify_unary_operation): Simplify all unary
operations through CONST nodes.  Optimize (neg (plus X C)) as
(minus -C X) for constant values C.
(simplify_binary_operation): Optimize (minus (neg X) C) as
(minus -C X) for constant values C.
(simplify_plus_minus): Avoid creating (neg (const (plus X C)),
instead create (minus -C X).

* gcc.c-torture/compile/20031011-2.c: New test case.

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

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20031011-2.c [new file with mode: 0644]

index 38bd51f..4251bf3 100644 (file)
@@ -1,5 +1,16 @@
 2003-10-11  Roger Sayle  <roger@eyesopen.com>
 
+       PR optimization/12260
+       * simplify-rtx.c (simplify_unary_operation): Simplify all unary
+       operations through CONST nodes.  Optimize (neg (plus X C)) as
+       (minus -C X) for constant values C.
+       (simplify_binary_operation): Optimize (minus (neg X) C) as
+       (minus -C X) for constant values C.
+       (simplify_plus_minus): Avoid creating (neg (const (plus X C)),
+       instead create (minus -C X).
+
+2003-10-11  Roger Sayle  <roger@eyesopen.com>
+
        * expr.c (expand_expr <PLUS_EXPR>): Let expand_operands call
        safe_from_p for us, once it chooses an evaluation order.
        (expand_expr <MULT_EXPR>): Likewise.
index 0e86463..22ba167 100644 (file)
@@ -407,6 +407,8 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
          return gen_rtx_CONST_VECTOR (mode, v);
        }
     }
+  else if (GET_CODE (op) == CONST)
+    return simplify_unary_operation (code, mode, XEXP (op, 0), op_mode);
 
   if (VECTOR_MODE_P (mode) && GET_CODE (trueop) == CONST_VECTOR)
     {
@@ -971,11 +973,22 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
            return simplify_gen_binary (MINUS, mode, XEXP (op, 1),
                                        XEXP (op, 0));
 
-         /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
          if (GET_CODE (op) == PLUS
              && !HONOR_SIGNED_ZEROS (mode)
              && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
            {
+             /* (neg (plus A C)) is simplified to (minus -C A).  */
+             if (GET_CODE (XEXP (op, 1)) == CONST_INT
+                 || GET_CODE (XEXP (op, 1)) == CONST_DOUBLE)
+               {
+                 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1),
+                                                  mode);
+                 if (temp)
+                   return simplify_gen_binary (MINUS, mode, temp,
+                                               XEXP (op, 0));
+               }
+
+             /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
              temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
              return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
            }
@@ -1572,6 +1585,16 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
          if (GET_CODE (op1) == NEG)
            return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
 
+         /* (-x - c) may be simplified as (-c - x).  */
+         if (GET_CODE (op0) == NEG
+             && (GET_CODE (op1) == CONST_INT
+                 || GET_CODE (op1) == CONST_DOUBLE))
+           {
+             tem = simplify_unary_operation (NEG, mode, op1, mode);
+             if (tem)
+               return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
+           }
+
          /* If one of the operands is a PLUS or a MINUS, see if we can
             simplify this by the associative law.
             Don't use the associative law for floating point.
@@ -2375,6 +2398,13 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
   /* Sort the operations based on swap_commutative_operands_p.  */
   qsort (ops, n_ops, sizeof (*ops), simplify_plus_minus_op_data_cmp);
 
+  /* Create (minus -C X) instead of (neg (const (plus X C))).  */
+  if (n_ops == 2
+      && GET_CODE (ops[1].op) == CONST_INT
+      && CONSTANT_P (ops[0].op)
+      && ops[0].neg)
+    return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
+  
   /* We suppressed creation of trivial CONST expressions in the
      combination loop to avoid recursion.  Create one manually now.
      The combination loop should have ensured that there is exactly
index 331794d..ad9bafc 100644 (file)
@@ -1,5 +1,10 @@
 2003-10-11  Roger Sayle  <roger@eyesopen.com>
 
+       PR optimization/12260
+       * gcc.c-torture/compile/20031011-2.c: New test case.
+
+2003-10-11  Roger Sayle  <roger@eyesopen.com>
+
        * gcc.c-torture/execute/20031011-1.c: New testcase.
 
 2003-10-11  Eric Botcazou  <ebotcazou@libertysurf.fr>
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031011-2.c b/gcc/testsuite/gcc.c-torture/compile/20031011-2.c
new file mode 100644 (file)
index 0000000..0268455
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR optimization/12260.  */
+
+extern int f(void);
+extern int g(int);
+
+static char buf[512];
+void h(int l) {
+    while (l) {
+        char *op = buf;
+        if (f() == 0)
+            break;
+        if (g(op - buf + 1))
+            break;
+    }
+}