]> granicus.if.org Git - llvm/commitdiff
[GISel]: Add G_FMA opcode for fused multiply adds
authorAditya Nandakumar <aditya_nandakumar@apple.com>
Tue, 20 Jun 2017 19:25:23 +0000 (19:25 +0000)
committerAditya Nandakumar <aditya_nandakumar@apple.com>
Tue, 20 Jun 2017 19:25:23 +0000 (19:25 +0000)
https://reviews.llvm.org/D34372

Reviewed by dsanders

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305824 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/GenericOpcodes.td
include/llvm/Target/TargetOpcodes.def
lib/CodeGen/GlobalISel/IRTranslator.cpp
test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

index de3796cd4ee5639771006646502fb4ff5d7a60b8..ed31e84046c8c9660c7f968382c3c82dfa255637 100644 (file)
@@ -386,6 +386,14 @@ def G_FMUL : Instruction {
   let isCommutable = 1;
 }
 
+// Generic fused multiply-add instruction.
+def G_FMA : Instruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
+  let hasSideEffects = 0;
+  let isCommutable = 0;
+}
+
 // Generic FP division.
 def G_FDIV : Instruction {
   let OutOperandList = (outs type0:$dst);
index 36764249632da801c93c3ea601b7d45981349c21..e2a67a9460ddd260959354601d090f3cfac69891 100644 (file)
@@ -359,6 +359,9 @@ HANDLE_TARGET_OPCODE(G_FSUB)
 /// Generic FP multiplication.
 HANDLE_TARGET_OPCODE(G_FMUL)
 
+/// Generic FMA multiplication. Behaves like llvm fma intrinsic
+HANDLE_TARGET_OPCODE(G_FMA)
+
 /// Generic FP division.
 HANDLE_TARGET_OPCODE(G_FDIV)
 
index dccd8e0706ca69c72e747fd1e1dfbde26025e4a3..7fefbf90922d25d963dc26bc3411f1d35a2c0570 100644 (file)
@@ -686,6 +686,13 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
         .addUse(getOrCreateVReg(*CI.getArgOperand(0)))
         .addUse(getOrCreateVReg(*CI.getArgOperand(1)));
     return true;
+  case Intrinsic::fma:
+    MIRBuilder.buildInstr(TargetOpcode::G_FMA)
+        .addDef(getOrCreateVReg(CI))
+        .addUse(getOrCreateVReg(*CI.getArgOperand(0)))
+        .addUse(getOrCreateVReg(*CI.getArgOperand(1)))
+        .addUse(getOrCreateVReg(*CI.getArgOperand(2)));
+    return true;
   case Intrinsic::memcpy:
   case Intrinsic::memmove:
   case Intrinsic::memset:
index 65b8ba57070116efdee691f4190ce2365ed2ec7e..e07d5ad8410a63a9f354e159f3209fd4be2042c7 100644 (file)
@@ -1247,6 +1247,18 @@ define float @test_pow_intrin(float %l, float %r) {
   ret float %res
 }
 
+declare float @llvm.fma.f32(float, float, float)
+define float @test_fma_intrin(float %a, float %b, float %c) {
+; CHECK-LABEL: name: test_fma_intrin
+; CHECK: [[A:%[0-9]+]](s32) = COPY %s0
+; CHECK: [[B:%[0-9]+]](s32) = COPY %s1
+; CHECK: [[C:%[0-9]+]](s32) = COPY %s2
+; CHECK: [[RES:%[0-9]+]](s32) = G_FMA [[A]], [[B]], [[C]]
+; CHECK: %s0 = COPY [[RES]]
+  %res = call float @llvm.fma.f32(float %a, float %b, float %c)
+  ret float %res
+}
+
 declare void @llvm.lifetime.start.p0i8(i64, i8*)
 declare void @llvm.lifetime.end.p0i8(i64, i8*)
 define void @test_lifetime_intrin() {