aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2002-12-05 01:05:13 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2002-12-05 01:05:13 +0000
commit16823694d5a03199161bfb60157a9a6e3a2ee697 (patch)
treea75fcb2170c99b7b343e9abad85d48152fdd43c2
parent76508852a0241db33b2512c0b460cdf06f7e0ce5 (diff)
downloadgcc-16823694d5a03199161bfb60157a9a6e3a2ee697.zip
gcc-16823694d5a03199161bfb60157a9a6e3a2ee697.tar.gz
gcc-16823694d5a03199161bfb60157a9a6e3a2ee697.tar.bz2
Index: gcc/ChangeLog
2002-12-02 Geoffrey Keating <geoffk@apple.com> * combine.c (combine_simplify_rtx): Add new canonicalizations. * doc/md.texi (Insn Canonicalizations): Document new canonicalizations for multiply/add combinations. * config/rs6000/rs6000.md: Add and modify floating add/multiply patterns to ensure they're used whenever they can be. Index: gcc/testsuite/ChangeLog 2002-12-02 Geoffrey Keating <geoffk@apple.com> * gcc.dg/ppc-fmadd-1.c: New file. * gcc.dg/ppc-fmadd-2.c: New file. * gcc.dg/ppc-fmadd-3.c: New file. From-SVN: r59841
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/combine.c57
-rw-r--r--gcc/config/rs6000/rs6000.md72
-rw-r--r--gcc/doc/md.texi8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/ppc-fmadd-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/ppc-fmadd-2.c27
-rw-r--r--gcc/testsuite/gcc.dg/ppc-fmadd-3.c36
8 files changed, 253 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3d20349..cb473f5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2002-12-04 Geoffrey Keating <geoffk@apple.com>
+
+ * combine.c (combine_simplify_rtx): Add new canonicalizations.
+ * doc/md.texi (Insn Canonicalizations): Document new
+ canonicalizations for multiply/add combinations.
+ * config/rs6000/rs6000.md: Add and modify floating add/multiply
+ patterns to ensure they're used whenever they can be.
+
2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.c: Update the comments related to shifts.
diff --git a/gcc/combine.c b/gcc/combine.c
index a0214d1..4d24807 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4029,6 +4029,24 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1),
XEXP (XEXP (x, 0), 0));
+ /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
+ if (GET_CODE (XEXP (x, 0)) == PLUS
+ && !HONOR_SIGNED_ZEROS (mode)
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
+ {
+ temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
+ temp = combine_simplify_rtx (temp, mode, last, in_dest);
+ return gen_binary (MINUS, mode, temp, XEXP (XEXP (x, 0), 1));
+ }
+
+ /* (neg (mult A B)) becomes (mult (neg A) B).
+ This works even for floating-point values. */
+ if (GET_CODE (XEXP (x, 0)) == MULT)
+ {
+ temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
+ return gen_binary (MULT, mode, temp, XEXP (XEXP (x, 0), 1));
+ }
+
/* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx
&& nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
@@ -4217,6 +4235,19 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
#endif
case PLUS:
+ /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).
+ */
+ if (GET_CODE (XEXP (x, 0)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == NEG)
+ {
+ rtx in1, in2;
+
+ in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
+ in2 = XEXP (XEXP (x, 0), 1);
+ return gen_binary (MINUS, mode, XEXP (x, 1),
+ gen_binary (MULT, mode, in1, in2));
+ }
+
/* If we have (plus (plus (A const) B)), associate it so that CONST is
outermost. That's because that's the way indexed addresses are
supposed to appear. This code used to check many more cases, but
@@ -4323,6 +4354,32 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
-INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
+ /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).
+ */
+ if (GET_CODE (XEXP (x, 1)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 1), 0)) == NEG)
+ {
+ rtx in1, in2;
+
+ in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
+ in2 = XEXP (XEXP (x, 1), 1);
+ return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
+ XEXP (x, 0));
+ }
+
+ /* Canonicalize (minus (neg A) (mult B C)) to
+ (minus (mult (neg B) C) A). */
+ if (GET_CODE (XEXP (x, 1)) == MULT
+ && GET_CODE (XEXP (x, 0)) == NEG)
+ {
+ rtx in1, in2;
+
+ in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
+ in2 = XEXP (XEXP (x, 1), 1);
+ return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
+ XEXP (XEXP (x, 0), 0));
+ }
+
/* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
integers. */
if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 853dab2..16f083b 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5280,7 +5280,18 @@
(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(match_operand:SF 2 "gpc_reg_operand" "f"))
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
- "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (SFmode)"
+ "fnmadds %0,%1,%2,%3"
+ [(set_attr "type" "fp")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
+ (match_operand:SF 2 "gpc_reg_operand" "f"))
+ (match_operand:SF 3 "gpc_reg_operand" "f")))]
+ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
"fnmadds %0,%1,%2,%3"
[(set_attr "type" "fp")])
@@ -5295,10 +5306,31 @@
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
+ (match_operand:SF 2 "gpc_reg_operand" "f"))
+ (match_operand:SF 3 "gpc_reg_operand" "f")))]
+ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
+ "{fnma|fnmadd} %0,%1,%2,%3"
+ [(set_attr "type" "dmul")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(match_operand:SF 2 "gpc_reg_operand" "f"))
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
- "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (SFmode)"
+ "fnmsubs %0,%1,%2,%3"
+ [(set_attr "type" "fp")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
+ (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
+ (match_operand:SF 2 "gpc_reg_operand" "f"))))]
+ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
"fnmsubs %0,%1,%2,%3"
[(set_attr "type" "fp")])
@@ -5311,6 +5343,16 @@
"{fnms|fnmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul")])
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
+ (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
+ (match_operand:SF 2 "gpc_reg_operand" "f"))))]
+ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
+ "{fnms|fnmsub} %0,%1,%2,%3"
+ [(set_attr "type" "fp")])
+
(define_expand "sqrtsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
@@ -5524,7 +5566,18 @@
(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
(match_operand:DF 2 "gpc_reg_operand" "f"))
(match_operand:DF 3 "gpc_reg_operand" "f"))))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (DFmode)"
+ "{fnma|fnmadd} %0,%1,%2,%3"
+ [(set_attr "type" "dmul")])
+
+(define_insn ""
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
+ (match_operand:DF 2 "gpc_reg_operand" "f"))
+ (match_operand:DF 3 "gpc_reg_operand" "f")))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (DFmode)"
"{fnma|fnmadd} %0,%1,%2,%3"
[(set_attr "type" "dmul")])
@@ -5533,7 +5586,18 @@
(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
(match_operand:DF 2 "gpc_reg_operand" "f"))
(match_operand:DF 3 "gpc_reg_operand" "f"))))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (DFmode)"
+ "{fnms|fnmsub} %0,%1,%2,%3"
+ [(set_attr "type" "dmul")])
+
+(define_insn ""
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
+ (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
+ (match_operand:DF 2 "gpc_reg_operand" "f"))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (DFmode)"
"{fnms|fnmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul")])
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index c4501ee..bc187c5 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3670,6 +3670,14 @@ For these operators, if only one operand is a @code{neg}, @code{not},
@code{mult}, @code{plus}, or @code{minus} expression, it will be the
first operand.
+@item
+In combinations of @code{neg}, @code{mult}, @code{plus}, and
+@code{minus}, the @code{neg} operations (if any) will be moved inside
+the operations as far as possible. For instance,
+@code{(neg (mult A B))} is canonicalized as @code{(mult (neg A) B)}, but
+@code{(plus (mult (neg A) B) C)} is canonicalized as
+@code{(minus A (mult B C))}.
+
@cindex @code{compare}, canonicalization of
@item
For the @code{compare} operator, a constant is always the second operand
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0695cfb..c8181d4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2002-12-04 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.dg/ppc-fmadd-1.c: New file.
+ * gcc.dg/ppc-fmadd-2.c: New file.
+ * gcc.dg/ppc-fmadd-3.c: New file.
+
2002-12-04 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/compile/20021204-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/ppc-fmadd-1.c b/gcc/testsuite/gcc.dg/ppc-fmadd-1.c
new file mode 100644
index 0000000..ff959f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ppc-fmadd-1.c
@@ -0,0 +1,43 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-ffast-math -O2" } */
+/* { dg-final { scan-assembler-not "f(add|sub|mul|neg)" } } */
+
+void foo(double *a, double *b, double *c, double *d)
+{
+ a[0] = b[0] + c[0] * d[0]; // fmadd
+ a[1] = b[1] - c[1] * d[1]; // fnmsub with fast-math
+ a[2] = -b[2] + c[2] * d[2]; // fmsub
+ a[3] = -b[3] - c[3] * d[3]; // fnmadd with fast-math
+ a[4] = -( b[4] + c[4] * d[4]); // fnmadd
+ a[5] = -( b[5] - c[5] * d[5]); // fmsub with fast-math
+ a[6] = -(-b[6] + c[6] * d[6]); // fnmsub
+ a[7] = -(-b[7] - c[7] * d[7]); // fmadd with fast-math
+ a[10] = b[10] - c[10] * -d[10]; // fmadd
+ a[11] = b[11] + c[11] * -d[11]; // fnmsub with fast-math
+ a[12] = -b[12] - c[12] * -d[12]; // fmsub
+ a[13] = -b[13] + c[13] * -d[13]; // fnmadd with fast-math
+ a[14] = -( b[14] - c[14] * -d[14]); // fnmadd
+ a[15] = -( b[15] + c[15] * -d[15]); // fmsub with fast-math
+ a[16] = -(-b[16] - c[16] * -d[16]); // fnmsub
+ a[17] = -(-b[17] + c[17] * -d[17]); // fmadd with fast-math
+}
+
+void foos(float *a, float *b, float *c, float *d)
+{
+ a[0] = b[0] + c[0] * d[0]; // fmadd
+ a[1] = b[1] - c[1] * d[1]; // fnmsub with fast-math
+ a[2] = -b[2] + c[2] * d[2]; // fmsub
+ a[3] = -b[3] - c[3] * d[3]; // fnmadd with fast-math
+ a[4] = -( b[4] + c[4] * d[4]); // fnmadd
+ a[5] = -( b[5] - c[5] * d[5]); // fmsub with fast-math
+ a[6] = -(-b[6] + c[6] * d[6]); // fnmsub
+ a[7] = -(-b[7] - c[7] * d[7]); // fmadd with fast-math
+ a[10] = b[10] - c[10] * -d[10]; // fmadd
+ a[11] = b[11] + c[11] * -d[11]; // fnmsub with fast-math
+ a[12] = -b[12] - c[12] * -d[12]; // fmsub
+ a[13] = -b[13] + c[13] * -d[13]; // fnmadd with fast-math
+ a[14] = -( b[14] - c[14] * -d[14]); // fnmadd
+ a[15] = -( b[15] + c[15] * -d[15]); // fmsub with fast-math
+ a[16] = -(-b[16] - c[16] * -d[16]); // fnmsub
+ a[17] = -(-b[17] + c[17] * -d[17]); // fmadd with fast-math
+}
diff --git a/gcc/testsuite/gcc.dg/ppc-fmadd-2.c b/gcc/testsuite/gcc.dg/ppc-fmadd-2.c
new file mode 100644
index 0000000..02ed811
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ppc-fmadd-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "f(add|sub|mul|neg)" } } */
+
+void foo(double *a, double *b, double *c, double *d)
+{
+ a[0] = b[0] + c[0] * d[0]; // fmadd
+ a[2] = -b[2] + c[2] * d[2]; // fmsub
+ a[4] = -( b[4] + c[4] * d[4]); // fnmadd
+ a[6] = -(-b[6] + c[6] * d[6]); // fnmsub
+ a[10] = b[10] - c[10] * -d[10]; // fmadd
+ a[12] = -b[12] - c[12] * -d[12]; // fmsub
+ a[14] = -( b[14] - c[14] * -d[14]); // fnmadd
+ a[16] = -(-b[16] - c[16] * -d[16]); // fnmsub
+}
+
+void foos(float *a, float *b, float *c, float *d)
+{
+ a[0] = b[0] + c[0] * d[0]; // fmadd
+ a[2] = -b[2] + c[2] * d[2]; // fmsub
+ a[4] = -( b[4] + c[4] * d[4]); // fnmadd
+ a[6] = -(-b[6] + c[6] * d[6]); // fnmsub
+ a[10] = b[10] - c[10] * -d[10]; // fmadd
+ a[12] = -b[12] - c[12] * -d[12]; // fmsub
+ a[14] = -( b[14] - c[14] * -d[14]); // fnmadd
+ a[16] = -(-b[16] - c[16] * -d[16]); // fnmsub
+}
diff --git a/gcc/testsuite/gcc.dg/ppc-fmadd-3.c b/gcc/testsuite/gcc.dg/ppc-fmadd-3.c
new file mode 100644
index 0000000..d420522
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ppc-fmadd-3.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "f(add|sub|mul)" } } */
+
+void foo(double *a, double *b, double *c, double *d)
+{
+#if 0
+ a[1] = b[1] - c[1] * d[1]; // fneg, fmadd without fast-math
+#endif
+ a[3] = -b[3] - c[3] * d[3]; // fneg, fmsub without fast-math
+#if 0
+ a[5] = -( b[5] - c[5] * d[5]); // fneg, fnmadd without fast-math
+#endif
+ a[7] = -(-b[7] - c[7] * d[7]); // fneg, fnmsub without fast-math
+ a[11] = b[11] + c[11] * -d[11]; // fneg, fmadd without fast-math
+ a[13] = -b[13] + c[13] * -d[13]; // fneg, fmsub without fast-math
+ a[15] = -( b[15] + c[15] * -d[15]); // fneg, fnmadd without fast-math
+ a[17] = -(-b[17] + c[17] * -d[17]); // fneg, fnmsub without fast-math
+}
+
+void foos(float *a, float *b, float *c, float *d)
+{
+#if 0
+ a[1] = b[1] - c[1] * d[1]; // fneg, fmadd without fast-math
+#endif
+ a[3] = -b[3] - c[3] * d[3]; // fneg, fmsub without fast-math
+#if 0
+ a[5] = -( b[5] - c[5] * d[5]); // fneg, fnmadd without fast-math
+#endif
+ a[7] = -(-b[7] - c[7] * d[7]); // fneg, fnmsub without fast-math
+ a[11] = b[11] + c[11] * -d[11]; // fneg, fmadd without fast-math
+ a[13] = -b[13] + c[13] * -d[13]; // fneg, fmsub without fast-math
+ a[15] = -( b[15] + c[15] * -d[15]); // fneg, fnmadd without fast-math
+ a[17] = -(-b[17] + c[17] * -d[17]); // fneg, fnmsub without fast-math
+}
+