From 094240ab184c3ca4b94e9d7eac80fcd34d8dd30c Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Fri, 8 Jul 2011 21:39:34 +0000 Subject: [PATCH] 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 --- include/clang/Basic/Builtins.def | 4 ++++ lib/CodeGen/CGBuiltin.cpp | 16 ++++++++++++++++ test/CodeGen/libcalls.c | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+) 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 -- 2.40.0