Handle llvm.fma.* intrinsics. rdar://10914096
authorEvan Cheng <evan.cheng@apple.com>
Tue, 10 Apr 2012 21:40:28 +0000 (21:40 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 10 Apr 2012 21:40:28 +0000 (21:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154439 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMInstrNEON.td
lib/Target/ARM/ARMInstrVFP.td
test/CodeGen/ARM/fma.ll [new file with mode: 0644]

index fcb4f4fd097bb20df8a11de1e18c7e9dfc246453..a103c94cede4f612a7a8ce2d5f3c69a7cda109f3 100644 (file)
@@ -769,8 +769,10 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::FPOW,      MVT::f64, Expand);
   setOperationAction(ISD::FPOW,      MVT::f32, Expand);
 
-  setOperationAction(ISD::FMA, MVT::f64, Expand);
-  setOperationAction(ISD::FMA, MVT::f32, Expand);
+  if (!Subtarget->hasVFP4()) {
+    setOperationAction(ISD::FMA, MVT::f64, Expand);
+    setOperationAction(ISD::FMA, MVT::f32, Expand);
+  }
 
   // Various VFP goodness
   if (!TM.Options.UseSoftFloat && !Subtarget->isThumb1Only()) {
index ae52d386bd3afb82940906b89ee5d9c83c1bb5ba..99dbb95431ae9299b0c4bf225438250fbb16a3ae 100644 (file)
@@ -4133,6 +4133,14 @@ def  VFMSfq   : N3VQMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACQ, "vfms", "f32",
                           v4f32, fmul_su, fsub_mlx>,
                 Requires<[HasNEON2,FPContractions]>;
 
+// Match @llvm.fma.* intrinsics
+def : Pat<(fma (v2f32 DPR:$src1), (v2f32 DPR:$Vn), (v2f32 DPR:$Vm)),
+          (VFMAfd DPR:$src1, DPR:$Vn, DPR:$Vm)>,
+          Requires<[HasNEON, HasVFP4]>;
+def : Pat<(fma (v4f32 QPR:$src1), (v4f32 QPR:$Vn), (v4f32 QPR:$Vm)),
+          (VFMAfq QPR:$src1, QPR:$Vn, QPR:$Vm)>,
+          Requires<[HasNEON, HasVFP4]>;
+
 // Vector Subtract Operations.
 
 //   VSUB     : Vector Subtract (integer and floating-point)
index e9d572089b776a2bb0694e9f33dff20f81ea5b2f..a9ad4fa4ec48362aa3a44dbeb58c052230e18c24 100644 (file)
@@ -1080,6 +1080,14 @@ def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
           (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>,
           Requires<[HasVFP4,DontUseNEONForFP,FPContractions]>;
 
+// Match @llvm.fma.* intrinsics
+def : Pat<(fma (f64 DPR:$Ddin), (f64 DPR:$Dn), (f64 DPR:$Dm)),
+          (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
+      Requires<[HasVFP4]>;
+def : Pat<(fma (f32 SPR:$Sdin), (f32 SPR:$Sn), (f32 SPR:$Sm)),
+          (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
+      Requires<[HasVFP4]>;
+
 def VFMSD : ADbI<0b11101, 0b10, 1, 0,
                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
                  IIC_fpFMAC64, "vfms", ".f64\t$Dd, $Dn, $Dm",
diff --git a/test/CodeGen/ARM/fma.ll b/test/CodeGen/ARM/fma.ll
new file mode 100644 (file)
index 0000000..ff8aa34
--- /dev/null
@@ -0,0 +1,30 @@
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mattr=+vfp4 | FileCheck %s
+
+define float @test_f32(float %a, float %b, float %c) nounwind readnone ssp {
+entry:
+; CHECK: test_f32
+; CHECK: vfma.f32
+  %call = tail call float @llvm.fma.f32(float %a, float %b, float %c) nounwind readnone
+  ret float %call
+}
+
+define double @test_f64(double %a, double %b, double %c) nounwind readnone ssp {
+entry:
+; CHECK: test_f64
+; CHECK: vfma.f64
+  %call = tail call double @llvm.fma.f64(double %a, double %b, double %c) nounwind readnone
+  ret double %call
+}
+
+define <2 x float> @test_v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone ssp {
+entry:
+; CHECK: test_v2f32
+; CHECK: vfma.f32
+  %0 = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind
+  ret <2 x float> %0
+}
+
+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