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
This commit is contained in:
parent
76508852a0
commit
16823694d5
@ -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.
|
||||
|
@ -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))
|
||||
|
@ -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")])
|
||||
|
||||
@ -5293,12 +5304,33 @@
|
||||
"{fnma|fnmadd} %0,%1,%2,%3"
|
||||
[(set_attr "type" "dmul")])
|
||||
|
||||
(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")])
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
43
gcc/testsuite/gcc.dg/ppc-fmadd-1.c
Normal file
43
gcc/testsuite/gcc.dg/ppc-fmadd-1.c
Normal file
@ -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
|
||||
}
|
27
gcc/testsuite/gcc.dg/ppc-fmadd-2.c
Normal file
27
gcc/testsuite/gcc.dg/ppc-fmadd-2.c
Normal file
@ -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
|
||||
}
|
36
gcc/testsuite/gcc.dg/ppc-fmadd-3.c
Normal file
36
gcc/testsuite/gcc.dg/ppc-fmadd-3.c
Normal file
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user