]> granicus.if.org Git - clang/commitdiff
CGBuiltin: Use @llvm.fabs rather than fabs libcall when emitting builtins
authorTom Stellard <thomas.stellard@amd.com>
Wed, 3 Sep 2014 15:24:29 +0000 (15:24 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Wed, 3 Sep 2014 15:24:29 +0000 (15:24 +0000)
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
test/CodeGen/builtins.c

index b74038e075189913f55a538c00efc879ca4d7e92..6b14796160fe091d58bfa2e9035806c618f9ff1b 100644 (file)
@@ -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,
index 39bd84c5a5a4e7442039ce1807f5ec3ce7e5dea0..451ed07c738895d333d169deccf06bebe9a98382 100644 (file)
@@ -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