aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-12-14 22:54:33 +0000
committerNate Begeman <natebegeman@mac.com>2005-12-14 22:54:33 +0000
commita07da92624219599e6569460b3b56b49d60a4b46 (patch)
tree4ad9257a849539d4a3b7138b4b7efc2f7d1e849e
parent1dae25e23ac4edd64a124b3d831282ceaf3610ea (diff)
Use the new predicate support that Evan Cheng added to remove some code
from the DAGToDAG cpp file. This adds pattern support for vector and scalar fma, which passes test/Regression/CodeGen/PowerPC/fma.ll, and does the right thing in the presence of -disable-excess-fp-precision. Allows us to match: void %foo(<4 x float> * %a) { entry: %tmp1 = load <4 x float> * %a; %tmp2 = mul <4 x float> %tmp1, %tmp1 %tmp3 = add <4 x float> %tmp2, %tmp1 store <4 x float> %tmp3, <4 x float> *%a ret void } As: _foo: li r2, 0 lvx v0, r2, r3 vmaddfp v0, v0, v0, v0 stvx v0, r2, r3 blr Or, with llc -disable-excess-fp-precision, _foo: li r2, 0 lvx v0, r2, r3 vxor v1, v1, v1 vmaddfp v1, v0, v0, v1 vaddfp v0, v1, v0 stvx v0, r2, r3 blr git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24719 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp47
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td34
2 files changed, 24 insertions, 57 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 01d089d9b9..f666f23255 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -885,53 +885,6 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
CurDAG->getTargetFrameIndex(FI, MVT::i32),
getI32Imm(0));
}
- case ISD::FADD: {
- MVT::ValueType Ty = N->getValueType(0);
- if (!NoExcessFPPrecision) { // Match FMA ops
- if (N->getOperand(0).getOpcode() == ISD::FMUL &&
- N->getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD :PPC::FMADDS,
- Ty, Select(N->getOperand(0).getOperand(0)),
- Select(N->getOperand(0).getOperand(1)),
- Select(N->getOperand(1)));
- } else if (N->getOperand(1).getOpcode() == ISD::FMUL &&
- N->getOperand(1).hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD :PPC::FMADDS,
- Ty, Select(N->getOperand(1).getOperand(0)),
- Select(N->getOperand(1).getOperand(1)),
- Select(N->getOperand(0)));
- }
- }
-
- // Other cases are autogenerated.
- break;
- }
- case ISD::FSUB: {
- MVT::ValueType Ty = N->getValueType(0);
-
- if (!NoExcessFPPrecision) { // Match FMA ops
- if (N->getOperand(0).getOpcode() == ISD::FMUL &&
- N->getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMSUB:PPC::FMSUBS,
- Ty, Select(N->getOperand(0).getOperand(0)),
- Select(N->getOperand(0).getOperand(1)),
- Select(N->getOperand(1)));
- } else if (N->getOperand(1).getOpcode() == ISD::FMUL &&
- N->getOperand(1).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ?PPC::FNMSUB:PPC::FNMSUBS,
- Ty, Select(N->getOperand(1).getOperand(0)),
- Select(N->getOperand(1).getOperand(1)),
- Select(N->getOperand(0)));
- }
- }
-
- // Other cases are autogenerated.
- break;
- }
case ISD::SDIV: {
// FIXME: since this depends on the setting of the carry flag from the srawi
// we should really be making notes about that for the scheduler.
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 04011e8513..4ec8fe3346 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -168,7 +168,7 @@ def crbitm: Operand<i8> {
//===----------------------------------------------------------------------===//
// PowerPC Instruction Predicate Definitions.
-def FPContractions : Predicate<"!NoExcessFPPrecision">;
+def FPContractions : Predicate<"NoExcessFPPrecision">;
//===----------------------------------------------------------------------===//
// PowerPC Instruction Definitions.
@@ -746,22 +746,26 @@ def FNMADD : AForm_1<63, 31,
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
"fnmadd $FRT, $FRA, $FRC, $FRB", FPFused,
[(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
- F8RC:$FRB)))]>;
+ F8RC:$FRB)))]>,
+ Requires<[FPContractions]>;
def FNMADDS : AForm_1<59, 31,
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
"fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral,
[(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC),
- F4RC:$FRB)))]>;
+ F4RC:$FRB)))]>,
+ Requires<[FPContractions]>;
def FNMSUB : AForm_1<63, 30,
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
"fnmsub $FRT, $FRA, $FRC, $FRB", FPFused,
[(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC),
- F8RC:$FRB)))]>;
+ F8RC:$FRB)))]>,
+ Requires<[FPContractions]>;
def FNMSUBS : AForm_1<59, 30,
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
"fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral,
[(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC),
- F4RC:$FRB)))]>;
+ F4RC:$FRB)))]>,
+ Requires<[FPContractions]>;
// FSEL is artificially split into 4 and 8-byte forms for the result. To avoid
// having 4 of these, force the comparison to always be an 8-byte double (code
// should use an FMRSD if the input comparison value really wants to be a float)
@@ -848,12 +852,14 @@ def RLDICR : MDForm_1<30, 1,
def VMADDFP : VAForm_1<46, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC),
"vmaddfp $vD, $vA, $vC, $vB", VecFP,
[(set VRRC:$vD, (fadd (fmul VRRC:$vA, VRRC:$vC),
- VRRC:$vB))]>;
+ VRRC:$vB))]>,
+ Requires<[FPContractions]>;
def VNMSUBFP: VAForm_1<47, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC),
- "vnmsubfp $vD, $vA, $vC, $vB", VecFP,
- [(set VRRC:$vD, (fneg (fsub (fmul VRRC:$vA,
- VRRC:$vC),
- VRRC:$vB)))]>;
+ "vnmsubfp $vD, $vA, $vC, $vB", VecFP,
+ [(set VRRC:$vD, (fneg (fsub (fmul VRRC:$vA,
+ VRRC:$vC),
+ VRRC:$vB)))]>,
+ Requires<[FPContractions]>;
// VX-Form instructions. AltiVec arithmetic ops.
def VADDFP : VXForm_1<10, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
@@ -971,6 +977,14 @@ def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)),
def : Pat<(fmul VRRC:$vA, VRRC:$vB),
(VMADDFP VRRC:$vA, (V_SET0), VRRC:$vB)>;
+// Fused negative multiply subtract, alternate pattern
+def : Pat<(fsub F8RC:$B, (fmul F8RC:$A, F8RC:$C)),
+ (FNMSUB F8RC:$A, F8RC:$C, F8RC:$B)>,
+ Requires<[FPContractions]>;
+def : Pat<(fsub F4RC:$B, (fmul F4RC:$A, F4RC:$C)),
+ (FNMSUBS F4RC:$A, F4RC:$C, F4RC:$B)>,
+ Requires<[FPContractions]>;
+
// Fused multiply add and multiply sub for packed float. These are represented
// separately from the real instructions above, for operations that must have
// the additional precision, such as Newton-Rhapson (used by divide, sqrt)