26#define DEBUG_TYPE "amdgpu-simplifylib"
32 cl::desc(
"Enable pre-link mode optimizations"),
37 cl::desc(
"Comma separated list of functions to replace with native, or all"),
41#define MATH_PI numbers::pi
42#define MATH_E numbers::e
43#define MATH_SQRT2 numbers::sqrt2
44#define MATH_SQRT1_2 numbers::inv_sqrt2
55 bool AllNative =
false;
63 bool parseFunctionName(
const StringRef &FMangledName, FuncInfo &FInfo);
65 bool TDOFold(
CallInst *CI,
const FuncInfo &FInfo);
76 bool sincosUseNative(
CallInst *aCI,
const FuncInfo &FInfo);
79 bool evaluateScalarMathFunc(
const FuncInfo &FInfo,
double &Res0,
double &Res1,
81 bool evaluateCall(
CallInst *aCI,
const FuncInfo &FInfo);
85 std::tuple<Value *, Value *, Value *> insertSinCos(
Value *Arg,
95 const FuncInfo &FInfo);
102 bool shouldReplaceLibcallWithIntrinsic(
const CallInst *CI,
103 bool AllowMinSizeF32 =
false,
104 bool AllowF64 =
false,
105 bool AllowStrictFP =
false);
111 bool AllowMinSizeF32 =
false,
112 bool AllowF64 =
false,
113 bool AllowStrictFP =
false);
121 I->replaceAllUsesWith(With);
122 I->eraseFromParent();
142template <
typename IRB>
144 const Twine &Name =
"") {
145 CallInst *R =
B.CreateCall(Callee, Arg, Name);
147 R->setCallingConv(
F->getCallingConv());
151template <
typename IRB>
154 CallInst *R =
B.CreateCall(Callee, {Arg1, Arg2}, Name);
156 R->setCallingConv(
F->getCallingConv());
166 {FT->getParamType(0), PowNExpTy},
false);
404 : AMDGPULibFunc::getFunction(
M, fInfo);
407bool AMDGPULibCalls::parseFunctionName(
const StringRef &FMangledName,
428bool AMDGPULibCalls::useNativeFunc(
const StringRef F)
const {
433 AllNative = useNativeFunc(
"all") ||
438bool AMDGPULibCalls::sincosUseNative(
CallInst *aCI,
const FuncInfo &FInfo) {
439 bool native_sin = useNativeFunc(
"sin");
440 bool native_cos = useNativeFunc(
"cos");
442 if (native_sin && native_cos) {
457 if (sinExpr && cosExpr) {
465 <<
" with native version of sin/cos");
480 if (!parseFunctionName(Callee->getName(), FInfo) || !FInfo.
isMangled() ||
483 !(AllNative || useNativeFunc(FInfo.
getName()))) {
488 return sincosUseNative(aCI, FInfo);
497 <<
" with native version");
509 const FuncInfo &FInfo) {
511 if (!Callee->isDeclaration())
514 assert(Callee->hasName() &&
"Invalid read_pipe/write_pipe function");
515 auto *M = Callee->getParent();
516 std::string Name = std::string(Callee->getName());
518 if (NumArg != 4 && NumArg != 6)
524 if (!PacketSize || !PacketAlign)
529 if (Alignment !=
Size)
532 unsigned PtrArgLoc = CI->
arg_size() - 3;
537 for (
unsigned I = 0;
I != PtrArgLoc; ++
I)
541 Name = Name +
"_" + std::to_string(
Size);
550 for (
unsigned I = 0;
I != PtrArgLoc; ++
I)
552 Args.push_back(PtrArg);
554 auto *NCI =
B.CreateCall(
F, Args);
567 if (!Callee || Callee->isIntrinsic() || CI->
isNoBuiltin())
571 if (!parseFunctionName(Callee->getName(), FInfo))
581 if (TDOFold(CI, FInfo))
586 B.setIsFPConstrained(
true);
597 B.setFastMathFlags(FMF);
602 switch (FInfo.
getId()) {
606 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::exp,
611 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::exp2,
616 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::log,
621 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::log2,
626 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::log10,
629 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::minnum,
632 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::maxnum,
635 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::fma,
true,
638 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::fmuladd,
641 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::fabs,
true,
644 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::copysign,
647 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::floor,
true,
650 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::ceil,
true,
653 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::trunc,
true,
656 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::rint,
true,
659 return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::round,
true,
662 if (!shouldReplaceLibcallWithIntrinsic(CI,
true,
true))
668 Value *SplatArg1 =
B.CreateVectorSplat(VecTy->getElementCount(), Arg1);
674 {CI->getType(), CI->getArgOperand(1)->getType()}));
678 Module *M = Callee->getParent();
686 FPOp->getOperand(0), SQ.getWithInstruction(
Call))) {
687 Call->setCalledFunction(PowrFunc);
688 return fold_pow(FPOp,
B, PowrInfo) ||
true;
693 FPOp->getFastMathFlags())) {
702 B.CreateFPToSI(FPOp->getOperand(1), PownType->
getParamType(1));
704 Call->removeParamAttrs(
705 1, AttributeFuncs::typeIncompatible(CastedArg->
getType(),
706 Call->getParamAttributes(1)));
707 Call->setCalledFunction(PownFunc);
708 Call->setArgOperand(1, CastedArg);
709 return fold_pow(FPOp,
B, PownInfo) ||
true;
713 return fold_pow(FPOp,
B, FInfo);
717 return fold_pow(FPOp,
B, FInfo);
719 return fold_rootn(FPOp,
B, FInfo);
722 return tryReplaceLibcallWithSimpleIntrinsic(
723 B, CI, Intrinsic::sqrt,
true,
true,
false);
726 return fold_sincos(FPOp,
B, FInfo);
732 switch (FInfo.
getId()) {
737 return fold_read_write_pipe(CI,
B, FInfo);
746bool AMDGPULibCalls::TDOFold(
CallInst *CI,
const FuncInfo &FInfo) {
752 int const sz = (int)tr.
size();
758 for (
int eltNo = 0; eltNo <
getVecSize(FInfo); ++eltNo) {
760 CV->getElementAsConstant((
unsigned)eltNo));
761 assert(eltval &&
"Non-FP arguments in math function!");
763 for (
int i=0; i < sz; ++i) {
779 for (
double D : DVal)
787 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *nval <<
"\n");
794 for (
int i = 0; i < sz; ++i) {
795 if (CF->isExactlyValue(tr[i].input)) {
796 Value *nval = ConstantFP::get(CF->getType(), tr[i].result);
797 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *nval <<
"\n");
810#if _XOPEN_SOURCE >= 600 || defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L
819 const FuncInfo &FInfo) {
823 "fold_pow: encounter a wrong function call");
825 Module *
M =
B.GetInsertBlock()->getModule();
831 const APInt *CINT =
nullptr;
836 int ci_opr1 = (CINT ? (int)CINT->
getSExtValue() : 0x1111111);
838 if ((CF && CF->
isZero()) || (CINT && ci_opr1 == 0)) {
841 Constant *cnval = ConstantFP::get(eltType, 1.0);
850 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> " << *opr0 <<
"\n");
856 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> " << *opr0 <<
" * "
858 Value *nval =
B.CreateFMul(opr0, opr0,
"__pow2");
862 if ((CF && CF->
isExactlyValue(-1.0)) || (CINT && ci_opr1 == -1)) {
864 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> 1 / " << *opr0 <<
"\n");
865 Constant *cnval = ConstantFP::get(eltType, 1.0);
869 Value *nval =
B.CreateFDiv(cnval, opr0,
"__powrecip");
877 if (FunctionCallee FPExpr =
881 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> " << FInfo.getName()
882 <<
'(' << *opr0 <<
")\n");
900 int ival = (int)dval;
901 if ((
double)ival == dval) {
904 ci_opr1 = 0x11111111;
909 unsigned abs_opr1 = (ci_opr1 < 0) ? -ci_opr1 : ci_opr1;
910 if (abs_opr1 <= 12) {
914 cnval = ConstantFP::get(eltType, 1.0);
920 Value *valx2 =
nullptr;
922 while (abs_opr1 > 0) {
923 valx2 = valx2 ?
B.CreateFMul(valx2, valx2,
"__powx2") : opr0;
925 nval = nval ?
B.CreateFMul(nval, valx2,
"__powprod") : valx2;
932 cnval = ConstantFP::get(eltType, 1.0);
936 nval =
B.CreateFDiv(cnval, nval,
"__1powprod");
939 << ((ci_opr1 < 0) ?
"1/prod(" :
"prod(") << *opr0
950 FunctionCallee ExpExpr;
951 if (ShouldUseIntrinsic)
960 bool needlog =
false;
961 bool needabs =
false;
962 bool needcopysign =
false;
973 V =
log2(std::abs(V));
974 cnval = ConstantFP::get(eltType, V);
989 "Wrong vector size detected");
994 if (V < 0.0) needcopysign =
true;
995 V =
log2(std::abs(V));
1000 for (
double D : DVal)
1021 nval =
B.CreateUnaryIntrinsic(Intrinsic::fabs, opr0,
nullptr,
"__fabs");
1023 nval = cnval ? cnval : opr0;
1026 FunctionCallee LogExpr;
1027 if (ShouldUseIntrinsic) {
1041 opr1 =
B.CreateSIToFP(opr1, nval->
getType(),
"pownI2F");
1043 nval =
B.CreateFMul(opr1, nval,
"__ylogx");
1052 opr_n =
B.CreateZExtOrTrunc(opr_n, nTy,
"__ytou");
1054 opr_n =
B.CreateFPToSI(opr1, nTy,
"__ytou");
1056 Value *sign =
B.CreateShl(opr_n,
size-1,
"__yeven");
1057 sign =
B.CreateAnd(
B.CreateBitCast(opr0, nTy), sign,
"__pow_sign");
1058 nval =
B.CreateOr(
B.CreateBitCast(nval, nTy), sign);
1059 nval =
B.CreateBitCast(nval, opr0->
getType());
1063 <<
"exp2(" << *opr1 <<
" * log2(" << *opr0 <<
"))\n");
1070 const FuncInfo &FInfo) {
1074 const APInt *CINT =
nullptr;
1078 Function *Parent =
B.GetInsertBlock()->getParent();
1081 if (ci_opr1 == 1 && !Parent->
hasFnAttribute(Attribute::StrictFP)) {
1085 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> " << *opr0 <<
'\n');
1090 Module *
M =
B.GetInsertBlock()->getModule();
1094 shouldReplaceLibcallWithIntrinsic(CI,
1098 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> sqrt(" << *opr0 <<
")\n");
1100 CallInst *NewCall =
B.CreateUnaryIntrinsic(Intrinsic::sqrt, opr0, CI);
1105 MDBuilder MDHelper(
M->getContext());
1106 MDNode *FPMD = MDHelper.createFPMath(std::max(FPOp->
getFPAccuracy(), 2.0f));
1107 NewCall->
setMetadata(LLVMContext::MD_fpmath, FPMD);
1114 if (FunctionCallee FPExpr =
1116 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> cbrt(" << *opr0
1122 }
else if (ci_opr1 == -1) {
1123 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> 1.0 / " << *opr0 <<
"\n");
1124 Value *nval =
B.CreateFDiv(ConstantFP::get(opr0->
getType(), 1.0),
1131 if (ci_opr1 == -2 &&
1132 shouldReplaceLibcallWithIntrinsic(CI,
1139 MDBuilder MDHelper(
M->getContext());
1140 MDNode *FPMD = MDHelper.createFPMath(std::max(FPOp->
getFPAccuracy(), 2.0f));
1146 CallInst *Sqrt =
B.CreateUnaryIntrinsic(Intrinsic::sqrt, opr0, CI);
1148 B.CreateFDiv(ConstantFP::get(opr0->
getType(), 1.0), Sqrt));
1153 LLVM_DEBUG(
errs() <<
"AMDIC: " << *FPOp <<
" ---> rsqrt(" << *opr0
1164 const FuncInfo &FInfo) {
1167 FuncInfo nf = FInfo;
1169 return getFunction(M, nf);
1175bool AMDGPULibCalls::shouldReplaceLibcallWithIntrinsic(
const CallInst *CI,
1176 bool AllowMinSizeF32,
1178 bool AllowStrictFP) {
1193 if (!AllowStrictFP && ParentF->
hasFnAttribute(Attribute::StrictFP))
1196 if (IsF32 && !AllowMinSizeF32 && ParentF->
hasMinSize())
1201void AMDGPULibCalls::replaceLibCallWithSimpleIntrinsic(
IRBuilder<> &
B,
1209 if (Arg0VecTy && !Arg1VecTy) {
1210 Value *SplatRHS =
B.CreateVectorSplat(Arg0VecTy->getElementCount(), Arg1);
1212 }
else if (!Arg0VecTy && Arg1VecTy) {
1213 Value *SplatLHS =
B.CreateVectorSplat(Arg1VecTy->getElementCount(), Arg0);
1219 CI->
getModule(), IntrID, {CI->getType()}));
1222bool AMDGPULibCalls::tryReplaceLibcallWithSimpleIntrinsic(
1224 bool AllowF64,
bool AllowStrictFP) {
1225 if (!shouldReplaceLibcallWithIntrinsic(CI, AllowMinSizeF32, AllowF64,
1228 replaceLibCallWithSimpleIntrinsic(
B, CI, IntrID);
1232std::tuple<Value *, Value *, Value *>
1236 Function *
F =
B.GetInsertBlock()->getParent();
1237 B.SetInsertPointPastAllocas(
F);
1239 AllocaInst *
Alloc =
B.CreateAlloca(Arg->
getType(),
nullptr,
"__sincos_");
1246 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
1249 B.SetCurrentDebugLocation(
DL);
1257 Value *CastAlloc =
B.CreateAddrSpaceCast(
Alloc, CosPtrTy);
1265 return {SinCos, LoadCos, SinCos};
1270 const FuncInfo &fInfo) {
1289 Function *
F =
B.GetInsertBlock()->getParent();
1295 SinCosLibFuncPrivate.getLeads()[0].PtrKind =
1299 SinCosLibFuncGeneric.getLeads()[0].PtrKind =
1302 FunctionCallee FSinCosPrivate = getFunction(M, SinCosLibFuncPrivate);
1303 FunctionCallee FSinCosGeneric = getFunction(M, SinCosLibFuncGeneric);
1304 FunctionCallee FSinCos = FSinCosPrivate ? FSinCosPrivate : FSinCosGeneric;
1313 const std::string PairName = PartnerInfo.mangle();
1317 const std::string SinCosPrivateName = SinCosLibFuncPrivate.mangle();
1318 const std::string SinCosGenericName = SinCosLibFuncGeneric.mangle();
1322 MDNode *FPMath = CI->
getMetadata(LLVMContext::MD_fpmath);
1326 for (User* U : CArgVal->
users()) {
1335 bool Handled =
true;
1337 if (UCallee->
getName() == SinName)
1339 else if (UCallee->
getName() == CosName)
1341 else if (UCallee->
getName() == SinCosPrivateName ||
1342 UCallee->
getName() == SinCosGenericName)
1350 FMF &= OtherOp->getFastMathFlags();
1359 B.setFastMathFlags(FMF);
1360 B.setDefaultFPMathTag(FPMath);
1362 B.SetCurrentDebugLocation(DbgLoc);
1364 auto [Sin, Cos, SinCos] = insertSinCos(CArgVal, FMF,
B, FSinCos);
1367 for (CallInst *
C : Calls)
1368 C->replaceAllUsesWith(Res);
1373 replaceTrigInsts(SinCalls, Sin);
1374 replaceTrigInsts(CosCalls, Cos);
1375 replaceTrigInsts(SinCosCalls, SinCos);
1382bool AMDGPULibCalls::evaluateScalarMathFunc(
const FuncInfo &FInfo,
double &Res0,
1388 double opr0 = 0.0, opr1 = 0.0;
1403 switch (FInfo.getId()) {
1404 default :
return false;
1412 Res0 = log(opr0 + sqrt(opr0*opr0 - 1.0));
1425 Res0 = log(opr0 + sqrt(opr0*opr0 + 1.0));
1438 Res0 = (log(opr0 + 1.0) - log(opr0 - 1.0))/2.0;
1446 Res0 = (opr0 < 0.0) ? -
pow(-opr0, 1.0/3.0) :
pow(opr0, 1.0/3.0);
1466 Res0 =
pow(2.0, opr0);
1470 Res0 =
pow(10.0, opr0);
1478 Res0 = log(opr0) / log(2.0);
1482 Res0 = log(opr0) / log(10.0);
1486 Res0 = 1.0 / sqrt(opr0);
1516 Res0 =
pow(opr0, opr1);
1521 double val = (double)iopr1->getSExtValue();
1522 Res0 =
pow(opr0, val);
1530 double val = (double)iopr1->getSExtValue();
1531 Res0 =
pow(opr0, 1.0 / val);
1547bool AMDGPULibCalls::evaluateCall(
CallInst *aCI,
const FuncInfo &FInfo) {
1548 int numArgs = (int)aCI->
arg_size();
1569 double DVal0[16], DVal1[16];
1572 if (FuncVecSize == 1) {
1573 if (!evaluateScalarMathFunc(FInfo, DVal0[0], DVal1[0], copr0, copr1)) {
1579 for (
int i = 0; i < FuncVecSize; ++i) {
1582 if (!evaluateScalarMathFunc(FInfo, DVal0[i], DVal1[i], celt0, celt1)) {
1590 if (FuncVecSize == 1) {
1591 nval0 = ConstantFP::get(aCI->
getType(), DVal0[0]);
1593 nval1 = ConstantFP::get(aCI->
getType(), DVal1[0]);
1597 for (
int i = 0; i < FuncVecSize; ++i)
1601 if (hasTwoResults) {
1602 for (
int i = 0; i < FuncVecSize; ++i)
1610 if (hasTwoResults) {
1617 if (hasTwoResults) {
1620 "math function with ptr arg not supported yet");
1631 Simplifier.initNativeFuncs();
1636 F.printAsOperand(
dbgs(),
false,
F.getParent());
dbgs() <<
'\n';);
1638 for (
auto &BB :
F) {
1645 if (Simplifier.fold(CI))
1659 Simplifier.initNativeFuncs();
1662 for (
auto &BB :
F) {
1667 if (CI && Simplifier.useNative(CI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const TableEntry tbl_log[]
static const TableEntry tbl_tgamma[]
static AMDGPULibFunc::EType getArgType(const AMDGPULibFunc &FInfo)
static const TableEntry tbl_expm1[]
static const TableEntry tbl_asinpi[]
static const TableEntry tbl_cos[]
static const TableEntry tbl_exp10[]
static CallInst * CreateCallEx(IRB &B, FunctionCallee Callee, Value *Arg, const Twine &Name="")
static CallInst * CreateCallEx2(IRB &B, FunctionCallee Callee, Value *Arg1, Value *Arg2, const Twine &Name="")
static const TableEntry tbl_rsqrt[]
static const TableEntry tbl_atanh[]
static const TableEntry tbl_cosh[]
static const TableEntry tbl_asin[]
static const TableEntry tbl_sinh[]
static const TableEntry tbl_acos[]
static const TableEntry tbl_tan[]
static const TableEntry tbl_cospi[]
static const TableEntry tbl_tanpi[]
static cl::opt< bool > EnablePreLink("amdgpu-prelink", cl::desc("Enable pre-link mode optimizations"), cl::init(false), cl::Hidden)
static bool HasNative(AMDGPULibFunc::EFuncId id)
ArrayRef< TableEntry > TableRef
static int getVecSize(const AMDGPULibFunc &FInfo)
static const TableEntry tbl_sin[]
static const TableEntry tbl_atan[]
static const TableEntry tbl_log2[]
static const TableEntry tbl_acospi[]
static const TableEntry tbl_sqrt[]
static const TableEntry tbl_asinh[]
static TableRef getOptTable(AMDGPULibFunc::EFuncId id)
static const TableEntry tbl_acosh[]
static const TableEntry tbl_exp[]
static const TableEntry tbl_cbrt[]
static const TableEntry tbl_sinpi[]
static const TableEntry tbl_atanpi[]
static FunctionType * getPownType(FunctionType *FT)
static const TableEntry tbl_erf[]
static const TableEntry tbl_log10[]
static const TableEntry tbl_erfc[]
static cl::list< std::string > UseNative("amdgpu-use-native", cl::desc("Comma separated list of functions to replace with native, or all"), cl::CommaSeparated, cl::ValueOptional, cl::Hidden)
static const TableEntry tbl_tanh[]
static const TableEntry tbl_exp2[]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Machine Check Debug Module
FunctionAnalysisManager FAM
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
static void replaceCall(FPMathOperator *I, Value *With)
bool isUnsafeFiniteOnlyMath(const FPMathOperator *FPOp) const
bool canIncreasePrecisionOfConstantFold(const FPMathOperator *FPOp) const
static void replaceCall(Instruction *I, Value *With)
AMDGPULibCalls(Function &F, FunctionAnalysisManager &FAM)
bool useNative(CallInst *CI)
static unsigned getEPtrKindFromAddrSpace(unsigned AS)
Wrapper class for AMDGPULIbFuncImpl.
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr)
std::string getName() const
Get unmangled name for mangled library function and name for unmangled library function.
static FunctionCallee getOrInsertFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
void setPrefix(ENamePrefix PFX)
bool isCompatibleSignature(const Module &M, const FunctionType *FuncTy) const
Param * getLeads()
Get leading parameters for mangled lib functions.
ENamePrefix getPrefix() const
LLVM_ABI double convertToDouble() const
Converts this APFloat to host double value.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
LLVM_ABI float convertToFloat() const
Converts this APFloat to host float value.
int64_t getSExtValue() const
Get sign extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
A function analysis which provides an AssumptionCache.
InstListType::iterator iterator
Instruction iterators...
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
bool isNoInline() const
Return true if the call should not be inlined.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI APFloat getElementAsAPFloat(uint64_t i) const
If this is a sequential container of floating point type, return the specified element as an APFloat.
LLVM_ABI Constant * getElementAsConstant(uint64_t i) const
Return a Constant for a specified index's element.
LLVM_ABI uint64_t getNumElements() const
Return the number of elements in the array or vector.
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
static LLVM_ABI Constant * getSplat(unsigned NumElts, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
LLVM_ABI bool isExactlyValue(const APFloat &V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Align getAlignValue() const
Return the constant as an llvm::Align, interpreting 0 as Align(1).
This is an important base class in LLVM.
static LLVM_ABI DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)
Try to combine the vector of locations passed as input in a single one.
Analysis pass which computes a DominatorTree.
Utility class for floating point operations which can have information about relaxed accuracy require...
bool isFast() const
Test if this operation allows all non-strict floating-point transforms.
bool hasNoNaNs() const
Test if this operation's arguments and results are assumed not-NaN.
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
bool hasNoInfs() const
Test if this operation's arguments and results are assumed not-infinite.
bool hasApproxFunc() const
Test if this operation allows approximations of math library functions or intrinsics.
LLVM_ABI float getFPAccuracy() const
Get the maximum error permitted by this operation in ULPs.
Convenience struct for specifying and reasoning about fast-math flags.
void setAllowContract(bool B=true)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionType * getFunctionType()
Class to represent function types.
Type * getParamType(unsigned i) const
Parameter type accessors.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
static LLVM_ABI MDNode * getMostGenericFPMath(MDNode *A, MDNode *B)
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetLibraryInfo.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
LLVM_ABI Type * getWithNewType(Type *EltTy) const
Given vector type, change the element type, whilst keeping the old number of elements.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
void dropAllReferences()
Drop all references to operands.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
self_iterator getIterator()
@ FLAT_ADDRESS
Address space for flat memory.
@ PRIVATE_ADDRESS
Address space for private memory.
LLVM_ABI APInt pow(const APInt &X, int64_t N)
Compute X^N for N>=0.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
bool match(Val *V, const Pattern &P)
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static double log2(double V)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI bool isKnownIntegral(const Value *V, const SimplifyQuery &SQ, FastMathFlags FMF)
Return true if the floating-point value V is known to be an integer value.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool cannotBeOrderedLessThanZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if we can prove that the specified FP value is either NaN or never less than -0....
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This struct is a compact representation of a valid (non-zero power of two) alignment.