Teach SelectionDAG to constant fold all-constant FMA nodes the same way that it const...
authorOwen Anderson <resistor@mac.com>
Thu, 9 May 2013 22:27:13 +0000 (22:27 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 9 May 2013 22:27:13 +0000 (22:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181555 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
test/CodeGen/X86/fma.ll

index 15235c8ac307737bbd6867e6083d85d24dbbef39..f2c512dec7a5da315cbf35c74fbda4d63153e9ca 100644 (file)
@@ -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.
index bd3514cc3f7329951f498fb9c64e6f128d5773bf..917eac0ca32dec91fe4ae5ef5517021bc061db55 100644 (file)
@@ -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