]> granicus.if.org Git - llvm/commitdiff
SimplifyLibCalls: Replace more unary libcalls with intrinsics
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 23 Jan 2017 23:55:08 +0000 (23:55 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 23 Jan 2017 23:55:08 +0000 (23:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292855 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/SimplifyLibCalls.h
lib/Transforms/InstCombine/InstCombineCalls.cpp
lib/Transforms/InstCombine/InstCombineCasts.cpp
lib/Transforms/Utils/SimplifyLibCalls.cpp
test/Transforms/InstCombine/double-float-shrink-2.ll
test/Transforms/InstCombine/float-shrink-compare.ll
test/Transforms/InstCombine/win-math.ll

index fbeea5bd95eee375b360c23fb211dce3defdc70e..665dd6f4b257939eca7b31c73465de2ebbc28f8d 100644 (file)
@@ -128,7 +128,6 @@ private:
   Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
   Value *optimizePow(CallInst *CI, IRBuilder<> &B);
   Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
-  Value *optimizeFabs(CallInst *CI, IRBuilder<> &B);
   Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
   Value *optimizeLog(CallInst *CI, IRBuilder<> &B);
   Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
index e6e126bf784b26ed17353dcea237bf7040c6f170..07ee3c032c2be68c5d33cc8e27c69ba33fcaa3b5 100644 (file)
@@ -1680,11 +1680,18 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
       return SelectInst::Create(Cond, Call0, Call1);
     }
 
+    LLVM_FALLTHROUGH;
+  }
+  case Intrinsic::ceil:
+  case Intrinsic::floor:
+  case Intrinsic::round:
+  case Intrinsic::nearbyint:
+  case Intrinsic::trunc: {
     Value *ExtSrc;
     if (match(II->getArgOperand(0), m_FPExt(m_Value(ExtSrc))) &&
         II->getArgOperand(0)->hasOneUse()) {
       // fabs (fpext x) -> fpext (fabs x)
-      Value *F = Intrinsic::getDeclaration(II->getModule(), Intrinsic::fabs,
+      Value *F = Intrinsic::getDeclaration(II->getModule(), II->getIntrinsicID(),
                                            { ExtSrc->getType() });
       CallInst *NewFabs = Builder->CreateCall(F, ExtSrc);
       NewFabs->copyFastMathFlags(II);
index 5ba6fd6fe3259689090deaa932935163eed739dd..178920678d83dc2013bd2d4fd2a3434aaf488270 100644 (file)
@@ -1393,7 +1393,14 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) {
   if (II) {
     switch (II->getIntrinsicID()) {
     default: break;
-    case Intrinsic::fabs: {
+    case Intrinsic::fabs:
+    case Intrinsic::ceil:
+    case Intrinsic::floor:
+    case Intrinsic::rint:
+    case Intrinsic::round:
+    case Intrinsic::nearbyint:
+    case Intrinsic::trunc: {
+      // Do unary FP operation on smaller type.
       // (fptrunc (fabs x)) -> (fabs (fptrunc x))
       Value *InnerTrunc = Builder->CreateFPTrunc(II->getArgOperand(0),
                                                  CI.getType());
index 3ab933d93201ff2d3282488fadf8dc473ddc78a9..4ea051e973b5bac3c14c3025bc87c514ab7b5b8e 100644 (file)
@@ -948,6 +948,20 @@ static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B,
   return B.CreateFPExt(V, B.getDoubleTy());
 }
 
+// Replace a libcall \p CI with a call to intrinsic \p IID
+static Value *replaceUnaryCall(CallInst *CI, IRBuilder<> &B, Intrinsic::ID IID) {
+  // Propagate fast-math flags from the existing call to the new call.
+  IRBuilder<>::FastMathFlagGuard Guard(B);
+  B.setFastMathFlags(CI->getFastMathFlags());
+
+  Module *M = CI->getModule();
+  Value *V = CI->getArgOperand(0);
+  Function *F = Intrinsic::getDeclaration(M, IID, CI->getType());
+  CallInst *NewCall = B.CreateCall(F, V);
+  NewCall->takeName(CI);
+  return NewCall;
+}
+
 /// Shrink double -> float for binary functions like 'fmin/fmax'.
 static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilder<> &B) {
   Function *Callee = CI->getCalledFunction();
@@ -1210,19 +1224,6 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) {
   return Ret;
 }
 
-Value *LibCallSimplifier::optimizeFabs(CallInst *CI, IRBuilder<> &B) {
-  Function *Callee = CI->getCalledFunction();
-  IRBuilder<>::FastMathFlagGuard Guard(B);
-  B.setFastMathFlags(CI->getFastMathFlags());
-
-  // fabs/fabsf -> llvm.fabs.*
-  Value *F = Intrinsic::getDeclaration(Callee->getParent(), Intrinsic::fabs,
-                                       CI->getType());
-  Value *NewCall = B.CreateCall(F, { CI->getArgOperand(0) });
-  NewCall->takeName(CI);
-  return NewCall;
-}
-
 Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilder<> &B) {
   Function *Callee = CI->getCalledFunction();
   // If we can shrink the call to a float function rather than a double
@@ -2091,7 +2092,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
     case LibFunc_fabsf:
     case LibFunc_fabs:
     case LibFunc_fabsl:
-      return optimizeFabs(CI, Builder);
+      return replaceUnaryCall(CI, Builder, Intrinsic::fabs);
     case LibFunc_sqrtf:
     case LibFunc_sqrt:
     case LibFunc_sqrtl:
@@ -2144,14 +2145,16 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
     case LibFunc_fputc:
       return optimizeErrorReporting(CI, Builder, 1);
     case LibFunc_ceil:
+      return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
     case LibFunc_floor:
-    case LibFunc_rint:
+      return replaceUnaryCall(CI, Builder, Intrinsic::floor);
     case LibFunc_round:
+      return replaceUnaryCall(CI, Builder, Intrinsic::round);
     case LibFunc_nearbyint:
+    case LibFunc_rint:
+      return replaceUnaryCall(CI, Builder, Intrinsic::nearbyint);
     case LibFunc_trunc:
-      if (hasFloatVersion(FuncName))
-        return optimizeUnaryDoubleFP(CI, Builder, false);
-      return nullptr;
+      return replaceUnaryCall(CI, Builder, Intrinsic::trunc);
     case LibFunc_acos:
     case LibFunc_acosh:
     case LibFunc_asin:
@@ -2215,16 +2218,10 @@ void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) {
 //   * log(exp10(y)) -> y*log(10)
 //   * log(sqrt(x))  -> 0.5*log(x)
 //
-// lround, lroundf, lroundl:
-//   * lround(cnst) -> cnst'
-//
 // pow, powf, powl:
 //   * pow(sqrt(x),y) -> pow(x,y*0.5)
 //   * pow(pow(x,y),z)-> pow(x,y*z)
 //
-// round, roundf, roundl:
-//   * round(cnst) -> cnst'
-//
 // signbit:
 //   * signbit(cnst) -> cnst'
 //   * signbit(nncst) -> 0 (if pstv is a non-negative constant)
@@ -2234,10 +2231,6 @@ void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) {
 //   * sqrt(Nroot(x)) -> pow(x,1/(2*N))
 //   * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
 //
-// trunc, truncf, truncl:
-//   * trunc(cnst) -> cnst'
-//
-//
 
 //===----------------------------------------------------------------------===//
 // Fortified Library Call Optimizations
index b314fcf2f8a9eb11c29da58a2fa4fbf75e6772d0..435bd0b0fc9b641575bc860c14dbdd95eb46ab84 100644 (file)
@@ -5,21 +5,21 @@
 ; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck -check-prefix=DO-SIMPLIFY %s
 ; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck -check-prefix=DO-SIMPLIFY %s
 
-; DO-SIMPLIFY: call float @floorf(
-; DO-SIMPLIFY: call float @ceilf(
-; DO-SIMPLIFY: call float @roundf(
-; DO-SIMPLIFY: call float @nearbyintf(
-; DO-SIMPLIFY: call float @truncf(
+; DO-SIMPLIFY: call float @llvm.floor.f32(
+; DO-SIMPLIFY: call float @llvm.ceil.f32(
+; DO-SIMPLIFY: call float @llvm.round.f32(
+; DO-SIMPLIFY: call float @llvm.nearbyint.f32(
+; DO-SIMPLIFY: call float @llvm.trunc.f32(
 ; DO-SIMPLIFY: call float @llvm.fabs.f32(
 ; DO-SIMPLIFY: call fast float @llvm.fabs.f32(
 
-; C89-SIMPLIFY: call float @floorf(
-; C89-SIMPLIFY: call float @ceilf(
+; C89-SIMPLIFY: call float @llvm.floor.f32(
+; C89-SIMPLIFY: call float @llvm.ceil.f32(
 ; C89-SIMPLIFY: call double @round(
 ; C89-SIMPLIFY: call double @nearbyint(
 
-; DONT-SIMPLIFY: call double @floor(
-; DONT-SIMPLIFY: call double @ceil(
+; DONT-SIMPLIFY: call float @llvm.floor.f32(
+; DONT-SIMPLIFY: call float @llvm.ceil.f32(
 ; DONT-SIMPLIFY: call double @round(
 ; DONT-SIMPLIFY: call double @nearbyint(
 ; DONT-SIMPLIFY: call double @trunc(
index d9f4bc2dbb604e59fed417d3906e8afd1c117b6d..a98f4cd1cb422019d98c7c9ab3e539879e5564c2 100644 (file)
@@ -3,27 +3,51 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 target triple = "x86_64-apple-macosx10.8.0"
 
 define i32 @test1(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @ceil(double %1) nounwind readnone
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %ceil = call double @ceil(double %x.ext) nounwind readnone
+  %ext.y = fpext float %y to double
+  %cmp = fcmp oeq double %ceil, %ext.y
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT: %ceilf = call float @ceilf(float %x)
-; CHECK-NEXT: fcmp oeq float %ceilf, %y
+; CHECK-NEXT: %ceil = call float @llvm.ceil.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %ceil, %y
+}
+
+define i32 @test1_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %ceil = call double @llvm.ceil.f64(double %x.ext) nounwind readnone
+  %ext.y = fpext float %y to double
+  %cmp = fcmp oeq double %ceil, %ext.y
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test1_intrin(
+; CHECK-NEXT: %ceil = call float @llvm.ceil.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %ceil, %y
 }
 
 define i32 @test2(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @fabs(double %1) nounwind readnone
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %fabs = call double @fabs(double %x.ext) nounwind readnone
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %fabs, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT: [[FABS:%[0-9]+]] = call float @llvm.fabs.f32(float %x)
-; CHECK-NEXT: fcmp oeq float [[FABS]], %y
+; CHECK-NEXT: %fabs = call float @llvm.fabs.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %fabs, %y
+}
+
+define i32 @test2_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %fabs = call double @llvm.fabs.f64(double %x.ext) nounwind readnone
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %fabs, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test2_intrin(
+; CHECK-NEXT: %fabs = call float @llvm.fabs.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %fabs, %y
 }
 
 define i32 @fmf_test2(float %x, float %y) nounwind uwtable {
@@ -39,75 +63,136 @@ define i32 @fmf_test2(float %x, float %y) nounwind uwtable {
 }
 
 define i32 @test3(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @floor(double %1) nounwind readnone
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %floor = call double @floor(double %x.ext) nounwind readnone
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %floor, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT: %floorf = call float @floorf(float %x)
-; CHECK-NEXT: fcmp oeq float %floorf, %y
+; CHECK-NEXT: %floor = call float @llvm.floor.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %floor, %y
+}
+
+
+define i32 @test3_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %floor = call double @llvm.floor.f64(double %x.ext) nounwind readnone
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %floor, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test3_intrin(
+; CHECK-NEXT: %floor = call float @llvm.floor.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %floor, %y
 }
 
 define i32 @test4(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @nearbyint(double %1) nounwind
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %nearbyint = call double @nearbyint(double %x.ext) nounwind
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %nearbyint, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT: %nearbyintf = call float @nearbyintf(float %x)
-; CHECK-NEXT: fcmp oeq float %nearbyintf, %y
+; CHECK-NEXT: %nearbyint = call float @llvm.nearbyint.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %nearbyint, %y
+}
+
+define i32 @shrink_nearbyint_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %nearbyint = call double @llvm.nearbyint.f64(double %x.ext) nounwind
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %nearbyint, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @shrink_nearbyint_intrin(
+; CHECK-NEXT: %nearbyint = call float @llvm.nearbyint.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %nearbyint, %y
 }
 
 define i32 @test5(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @rint(double %1) nounwind
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %rint = call double @rint(double %x.ext) nounwind
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %rint, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test5(
-; CHECK-NEXT: %rintf = call float @rintf(float %x)
-; CHECK-NEXT: fcmp oeq float %rintf, %y
+; CHECK-NEXT: %rint = call float @llvm.nearbyint.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %rint, %y
 }
 
 define i32 @test6(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @round(double %1) nounwind readnone
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %round = call double @round(double %x.ext) nounwind readnone
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %round, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test6(
-; CHECK-NEXT: %roundf = call float @roundf(float %x)
-; CHECK-NEXT: fcmp oeq float %roundf, %y
+; CHECK-NEXT: %round = call float @llvm.round.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %round, %y
+}
+
+define i32 @test6_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %round = call double @llvm.round.f64(double %x.ext) nounwind readnone
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %round, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test6_intrin(
+; CHECK-NEXT: %round = call float @llvm.round.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %round, %y
 }
 
 define i32 @test7(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %x to double
-  %2 = call double @trunc(double %1) nounwind
-  %3 = fpext float %y to double
-  %4 = fcmp oeq double %2, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %trunc = call double @trunc(double %x.ext) nounwind
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %trunc, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test7(
-; CHECK-NEXT: %truncf = call float @truncf(float %x)
-; CHECK-NEXT: fcmp oeq float %truncf, %y
+; CHECK-NEXT: %trunc = call float @llvm.trunc.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %trunc, %y
+}
+
+define i32 @test7_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %trunc = call double @llvm.trunc.f64(double %x.ext) nounwind
+  %y.ext = fpext float %y to double
+  %cmp = fcmp oeq double %trunc, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test7_intrin(
+; CHECK-NEXT: %trunc = call float @llvm.trunc.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %trunc, %y
 }
 
 define i32 @test8(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %y to double
-  %2 = fpext float %x to double
-  %3 = call double @ceil(double %2) nounwind readnone
-  %4 = fcmp oeq double %1, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %ceil = call double @ceil(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %y.ext, %ceil
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test8(
-; CHECK-NEXT: %ceilf = call float @ceilf(float %x)
-; CHECK-NEXT: fcmp oeq float %ceilf, %y
+; CHECK-NEXT: %ceil = call float @llvm.ceil.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %ceil, %y
+}
+
+define i32 @test8_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %ceil = call double @llvm.ceil.f64(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %y.ext, %ceil
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test8_intrin(
+; CHECK-NEXT: %ceil = call float @llvm.ceil.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %ceil, %y
 }
 
 define i32 @test9(float %x, float %y) nounwind uwtable {
@@ -122,64 +207,125 @@ define i32 @test9(float %x, float %y) nounwind uwtable {
 ; CHECK-NEXT: fcmp oeq float %fabs, %y
 }
 
+define i32 @test9_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %fabs = call double @llvm.fabs.f64(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %y.ext, %fabs
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test9_intrin(
+; CHECK-NEXT: %fabs = call float @llvm.fabs.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %fabs, %y
+}
+
 define i32 @test10(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %y to double
-  %2 = fpext float %x to double
-  %3 = call double @floor(double %2) nounwind readnone
-  %4 = fcmp oeq double %1, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %floor = call double @floor(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %floor, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test10(
-; CHECK-NEXT: %floorf = call float @floorf(float %x)
-; CHECK-NEXT: fcmp oeq float %floorf, %y
+; CHECK-NEXT: %floor = call float @llvm.floor.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %floor, %y
+}
+
+define i32 @test10_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %floor = call double @llvm.floor.f64(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %floor, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test10_intrin(
+; CHECK-NEXT: %floor = call float @llvm.floor.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %floor, %y
 }
 
 define i32 @test11(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %y to double
-  %2 = fpext float %x to double
-  %3 = call double @nearbyint(double %2) nounwind
-  %4 = fcmp oeq double %1, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %nearbyint = call double @nearbyint(double %x.ext) nounwind
+  %cmp = fcmp oeq double %nearbyint, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test11(
-; CHECK-NEXT: %nearbyintf = call float @nearbyintf(float %x)
-; CHECK-NEXT: fcmp oeq float %nearbyintf, %y
+; CHECK-NEXT: %nearbyint = call float @llvm.nearbyint.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %nearbyint, %y
+}
+
+
+define i32 @test11_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %nearbyint = call double @llvm.nearbyint.f64(double %x.ext) nounwind
+  %cmp = fcmp oeq double %nearbyint, %y.ext
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test11_intrin(
+; CHECK-NEXT: %nearbyint = call float @llvm.nearbyint.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %nearbyint, %y
 }
 
 define i32 @test12(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %y to double
-  %2 = fpext float %x to double
-  %3 = call double @rint(double %2) nounwind
-  %4 = fcmp oeq double %1, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %rint = call double @rint(double %x.ext) nounwind
+  %cmp = fcmp oeq double %y.ext, %rint
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test12(
-; CHECK-NEXT: %rintf = call float @rintf(float %x)
-; CHECK-NEXT: fcmp oeq float %rintf, %y
+; CHECK-NEXT: %rint = call float @llvm.nearbyint.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %rint, %y
 }
 
 define i32 @test13(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %y to double
-  %2 = fpext float %x to double
-  %3 = call double @round(double %2) nounwind readnone
-  %4 = fcmp oeq double %1, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %round = call double @round(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %y.ext, %round
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test13(
-; CHECK-NEXT: %roundf = call float @roundf(float %x)
-; CHECK-NEXT: fcmp oeq float %roundf, %y
+; CHECK-NEXT: %round = call float @llvm.round.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %round, %y
+}
+
+define i32 @test13_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %round = call double @llvm.round.f64(double %x.ext) nounwind readnone
+  %cmp = fcmp oeq double %y.ext, %round
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test13_intrin(
+; CHECK-NEXT: %round = call float @llvm.round.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %round, %y
 }
 
 define i32 @test14(float %x, float %y) nounwind uwtable {
-  %1 = fpext float %y to double
-  %2 = fpext float %x to double
-  %3 = call double @trunc(double %2) nounwind
-  %4 = fcmp oeq double %1, %3
-  %5 = zext i1 %4 to i32
-  ret i32 %5
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %trunc = call double @trunc(double %x.ext) nounwind
+  %cmp = fcmp oeq double %y.ext, %trunc
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
 ; CHECK-LABEL: @test14(
-; CHECK-NEXT: %truncf = call float @truncf(float %x)
-; CHECK-NEXT: fcmp oeq float %truncf, %y
+; CHECK-NEXT: %trunc = call float @llvm.trunc.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %trunc, %y
+}
+
+define i32 @test14_intrin(float %x, float %y) nounwind uwtable {
+  %x.ext = fpext float %x to double
+  %y.ext = fpext float %y to double
+  %trunc = call double @llvm.trunc.f64(double %x.ext) nounwind
+  %cmp = fcmp oeq double %y.ext, %trunc
+  %cmp.ext = zext i1 %cmp to i32
+  ret i32 %cmp.ext
+; CHECK-LABEL: @test14_intrin(
+; CHECK-NEXT: %trunc = call float @llvm.trunc.f32(float %x)
+; CHECK-NEXT: fcmp oeq float %trunc, %y
 }
 
 define i32 @test15(float %x, float %y, float %z) nounwind uwtable {
@@ -281,3 +427,10 @@ declare double @round(double) nounwind readnone
 declare double @trunc(double) nounwind readnone
 declare double @fmin(double, double) nounwind readnone
 declare double @fmax(double, double) nounwind readnone
+
+declare double @llvm.fabs.f64(double) nounwind readnone
+declare double @llvm.ceil.f64(double) nounwind readnone
+declare double @llvm.floor.f64(double) nounwind readnone
+declare double @llvm.nearbyint.f64(double) nounwind readnone
+declare double @llvm.round.f64(double) nounwind readnone
+declare double @llvm.trunc.f64(double) nounwind readnone
index 5542a2a18381457a84431aef8358a2b99fb3a768..36947791393d9a4b5fa271db0a35978ec60a9b19 100644 (file)
@@ -56,15 +56,15 @@ declare double @ceil(double %x)
 define float @float_ceil(float %x) nounwind readnone {
 ; WIN32-LABEL: @float_ceil(
 ; WIN32-NOT: float @ceilf
-; WIN32: double @ceil
+; WIN32: float @llvm.ceil.f32
 ; WIN64-LABEL: @float_ceil(
-; WIN64: float @ceilf
+; WIN64: float @llvm.ceil.f32
 ; WIN64-NOT: double @ceil
 ; MINGW32-LABEL: @float_ceil(
-; MINGW32: float @ceilf
+; MINGW32: float @llvm.ceil.f32
 ; MINGW32-NOT: double @ceil
 ; MINGW64-LABEL: @float_ceil(
-; MINGW64: float @ceilf
+; MINGW64: float @llvm.ceil.f32
 ; MINGW64-NOT: double @ceil
     %1 = fpext float %x to double
     %2 = call double @ceil(double %1)
@@ -137,15 +137,15 @@ declare double @floor(double %x)
 define float @float_floor(float %x) nounwind readnone {
 ; WIN32-LABEL: @float_floor(
 ; WIN32-NOT: float @floorf
-; WIN32: double @floor
+; WIN32: float @llvm.floor.f32
 ; WIN64-LABEL: @float_floor(
-; WIN64: float @floorf
+; WIN64: float @llvm.floor.f32
 ; WIN64-NOT: double @floor
 ; MINGW32-LABEL: @float_floor(
-; MINGW32: float @floorf
+; MINGW32: float @llvm.floor.f32
 ; MINGW32-NOT: double @floor
 ; MINGW64-LABEL: @float_floor(
-; MINGW64: float @floorf
+; MINGW64: float @llvm.floor.f32
 ; MINGW64-NOT: double @floor
     %1 = fpext float %x to double
     %2 = call double @floor(double %1)
@@ -262,10 +262,10 @@ define float @float_round(float %x) nounwind readnone {
 ; WIN64-NOT: float @roundf
 ; WIN64: double @round
 ; MINGW32-LABEL: @float_round(
-; MINGW32: float @roundf
+; MINGW32: float @llvm.round.f32
 ; MINGW32-NOT: double @round
 ; MINGW64-LABEL: @float_round(
-; MINGW64: float @roundf
+; MINGW64: float @llvm.round.f32
 ; MINGW64-NOT: double @round
     %1 = fpext float %x to double
     %2 = call double @round(double %1)