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 
   57  bool AllNative = 
false;
 
   65  bool parseFunctionName(
const StringRef &FMangledName, FuncInfo &FInfo);
 
   67  bool TDOFold(
CallInst *CI, 
const FuncInfo &FInfo);
 
   78  bool sincosUseNative(
CallInst *aCI, 
const FuncInfo &FInfo);
 
   81  bool evaluateScalarMathFunc(
const FuncInfo &FInfo, 
double &Res0, 
double &Res1,
 
   83  bool evaluateCall(
CallInst *aCI, 
const FuncInfo &FInfo);
 
   87  std::tuple<Value *, Value *, Value *> insertSinCos(
Value *Arg,
 
   97                            const FuncInfo &FInfo);
 
  104  bool shouldReplaceLibcallWithIntrinsic(
const CallInst *CI,
 
  105                                         bool AllowMinSizeF32 = 
false,
 
  106                                         bool AllowF64 = 
false,
 
  107                                         bool AllowStrictFP = 
false);
 
  113                                            bool AllowMinSizeF32 = 
false,
 
  114                                            bool AllowF64 = 
false,
 
  115                                            bool AllowStrictFP = 
false);
 
  123    I->replaceAllUsesWith(With);
 
  124    I->eraseFromParent();
 
 
 
  145template <
typename IRB>
 
  147                              const Twine &Name = 
"") {
 
  148  CallInst *R = 
B.CreateCall(Callee, Arg, Name);
 
  150    R->setCallingConv(
F->getCallingConv());
 
 
  154template <
typename IRB>
 
  157  CallInst *R = 
B.CreateCall(Callee, {Arg1, Arg2}, Name);
 
  159    R->setCallingConv(
F->getCallingConv());
 
 
  169                           {FT->getParamType(0), PowNExpTy}, 
false);
 
 
  407                       : AMDGPULibFunc::getFunction(
M, fInfo);
 
  410bool AMDGPULibCalls::parseFunctionName(
const StringRef &FMangledName,
 
  431bool AMDGPULibCalls::useNativeFunc(
const StringRef F)
 const {
 
  436  AllNative = useNativeFunc(
"all") ||
 
 
  441bool AMDGPULibCalls::sincosUseNative(
CallInst *aCI, 
const FuncInfo &FInfo) {
 
  442  bool native_sin = useNativeFunc(
"sin");
 
  443  bool native_cos = useNativeFunc(
"cos");
 
  445  if (native_sin && native_cos) {
 
  460    if (sinExpr && cosExpr) {
 
  468                                          << 
" with native version of sin/cos");
 
  483  if (!parseFunctionName(Callee->getName(), FInfo) || !FInfo.
isMangled() ||
 
  486      !(AllNative || useNativeFunc(FInfo.
getName()))) {
 
  491    return sincosUseNative(aCI, FInfo);
 
  500                                      << 
" with native version");
 
 
  512                                          const FuncInfo &FInfo) {
 
  514  if (!Callee->isDeclaration())
 
  517  assert(Callee->hasName() && 
"Invalid read_pipe/write_pipe function");
 
  518  auto *M = Callee->getParent();
 
  519  std::string Name = std::string(Callee->getName());
 
  521  if (NumArg != 4 && NumArg != 6)
 
  527  if (!PacketSize || !PacketAlign)
 
  532  if (Alignment != 
Size)
 
  535  unsigned PtrArgLoc = CI->
arg_size() - 3;
 
  540  for (
unsigned I = 0; 
I != PtrArgLoc; ++
I)
 
  544  Name = Name + 
"_" + std::to_string(
Size);
 
  553  for (
unsigned I = 0; 
I != PtrArgLoc; ++
I)
 
  555  Args.push_back(PtrArg);
 
  557  auto *NCI = 
B.CreateCall(
F, Args);
 
  574    return CF->getValueAPF().isInteger();
 
  579    unsigned NumElts = VFVTy->getNumElements();
 
  580    for (
unsigned i = 0; i != NumElts; ++i) {
 
  599  switch (
I->getOpcode()) {
 
  600  case Instruction::SIToFP:
 
  601  case Instruction::UIToFP:
 
  609  case Instruction::Call: {
 
  612    case Intrinsic::trunc:
 
  613    case Intrinsic::floor:
 
  614    case Intrinsic::ceil:
 
  615    case Intrinsic::rint:
 
  616    case Intrinsic::nearbyint:
 
  617    case Intrinsic::round:
 
  618    case Intrinsic::roundeven:
 
 
  638  if (!Callee || Callee->isIntrinsic() || CI->
isNoBuiltin())
 
  642  if (!parseFunctionName(Callee->getName(), FInfo))
 
  652  if (TDOFold(CI, FInfo))
 
  657    B.setIsFPConstrained(
true);
 
  668    B.setFastMathFlags(FMF);
 
  673    switch (FInfo.
getId()) {
 
  677      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::exp,
 
  682      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::exp2,
 
  687      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::log,
 
  692      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::log2,
 
  697      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::log10,
 
  700      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::minnum,
 
  703      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::maxnum,
 
  706      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::fma, 
true,
 
  709      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::fmuladd,
 
  712      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::fabs, 
true,
 
  715      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::copysign,
 
  718      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::floor, 
true,
 
  721      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::ceil, 
true,
 
  724      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::trunc, 
true,
 
  727      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::rint, 
true,
 
  730      return tryReplaceLibcallWithSimpleIntrinsic(
B, CI, Intrinsic::round, 
true,
 
  733      if (!shouldReplaceLibcallWithIntrinsic(CI, 
true, 
true))
 
  739        Value *SplatArg1 = 
B.CreateVectorSplat(VecTy->getElementCount(), Arg1);
 
  745          {CI->getType(), CI->getArgOperand(1)->getType()}));
 
  749      Module *M = Callee->getParent();
 
  760        Call->setCalledFunction(PowrFunc);
 
  761        return fold_pow(FPOp, 
B, PowrInfo) || 
true;
 
  766                          FPOp->getFastMathFlags())) {
 
  775              B.CreateFPToSI(FPOp->getOperand(1), PownType->
getParamType(1));
 
  777          Call->removeParamAttrs(
 
  778              1, AttributeFuncs::typeIncompatible(CastedArg->
getType(),
 
  779                                                  Call->getParamAttributes(1)));
 
  780          Call->setCalledFunction(PownFunc);
 
  781          Call->setArgOperand(1, CastedArg);
 
  782          return fold_pow(FPOp, 
B, PownInfo) || 
true;
 
  786      return fold_pow(FPOp, 
B, FInfo);
 
  790      return fold_pow(FPOp, 
B, FInfo);
 
  792      return fold_rootn(FPOp, 
B, FInfo);
 
  795      return tryReplaceLibcallWithSimpleIntrinsic(
 
  796          B, CI, Intrinsic::sqrt, 
true, 
true, 
false);
 
  799      return fold_sincos(FPOp, 
B, FInfo);
 
  805    switch (FInfo.
getId()) {
 
  810      return fold_read_write_pipe(CI, 
B, FInfo);
 
 
  819bool AMDGPULibCalls::TDOFold(
CallInst *CI, 
const FuncInfo &FInfo) {
 
  825  int const sz = (int)tr.
size();
 
  831      for (
int eltNo = 0; eltNo < 
getVecSize(FInfo); ++eltNo) {
 
  833                               CV->getElementAsConstant((
unsigned)eltNo));
 
  834        assert(eltval && 
"Non-FP arguments in math function!");
 
  836        for (
int i=0; i < sz; ++i) {
 
  848      LLVMContext &context = CI->
getParent()->getParent()->getContext();
 
  852        for (
double D : DVal)
 
  860      LLVM_DEBUG(
errs() << 
"AMDIC: " << *CI << 
" ---> " << *nval << 
"\n");
 
  867      for (
int i = 0; i < sz; ++i) {
 
  868        if (CF->isExactlyValue(tr[i].input)) {
 
  869          Value *nval = ConstantFP::get(CF->getType(), tr[i].result);
 
  870          LLVM_DEBUG(
errs() << 
"AMDIC: " << *CI << 
" ---> " << *nval << 
"\n");
 
  883#if _XOPEN_SOURCE >= 600 || defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L 
 
  892                              const FuncInfo &FInfo) {
 
  896         "fold_pow: encounter a wrong function call");
 
  898  Module *
M = 
B.GetInsertBlock()->getModule();
 
  904  const APInt *CINT = 
nullptr;
 
  909  int ci_opr1 = (CINT ? (int)CINT->
getSExtValue() : 0x1111111);
 
  911  if ((CF && CF->
isZero()) || (CINT && ci_opr1 == 0)) {
 
  914    Constant *cnval = ConstantFP::get(eltType, 1.0);
 
  923    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> " << *opr0 << 
"\n");
 
  929    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> " << *opr0 << 
" * " 
  931    Value *nval = 
B.CreateFMul(opr0, opr0, 
"__pow2");
 
  935  if ((CF && CF->
isExactlyValue(-1.0)) || (CINT && ci_opr1 == -1)) {
 
  937    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> 1 / " << *opr0 << 
"\n");
 
  938    Constant *cnval = ConstantFP::get(eltType, 1.0);
 
  942    Value *nval = 
B.CreateFDiv(cnval, opr0, 
"__powrecip");
 
  950    if (FunctionCallee FPExpr =
 
  954      LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> " << FInfo.getName()
 
  955                        << 
'(' << *opr0 << 
")\n");
 
  973    int ival = (int)dval;
 
  974    if ((
double)ival == dval) {
 
  977      ci_opr1 = 0x11111111;
 
  982  unsigned abs_opr1 = (ci_opr1 < 0) ? -ci_opr1 : ci_opr1;
 
  983  if (abs_opr1 <= 12) {
 
  987      cnval = ConstantFP::get(eltType, 1.0);
 
  993      Value *valx2 = 
nullptr;
 
  995      while (abs_opr1 > 0) {
 
  996        valx2 = valx2 ? 
B.CreateFMul(valx2, valx2, 
"__powx2") : opr0;
 
  998          nval = nval ? 
B.CreateFMul(nval, valx2, 
"__powprod") : valx2;
 
 1005      cnval = ConstantFP::get(eltType, 1.0);
 
 1009      nval = 
B.CreateFDiv(cnval, nval, 
"__1powprod");
 
 1012                      << ((ci_opr1 < 0) ? 
"1/prod(" : 
"prod(") << *opr0
 
 1023  FunctionCallee ExpExpr;
 
 1024  if (ShouldUseIntrinsic)
 
 1033  bool needlog = 
false;
 
 1034  bool needabs = 
false;
 
 1035  bool needcopysign = 
false;
 
 1046      V = 
log2(std::abs(V));
 
 1047      cnval = ConstantFP::get(eltType, V);
 
 1062              "Wrong vector size detected");
 
 1067        if (V < 0.0) needcopysign = 
true;
 
 1068        V = 
log2(std::abs(V));
 
 1073        for (
double D : DVal)
 
 1093    nval = 
B.CreateUnaryIntrinsic(Intrinsic::fabs, opr0, 
nullptr, 
"__fabs");
 
 1095    nval = cnval ? cnval : opr0;
 
 1098    FunctionCallee LogExpr;
 
 1099    if (ShouldUseIntrinsic) {
 
 1113    opr1 = 
B.CreateSIToFP(opr1, nval->
getType(), 
"pownI2F");
 
 1115  nval = 
B.CreateFMul(opr1, nval, 
"__ylogx");
 
 1124      opr_n = 
B.CreateZExtOrTrunc(opr_n, nTy, 
"__ytou");
 
 1126      opr_n = 
B.CreateFPToSI(opr1, nTy, 
"__ytou");
 
 1128    Value *sign = 
B.CreateShl(opr_n, 
size-1, 
"__yeven");
 
 1129    sign = 
B.CreateAnd(
B.CreateBitCast(opr0, nTy), sign, 
"__pow_sign");
 
 1130    nval = 
B.CreateOr(
B.CreateBitCast(nval, nTy), sign);
 
 1131    nval = 
B.CreateBitCast(nval, opr0->
getType());
 
 1135                    << 
"exp2(" << *opr1 << 
" * log2(" << *opr0 << 
"))\n");
 
 1142                                const FuncInfo &FInfo) {
 
 1146  const APInt *CINT = 
nullptr;
 
 1150  Function *Parent = 
B.GetInsertBlock()->getParent();
 
 1153  if (ci_opr1 == 1 && !Parent->
hasFnAttribute(Attribute::StrictFP)) {
 
 1157    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> " << *opr0 << 
'\n');
 
 1162  Module *
M = 
B.GetInsertBlock()->getModule();
 
 1166      shouldReplaceLibcallWithIntrinsic(CI,
 
 1170    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> sqrt(" << *opr0 << 
")\n");
 
 1172    CallInst *NewCall = 
B.CreateUnaryIntrinsic(Intrinsic::sqrt, opr0, CI);
 
 1177    MDBuilder MDHelper(
M->getContext());
 
 1178    MDNode *FPMD = MDHelper.createFPMath(std::max(FPOp->
getFPAccuracy(), 2.0f));
 
 1179    NewCall->
setMetadata(LLVMContext::MD_fpmath, FPMD);
 
 1186    if (FunctionCallee FPExpr =
 
 1188      LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> cbrt(" << *opr0
 
 1194  } 
else if (ci_opr1 == -1) { 
 
 1195    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> 1.0 / " << *opr0 << 
"\n");
 
 1196    Value *nval = 
B.CreateFDiv(ConstantFP::get(opr0->
getType(), 1.0),
 
 1203  if (ci_opr1 == -2 &&
 
 1204      shouldReplaceLibcallWithIntrinsic(CI,
 
 1211    MDBuilder MDHelper(
M->getContext());
 
 1212    MDNode *FPMD = MDHelper.createFPMath(std::max(FPOp->
getFPAccuracy(), 2.0f));
 
 1218    CallInst *Sqrt = 
B.CreateUnaryIntrinsic(Intrinsic::sqrt, opr0, CI);
 
 1220        B.CreateFDiv(ConstantFP::get(opr0->
getType(), 1.0), Sqrt));
 
 1225    LLVM_DEBUG(
errs() << 
"AMDIC: " << *FPOp << 
" ---> rsqrt(" << *opr0
 
 1236                                                 const FuncInfo &FInfo) {
 
 1239  FuncInfo nf = FInfo;
 
 1241  return getFunction(M, nf);
 
 1247bool AMDGPULibCalls::shouldReplaceLibcallWithIntrinsic(
const CallInst *CI,
 
 1248                                                       bool AllowMinSizeF32,
 
 1250                                                       bool AllowStrictFP) {
 
 1265  if (!AllowStrictFP && ParentF->
hasFnAttribute(Attribute::StrictFP))
 
 1268  if (IsF32 && !AllowMinSizeF32 && ParentF->
hasMinSize())
 
 1273void AMDGPULibCalls::replaceLibCallWithSimpleIntrinsic(
IRBuilder<> &
B,
 
 1281    if (Arg0VecTy && !Arg1VecTy) {
 
 1282      Value *SplatRHS = 
B.CreateVectorSplat(Arg0VecTy->getElementCount(), Arg1);
 
 1284    } 
else if (!Arg0VecTy && Arg1VecTy) {
 
 1285      Value *SplatLHS = 
B.CreateVectorSplat(Arg1VecTy->getElementCount(), Arg0);
 
 1291      CI->
getModule(), IntrID, {CI->getType()}));
 
 1294bool AMDGPULibCalls::tryReplaceLibcallWithSimpleIntrinsic(
 
 1296    bool AllowF64, 
bool AllowStrictFP) {
 
 1297  if (!shouldReplaceLibcallWithIntrinsic(CI, AllowMinSizeF32, AllowF64,
 
 1300  replaceLibCallWithSimpleIntrinsic(
B, CI, IntrID);
 
 1304std::tuple<Value *, Value *, Value *>
 
 1308  Function *
F = 
B.GetInsertBlock()->getParent();
 
 1309  B.SetInsertPointPastAllocas(
F);
 
 1311  AllocaInst *
Alloc = 
B.CreateAlloca(Arg->
getType(), 
nullptr, 
"__sincos_");
 
 1318    B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
 
 1321    B.SetCurrentDebugLocation(
DL);
 
 1329  Value *CastAlloc = 
B.CreateAddrSpaceCast(
Alloc, CosPtrTy);
 
 1336  LoadInst *LoadCos = 
B.CreateLoad(
Alloc->getAllocatedType(), 
Alloc);
 
 1337  return {SinCos, LoadCos, SinCos};
 
 1342                                 const FuncInfo &fInfo) {
 
 1361  Function *
F = 
B.GetInsertBlock()->getParent();
 
 1367  SinCosLibFuncPrivate.getLeads()[0].PtrKind =
 
 1371  SinCosLibFuncGeneric.getLeads()[0].PtrKind =
 
 1374  FunctionCallee FSinCosPrivate = getFunction(M, SinCosLibFuncPrivate);
 
 1375  FunctionCallee FSinCosGeneric = getFunction(M, SinCosLibFuncGeneric);
 
 1376  FunctionCallee FSinCos = FSinCosPrivate ? FSinCosPrivate : FSinCosGeneric;
 
 1385  const std::string PairName = PartnerInfo.mangle();
 
 1389  const std::string SinCosPrivateName = SinCosLibFuncPrivate.mangle();
 
 1390  const std::string SinCosGenericName = SinCosLibFuncGeneric.mangle();
 
 1394  MDNode *FPMath = CI->
getMetadata(LLVMContext::MD_fpmath);
 
 1398  for (User* U : CArgVal->
users()) {
 
 1407    bool Handled = 
true;
 
 1409    if (UCallee->
getName() == SinName)
 
 1411    else if (UCallee->
getName() == CosName)
 
 1413    else if (UCallee->
getName() == SinCosPrivateName ||
 
 1414             UCallee->
getName() == SinCosGenericName)
 
 1422      FMF &= OtherOp->getFastMathFlags();
 
 1431  B.setFastMathFlags(FMF);
 
 1432  B.setDefaultFPMathTag(FPMath);
 
 1434  B.SetCurrentDebugLocation(DbgLoc);
 
 1436  auto [Sin, Cos, SinCos] = insertSinCos(CArgVal, FMF, 
B, FSinCos);
 
 1439    for (CallInst *
C : Calls)
 
 1440      C->replaceAllUsesWith(Res);
 
 1445  replaceTrigInsts(SinCalls, Sin);
 
 1446  replaceTrigInsts(CosCalls, Cos);
 
 1447  replaceTrigInsts(SinCosCalls, SinCos);
 
 1454bool AMDGPULibCalls::evaluateScalarMathFunc(
const FuncInfo &FInfo, 
double &Res0,
 
 1460  double opr0 = 0.0, opr1 = 0.0;
 
 1475  switch (FInfo.getId()) {
 
 1476  default : 
return false;
 
 1484    Res0 = log(opr0 + sqrt(opr0*opr0 - 1.0));
 
 1497    Res0 = log(opr0 + sqrt(opr0*opr0 + 1.0));
 
 1510    Res0 = (log(opr0 + 1.0) - log(opr0 - 1.0))/2.0;
 
 1518    Res0 = (opr0 < 0.0) ? -
pow(-opr0, 1.0/3.0) : 
pow(opr0, 1.0/3.0);
 
 1538    Res0 = 
pow(2.0, opr0);
 
 1542    Res0 = 
pow(10.0, opr0);
 
 1550    Res0 = log(opr0) / log(2.0);
 
 1554    Res0 = log(opr0) / log(10.0);
 
 1558    Res0 = 1.0 / sqrt(opr0);
 
 1588    Res0 = 
pow(opr0, opr1);
 
 1593      double val = (double)iopr1->getSExtValue();
 
 1594      Res0 = 
pow(opr0, val);
 
 1602      double val = (double)iopr1->getSExtValue();
 
 1603      Res0 = 
pow(opr0, 1.0 / val);
 
 1619bool AMDGPULibCalls::evaluateCall(
CallInst *aCI, 
const FuncInfo &FInfo) {
 
 1620  int numArgs = (int)aCI->
arg_size();
 
 1641  double DVal0[16], DVal1[16];
 
 1644  if (FuncVecSize == 1) {
 
 1645    if (!evaluateScalarMathFunc(FInfo, DVal0[0], DVal1[0], copr0, copr1)) {
 
 1651    for (
int i = 0; i < FuncVecSize; ++i) {
 
 1654      if (!evaluateScalarMathFunc(FInfo, DVal0[i], DVal1[i], celt0, celt1)) {
 
 1662  if (FuncVecSize == 1) {
 
 1663    nval0 = ConstantFP::get(aCI->
getType(), DVal0[0]);
 
 1665      nval1 = ConstantFP::get(aCI->
getType(), DVal1[0]);
 
 1669      for (
int i = 0; i < FuncVecSize; ++i)
 
 1673      if (hasTwoResults) {
 
 1674        for (
int i = 0; i < FuncVecSize; ++i)
 
 1682      if (hasTwoResults) {
 
 1689  if (hasTwoResults) {
 
 1692           "math function with ptr arg not supported yet");
 
 1704  Simplifier.initFunction(
F, AM);
 
 1709             F.printAsOperand(
dbgs(), 
false, 
F.getParent()); 
dbgs() << 
'\n';);
 
 1711  for (
auto &BB : 
F) {
 
 1718        if (Simplifier.fold(CI))
 
 
 1733  Simplifier.initFunction(
F, AM);
 
 1736  for (
auto &BB : 
F) {
 
 1741      if (CI && Simplifier.useNative(CI))
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isKnownIntegral(const Value *V, const DataLayout &DL, FastMathFlags FMF)
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 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)
bool useNative(CallInst *CI)
void initFunction(Function &F, FunctionAnalysisManager &FAM)
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.
A cache of @llvm.assume calls within a function.
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
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
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 & getValue() const
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.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static LLVM_ABI DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)
Try to combine the vector of locations passed as input in a single one.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
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.
Provides information about what library functions are available for the current target.
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.
iterator_range< user_iterator > users()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
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.
const ParentTy * getParent() const
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.
LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
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 >
LLVM_ABI bool isKnownNeverInfOrNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point value can never contain a NaN or infinity.
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.
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.