mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
SimplifyLibCalls: Push TLI through the exp2->ldexp transform.
For the odd case of platforms with exp2 available but not ldexp. llvm-svn: 200795
This commit is contained in:
parent
9a2318e757
commit
700474a946
@ -352,6 +352,12 @@ namespace llvm {
|
||||
labs,
|
||||
/// int lchown(const char *path, uid_t owner, gid_t group);
|
||||
lchown,
|
||||
/// double ldexp(double x, int n);
|
||||
ldexp,
|
||||
/// float ldexpf(float x, int n);
|
||||
ldexpf,
|
||||
/// long double ldexpl(long double x, int n);
|
||||
ldexpl,
|
||||
/// long long int llabs(long long int j);
|
||||
llabs,
|
||||
/// double log(double x);
|
||||
|
@ -190,6 +190,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
|
||||
"isdigit",
|
||||
"labs",
|
||||
"lchown",
|
||||
"ldexp",
|
||||
"ldexpf",
|
||||
"ldexpl",
|
||||
"llabs",
|
||||
"log",
|
||||
"log10",
|
||||
@ -432,6 +435,8 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T,
|
||||
TLI.setUnavailable(LibFunc::fminl);
|
||||
TLI.setUnavailable(LibFunc::fmodl);
|
||||
TLI.setUnavailable(LibFunc::frexpl);
|
||||
TLI.setUnavailable(LibFunc::ldexpf);
|
||||
TLI.setUnavailable(LibFunc::ldexpl);
|
||||
TLI.setUnavailable(LibFunc::logl);
|
||||
TLI.setUnavailable(LibFunc::modfl);
|
||||
TLI.setUnavailable(LibFunc::powl);
|
||||
|
@ -1274,37 +1274,37 @@ struct Exp2Opt : public UnsafeFPLibCallOptimization {
|
||||
Value *Op = CI->getArgOperand(0);
|
||||
// Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32
|
||||
// Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32
|
||||
Value *LdExpArg = 0;
|
||||
if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
|
||||
if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
|
||||
LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty());
|
||||
} else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
|
||||
if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
|
||||
LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty());
|
||||
}
|
||||
LibFunc::Func LdExp = LibFunc::ldexpl;
|
||||
if (Op->getType()->isFloatTy())
|
||||
LdExp = LibFunc::ldexpf;
|
||||
else if (Op->getType()->isDoubleTy())
|
||||
LdExp = LibFunc::ldexp;
|
||||
|
||||
if (LdExpArg) {
|
||||
const char *Name;
|
||||
if (Op->getType()->isFloatTy())
|
||||
Name = "ldexpf";
|
||||
else if (Op->getType()->isDoubleTy())
|
||||
Name = "ldexp";
|
||||
else
|
||||
Name = "ldexpl";
|
||||
if (TLI->has(LdExp)) {
|
||||
Value *LdExpArg = 0;
|
||||
if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
|
||||
if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
|
||||
LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty());
|
||||
} else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
|
||||
if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
|
||||
LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty());
|
||||
}
|
||||
|
||||
Constant *One = ConstantFP::get(*Context, APFloat(1.0f));
|
||||
if (!Op->getType()->isFloatTy())
|
||||
One = ConstantExpr::getFPExtend(One, Op->getType());
|
||||
if (LdExpArg) {
|
||||
Constant *One = ConstantFP::get(*Context, APFloat(1.0f));
|
||||
if (!Op->getType()->isFloatTy())
|
||||
One = ConstantExpr::getFPExtend(One, Op->getType());
|
||||
|
||||
Module *M = Caller->getParent();
|
||||
Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
|
||||
Op->getType(),
|
||||
B.getInt32Ty(), NULL);
|
||||
CallInst *CI = B.CreateCall2(Callee, One, LdExpArg);
|
||||
if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
Module *M = Caller->getParent();
|
||||
Value *Callee =
|
||||
M->getOrInsertFunction(TLI->getName(LdExp), Op->getType(),
|
||||
Op->getType(), B.getInt32Ty(), NULL);
|
||||
CallInst *CI = B.CreateCall2(Callee, One, LdExpArg);
|
||||
if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
return CI;
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
; Test that the exp2 library call simplifier works correctly.
|
||||
;
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
; RUN: opt < %s -instcombine -S -mtriple=i386-pc-win32 | FileCheck %s -check-prefix=CHECK-WIN
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
|
||||
@ -74,3 +75,26 @@ define float @test_simplify8(i8 zeroext %x) {
|
||||
; CHECK: call float @ldexpf
|
||||
ret float %ret
|
||||
}
|
||||
|
||||
declare double @llvm.exp2.f64(double)
|
||||
declare float @llvm.exp2.f32(float)
|
||||
|
||||
define double @test_simplify9(i8 zeroext %x) {
|
||||
; CHECK-LABEL: @test_simplify9(
|
||||
; CHECK-WIN-LABEL: @test_simplify9(
|
||||
%conv = uitofp i8 %x to double
|
||||
%ret = call double @llvm.exp2.f64(double %conv)
|
||||
; CHECK: call double @ldexp
|
||||
; CHECK-WIN: call double @ldexp
|
||||
ret double %ret
|
||||
}
|
||||
|
||||
define float @test_simplify10(i8 zeroext %x) {
|
||||
; CHECK-LABEL: @test_simplify10(
|
||||
; CHECK-WIN-LABEL: @test_simplify10(
|
||||
%conv = uitofp i8 %x to float
|
||||
%ret = call float @llvm.exp2.f32(float %conv)
|
||||
; CHECK: call float @ldexpf
|
||||
; CHECK-WIN-NOT: call float @ldexpf
|
||||
ret float %ret
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user