diff options
author | Owen Anderson <resistor@mac.com> | 2013-05-09 22:27:13 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2013-05-09 22:27:13 +0000 |
commit | 32baf99b1d46570b6e34b2c1092e43abd845ef7a (patch) | |
tree | c29bd6dc1fa49373ff7f60c6bc2014cc5fe79425 /llvm | |
parent | 37f25ae3cf7e1bd2fc131b303b2342e67384003b (diff) | |
download | bcm5719-llvm-32baf99b1d46570b6e34b2c1092e43abd845ef7a.tar.gz bcm5719-llvm-32baf99b1d46570b6e34b2c1092e43abd845ef7a.zip |
Teach SelectionDAG to constant fold all-constant FMA nodes the same way that it constant folds FADD, FMUL, etc.
llvm-svn: 181555
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/fma.ll | 8 |
2 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 15235c8ac30..f2c512dec7a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3261,6 +3261,21 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT, // Perform various simplifications. ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode()); switch (Opcode) { + case ISD::FMA: { + ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1); + ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2); + ConstantFPSDNode *N3CFP = dyn_cast<ConstantFPSDNode>(N3); + if (N1CFP && N2CFP && N3CFP) { + APFloat V1 = N1CFP->getValueAPF(); + const APFloat &V2 = N2CFP->getValueAPF(); + const APFloat &V3 = N3CFP->getValueAPF(); + APFloat::opStatus s = + V1.fusedMultiplyAdd(V2, V3, APFloat::rmNearestTiesToEven); + if (s != APFloat::opInvalidOp) + return getConstantFP(V1, VT); + } + break; + } case ISD::CONCAT_VECTORS: // A CONCAT_VECTOR with all operands BUILD_VECTOR can be simplified to // one big BUILD_VECTOR. diff --git a/llvm/test/CodeGen/X86/fma.ll b/llvm/test/CodeGen/X86/fma.ll index bd3514cc3f7..917eac0ca32 100644 --- a/llvm/test/CodeGen/X86/fma.ll +++ b/llvm/test/CodeGen/X86/fma.ll @@ -34,6 +34,14 @@ entry: ret x86_fp80 %call } +; CHECK: test_f32_cst +; CHECK-NOT: fma +define float @test_f32_cst() nounwind readnone ssp { +entry: + %call = tail call float @llvm.fma.f32(float 3.0, float 3.0, float 3.0) nounwind readnone + ret float %call +} + declare float @llvm.fma.f32(float, float, float) nounwind readnone declare double @llvm.fma.f64(double, double, double) nounwind readnone declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone |