diff options
author | Owen Anderson <resistor@mac.com> | 2012-05-02 22:17:40 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2012-05-02 22:17:40 +0000 |
commit | 062c0a5b58b756b91811bf3e6e978257c9fda3ff (patch) | |
tree | 12ccaa115206bde970b3c09b41947f216575f9f6 | |
parent | c0f0a93936a23a0935aa946a65095388b50c087f (diff) | |
download | external_llvm-062c0a5b58b756b91811bf3e6e978257c9fda3ff.zip external_llvm-062c0a5b58b756b91811bf3e6e978257c9fda3ff.tar.gz external_llvm-062c0a5b58b756b91811bf3e6e978257c9fda3ff.tar.bz2 |
Teach DAGCombine the same multiply-by-1.0 folding trick when doing FMAs, just like it now knows for FMULs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156029 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 18 | ||||
-rw-r--r-- | test/CodeGen/ARM/fusedMAC.ll | 9 |
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index b8f08bf..c2b7f6c 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -215,6 +215,7 @@ namespace { SDValue visitFADD(SDNode *N); SDValue visitFSUB(SDNode *N); SDValue visitFMUL(SDNode *N); + SDValue visitFMA(SDNode *N); SDValue visitFDIV(SDNode *N); SDValue visitFREM(SDNode *N); SDValue visitFCOPYSIGN(SDNode *N); @@ -1126,6 +1127,7 @@ SDValue DAGCombiner::visit(SDNode *N) { case ISD::FADD: return visitFADD(N); case ISD::FSUB: return visitFSUB(N); case ISD::FMUL: return visitFMUL(N); + case ISD::FMA: return visitFMA(N); case ISD::FDIV: return visitFDIV(N); case ISD::FREM: return visitFREM(N); case ISD::FCOPYSIGN: return visitFCOPYSIGN(N); @@ -5751,6 +5753,22 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { return SDValue(); } +SDValue DAGCombiner::visitFMA(SDNode *N) { + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); + ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0); + ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1); + EVT VT = N->getValueType(0); + + if (N0CFP && N0CFP->isExactlyValue(1.0)) + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N1, N2); + if (N1CFP && N1CFP->isExactlyValue(1.0)) + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N2); + + return SDValue(); +} + SDValue DAGCombiner::visitFDIV(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); diff --git a/test/CodeGen/ARM/fusedMAC.ll b/test/CodeGen/ARM/fusedMAC.ll index 1ad7ce1..fd7fdd5 100644 --- a/test/CodeGen/ARM/fusedMAC.ll +++ b/test/CodeGen/ARM/fusedMAC.ll @@ -180,6 +180,15 @@ entry: ret double %tmp3 } +define float @test_fma_const_fold(float %a, float %b) nounwind { +; CHECK: test_fma_const_fold +; CHECK-NOT: vfma +; CHECK-NOT: vmul +; CHECK: vadd + %ret = call float @llvm.fma.f32(float %a, float 1.0, float %b) + ret float %ret +} + declare float @llvm.fma.f32(float, float, float) nounwind readnone declare double @llvm.fma.f64(double, double, double) nounwind readnone declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) nounwind readnone |