aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@apple.com>2011-07-08 21:39:34 +0000
committerCameron Zwarich <zwarich@apple.com>2011-07-08 21:39:34 +0000
commit094240ab184c3ca4b94e9d7eac80fcd34d8dd30c (patch)
tree8fa8ee4cd326eb99607e992b866d868896921b59
parent54cf341bd4145e5e31f91c5777fcdaf3f2400537 (diff)
Add codegen support for the fma/fmal/fmaf builtins.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134743 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/Builtins.def4
-rw-r--r--lib/CodeGen/CGBuiltin.cpp16
-rw-r--r--test/CodeGen/libcalls.c23
3 files changed, 43 insertions, 0 deletions
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index d9401d11a2..87328c7009 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -729,6 +729,10 @@ LIBBUILTIN(cos, "dd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cosl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cosf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fma, "dddd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmal, "LdLdLdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaf, "ffff", "fc", "math.h", ALL_LANGUAGES)
+
// Blocks runtime Builtin math library functions
LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 0ad05a75cc..269917b442 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -983,6 +983,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
}
+ case Builtin::BIfma:
+ case Builtin::BIfmaf:
+ case Builtin::BIfmal:
+ case Builtin::BI__builtin_fma:
+ case Builtin::BI__builtin_fmaf:
+ case Builtin::BI__builtin_fmal: {
+ // Rewrite fma to intrinsic.
+ Value *FirstArg = EmitScalarExpr(E->getArg(0));
+ const llvm::Type *ArgType = FirstArg->getType();
+ Value *F = CGM.getIntrinsic(Intrinsic::fma, &ArgType, 1);
+ return RValue::get(Builder.CreateCall3(F, FirstArg,
+ EmitScalarExpr(E->getArg(1)),
+ EmitScalarExpr(E->getArg(2)),
+ "tmp"));
+ }
+
case Builtin::BI__builtin_signbit:
case Builtin::BI__builtin_signbitf:
case Builtin::BI__builtin_signbitl: {
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index 828d7de6cb..5ff684fd5b 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -50,3 +50,26 @@ void test_pow(float a0, double a1, long double a2) {
// CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly
// CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly
// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly
+
+// CHECK-YES: define void @test_fma
+// CHECK-NO: define void @test_fma
+void test_fma(float a0, double a1, long double a2) {
+ // CHECK-YES: call float @llvm.fma.f32
+ // CHECK-NO: call float @llvm.fma.f32
+ float l0 = fmaf(a0, a0, a0);
+
+ // CHECK-YES: call double @llvm.fma.f64
+ // CHECK-NO: call double @llvm.fma.f64
+ double l1 = fma(a1, a1, a1);
+
+ // CHECK-YES: call x86_fp80 @llvm.fma.f80
+ // CHECK-NO: call x86_fp80 @llvm.fma.f80
+ long double l2 = fmal(a2, a2, a2);
+}
+
+// CHECK-YES: declare float @llvm.fma.f32(float, float, float) nounwind readnone
+// CHECK-YES: declare double @llvm.fma.f64(double, double, double) nounwind readnone
+// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone
+// CHECK-NO: declare float @llvm.fma.f32(float, float, float) nounwind readnone
+// CHECK-NO: declare double @llvm.fma.f64(double, double, double) nounwind readnone
+// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone