[llvm] r189724 - SimplifyLibCalls: When emitting an overloaded fp function check that it's available.

Benjamin Kramer benny.kra at googlemail.com
Sat Aug 31 11:19:35 PDT 2013


Author: d0k
Date: Sat Aug 31 13:19:35 2013
New Revision: 189724

URL: http://llvm.org/viewvc/llvm-project?rev=189724&view=rev
Log:
SimplifyLibCalls: When emitting an overloaded fp function check that it's available.

The existing code missed some edge cases when e.g. we're going to emit sqrtf but
only the availability of sqrt was checked. This happens on odd platforms like
windows.

Modified:
    llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/trunk/test/Transforms/InstCombine/win-math.ll

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=189724&r1=189723&r2=189724&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Sat Aug 31 13:19:35 2013
@@ -118,6 +118,21 @@ static bool callHasFloatingPointArgument
   return false;
 }
 
+/// \brief Check whether the overloaded unary floating point function
+/// corresponing to \a Ty is available.
+static bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
+                            LibFunc::Func DoubleFn, LibFunc::Func FloatFn,
+                            LibFunc::Func LongDoubleFn) {
+  switch (Ty->getTypeID()) {
+  case Type::FloatTyID:
+    return TLI->has(FloatFn);
+  case Type::DoubleTyID:
+    return TLI->has(DoubleFn);
+  default:
+    return TLI->has(LongDoubleFn);
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // Fortified Library Call Optimizations
 //===----------------------------------------------------------------------===//
@@ -1137,7 +1152,9 @@ struct PowOpt : public UnsafeFPLibCallOp
       if (Op1C->isExactlyValue(1.0))
         return Op1C;
       // pow(2.0, x) -> exp2(x)
-      if (Op1C->isExactlyValue(2.0) && TLI->has(LibFunc::exp2))
+      if (Op1C->isExactlyValue(2.0) &&
+          hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f,
+                          LibFunc::exp2l))
         return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes());
     }
 
@@ -1148,7 +1165,10 @@ struct PowOpt : public UnsafeFPLibCallOp
       return ConstantFP::get(CI->getType(), 1.0);
 
     if (Op2C->isExactlyValue(0.5) &&
-        TLI->has(LibFunc::sqrt) && TLI->has(LibFunc::fabs)) {
+        hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf,
+                        LibFunc::sqrtl) &&
+        hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf,
+                        LibFunc::fabsl)) {
       // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))).
       // This is faster than calling pow, and still handles negative zero
       // and negative infinity correctly.
@@ -1181,7 +1201,7 @@ struct Exp2Opt : public UnsafeFPLibCallO
   virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
     Value *Ret = NULL;
     if (UnsafeFPShrink && Callee->getName() == "exp2" &&
-        TLI->has(LibFunc::exp2)) {
+        TLI->has(LibFunc::exp2f)) {
       UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
       Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
     }

Modified: llvm/trunk/test/Transforms/InstCombine/win-math.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/win-math.ll?rev=189724&r1=189723&r2=189724&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/win-math.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/win-math.ll Sat Aug 31 13:19:35 2013
@@ -273,3 +273,23 @@ define float @float_round(float %x) noun
     ret float %3
 }
 
+declare float @powf(float, float)
+; win32 lacks sqrtf&fabsf, win64 lacks fabsf
+define float @float_powsqrt(float %x) nounwind readnone {
+; WIN32-LABEL: @float_powsqrt(
+; WIN32-NOT: float @sqrtf
+; WIN32: float @powf
+; WIN64-LABEL: @float_powsqrt(
+; WIN64-NOT: float @sqrtf
+; WIN64: float @powf
+; MINGW32-LABEL: @float_powsqrt(
+; MINGW32: float @sqrtf
+; MINGW32: float @fabsf
+; MINGW32-NOT: float @powf
+; MINGW64-LABEL: @float_powsqrt(
+; MINGW64: float @sqrtf
+; MINGW64: float @fabsf
+; MINGW64-NOT: float @powf
+    %1 = call float @powf(float %x, float 0.5)
+    ret float %1
+}





More information about the llvm-commits mailing list