re PR tree-optimization/24964 (Does not optimise abs(x)**2 to x**2)
authorRoger Sayle <roger@eyesopen.com>
Mon, 29 May 2006 16:22:05 +0000 (16:22 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 29 May 2006 16:22:05 +0000 (16:22 +0000)
PR tree-optimization/24964
* simplify-rtx.c (simplify_binary_operation_1): Add function comment.
<MULT>: Minor clean-up.  Don't convert x*-1.0 into -x if we honor
signaling NaNs.  Optimize -x*-x as x*x for all float modes, and
abs(x)*abs(x) as x*x for scalar floating point modes.

* gcc.target/i386/387-10.c: New test case.

From-SVN: r114206

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/387-10.c [new file with mode: 0644]

index dc310f6..97ec80c 100644 (file)
@@ -1,3 +1,11 @@
+2006-05-29  Roger Sayle  <roger@eyesopen.com>
+
+       PR tree-optimization/24964
+       * simplify-rtx.c (simplify_binary_operation_1): Add function comment.
+       <MULT>: Minor clean-up.  Don't convert x*-1.0 into -x if we honor
+       signaling NaNs.  Optimize -x*-x as x*x for all float modes, and
+       abs(x)*abs(x) as x*x for scalar floating point modes.
+
 2006-05-29  Sebastian Pop  <pop@cri.ensmp.fr>
 
        PR middle-end/27745
index 7199316..c51ca9e 100644 (file)
@@ -1472,6 +1472,11 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
   return simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
 }
 
+/* Subroutine of simplify_binary_operation.  Simplify a binary operation
+   CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
+   OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
+   actual constants.  */
+
 static rtx
 simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
                             rtx op0, rtx op1, rtx trueop0, rtx trueop1)
@@ -1907,12 +1912,12 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
        return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
 
       /* Likewise for multipliers wider than a word.  */
-      else if (GET_CODE (trueop1) == CONST_DOUBLE
-              && (GET_MODE (trueop1) == VOIDmode
-                  || GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_INT)
-              && GET_MODE (op0) == mode
-              && CONST_DOUBLE_LOW (trueop1) == 0
-              && (val = exact_log2 (CONST_DOUBLE_HIGH (trueop1))) >= 0)
+      if (GET_CODE (trueop1) == CONST_DOUBLE
+         && (GET_MODE (trueop1) == VOIDmode
+             || GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_INT)
+         && GET_MODE (op0) == mode
+         && CONST_DOUBLE_LOW (trueop1) == 0
+         && (val = exact_log2 (CONST_DOUBLE_HIGH (trueop1))) >= 0)
        return simplify_gen_binary (ASHIFT, mode, op0,
                                    GEN_INT (val + HOST_BITS_PER_WIDE_INT));
 
@@ -1927,10 +1932,27 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
          if (REAL_VALUES_EQUAL (d, dconst2))
            return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
 
-         if (REAL_VALUES_EQUAL (d, dconstm1))
+         if (!HONOR_SNANS (mode)
+             && REAL_VALUES_EQUAL (d, dconstm1))
            return simplify_gen_unary (NEG, mode, op0, mode);
        }
 
+      /* Optimize -x * -x as x * x.  */
+      if (FLOAT_MODE_P (mode)
+         && GET_CODE (op0) == NEG
+         && GET_CODE (op1) == NEG
+         && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
+         && !side_effects_p (XEXP (op0, 0)))
+       return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
+
+      /* Likewise, optimize abs(x) * abs(x) as x * x.  */
+      if (SCALAR_FLOAT_MODE_P (mode)
+         && GET_CODE (op0) == ABS
+         && GET_CODE (op1) == ABS
+         && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
+         && !side_effects_p (XEXP (op0, 0)))
+       return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
+
       /* Reassociate multiplication, but for floating point MULTs
         only when the user specifies unsafe math optimizations.  */
       if (! FLOAT_MODE_P (mode)
index 96c5729..8778352 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-29  Roger Sayle  <roger@eyesopen.com>
+
+       PR tree-optimization/24964
+       * gcc.target/i386/387-10.c: New test case.
+
 2006-05-28  Thomas Koenig  <Thomas.Koenig@online.de>
 
        * intrinsics/string_intrinsics.c (compare_string):
diff --git a/gcc/testsuite/gcc.target/i386/387-10.c b/gcc/testsuite/gcc.target/i386/387-10.c
new file mode 100644 (file)
index 0000000..150515b
--- /dev/null
@@ -0,0 +1,20 @@
+/* PR tree-optimization/24964 */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mfpmath=387" } */
+
+double fabs(double x);
+
+double test1(double x)
+{
+  double t = fabs(x);
+  return t*t;
+}
+
+double test2(double x)
+{
+  double t = -x;
+  return t*t;
+}
+
+/* { dg-final { scan-assembler-not "fchs" } } */
+/* { dg-final { scan-assembler-not "fabs" } } */