From d91dc0875630e6d2c81363b2801ed47257daa026 Mon Sep 17 00:00:00 2001
From: Tom Stellard <thomas.stellard@amd.com>
Date: Wed, 3 Sep 2014 15:24:29 +0000
Subject: [PATCH] CGBuiltin: Use @llvm.fabs rather than fabs libcall when
 emitting builtins

Using the intrinsic allows the SelectionDAGBuilder to turn this call
into the FABS Node and also the intrinsic is something the vectorizer knows
how to vectorize.

This patch also sets the readnone attribute on this call, which should
enable additional optmizations.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217042 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGBuiltin.cpp | 24 +++++-------------------
 test/CodeGen/builtins.c   | 10 +++++-----
 2 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index b74038e0751..6b14796160f 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -142,26 +142,12 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
   return RValue::get(Result);
 }
 
-/// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy,
-/// which must be a scalar floating point type.
+/// EmitFAbs - Emit a call to @llvm.fabs().
 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) {
-  const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>();
-  assert(ValTyP && "isn't scalar fp type!");
-
-  StringRef FnName;
-  switch (ValTyP->getKind()) {
-  default: llvm_unreachable("Isn't a scalar fp type!");
-  case BuiltinType::Float:      FnName = "fabsf"; break;
-  case BuiltinType::Double:     FnName = "fabs"; break;
-  case BuiltinType::LongDouble: FnName = "fabsl"; break;
-  }
-
-  // The prototype is something that takes and returns whatever V's type is.
-  llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), V->getType(),
-                                                   false);
-  llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName);
-
-  return CGF.EmitNounwindRuntimeCall(Fn, V, "abs");
+  Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
+  llvm::CallInst *Call = CGF.Builder.CreateCall(F, V);
+  Call->setDoesNotAccessMemory();
+  return Call;
 }
 
 static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn,
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 39bd84c5a5a..451ed07c738 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -171,26 +171,26 @@ void bar() {
 void test_float_builtins(float F, double D, long double LD) {
   volatile int res;
   res = __builtin_isinf(F);
-  // CHECK:  call float @fabsf(float
+  // CHECK:  call float @llvm.fabs.f32(float
   // CHECK:  fcmp oeq float {{.*}}, 0x7FF0000000000000
 
   res = __builtin_isinf(D);
-  // CHECK:  call double @fabs(double
+  // CHECK:  call double @llvm.fabs.f64(double
   // CHECK:  fcmp oeq double {{.*}}, 0x7FF0000000000000
   
   res = __builtin_isinf(LD);
-  // CHECK:  call x86_fp80 @fabsl(x86_fp80
+  // CHECK:  call x86_fp80 @llvm.fabs.f80(x86_fp80
   // CHECK:  fcmp oeq x86_fp80 {{.*}}, 0xK7FFF8000000000000000
   
   res = __builtin_isfinite(F);
   // CHECK: fcmp oeq float 
-  // CHECK: call float @fabsf
+  // CHECK: call float @llvm.fabs.f32(float
   // CHECK: fcmp une float {{.*}}, 0x7FF0000000000000
   // CHECK: and i1 
 
   res = __builtin_isnormal(F);
   // CHECK: fcmp oeq float
-  // CHECK: call float @fabsf
+  // CHECK: call float @llvm.fabs.f32(float
   // CHECK: fcmp ult float {{.*}}, 0x7FF0000000000000
   // CHECK: fcmp uge float {{.*}}, 0x3810000000000000
   // CHECK: and i1
-- 
GitLab