forked from OSchip/llvm-project
SimplifyLibCalls: Replace more unary libcalls with intrinsics
llvm-svn: 292855
This commit is contained in:
parent
461aa57ad3
commit
954a624fb9
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue