99 {
"sinc", Intrinsic::not_intrinsic},
100 {
"sincn", Intrinsic::not_intrinsic},
101 {
"cos", Intrinsic::cos},
102 {
"sin", Intrinsic::sin},
103#if LLVM_VERSION_MAJOR >= 19
104 {
"tan", Intrinsic::tan},
105 {
"acos", Intrinsic::acos},
107 {
"tan", Intrinsic::not_intrinsic},
108 {
"acos", Intrinsic::not_intrinsic},
110 {
"__nv_frcp_rd", Intrinsic::not_intrinsic},
111 {
"__nv_frcp_rn", Intrinsic::not_intrinsic},
112 {
"__nv_frcp_ru", Intrinsic::not_intrinsic},
113 {
"__nv_frcp_rz", Intrinsic::not_intrinsic},
114 {
"__nv_drcp_rd", Intrinsic::not_intrinsic},
115 {
"__nv_drcp_rn", Intrinsic::not_intrinsic},
116 {
"__nv_drcp_ru", Intrinsic::not_intrinsic},
117 {
"__nv_drcp_rz", Intrinsic::not_intrinsic},
118#if LLVM_VERSION_MAJOR >= 19
119 {
"asin", Intrinsic::asin},
121 {
"asin", Intrinsic::not_intrinsic},
123 {
"__nv_asin", Intrinsic::not_intrinsic},
124#if LLVM_VERSION_MAJOR >= 19
125 {
"atan", Intrinsic::atan},
127 {
"atan", Intrinsic::not_intrinsic},
129 {
"atan2", Intrinsic::not_intrinsic},
130 {
"__nv_atan2", Intrinsic::not_intrinsic},
131#if LLVM_VERSION_MAJOR >= 19
132 {
"cosh", Intrinsic::cosh},
133 {
"sinh", Intrinsic::sinh},
134 {
"tanh", Intrinsic::tanh},
136 {
"cosh", Intrinsic::not_intrinsic},
137 {
"sinh", Intrinsic::not_intrinsic},
138 {
"tanh", Intrinsic::not_intrinsic},
140 {
"acosh", Intrinsic::not_intrinsic},
141 {
"asinh", Intrinsic::not_intrinsic},
142 {
"atanh", Intrinsic::not_intrinsic},
143 {
"exp", Intrinsic::exp},
144 {
"exp2", Intrinsic::exp2},
145#if LLVM_VERSION_MAJOR >= 18
146 {
"exp10", Intrinsic::exp10},
148 {
"exp10", Intrinsic::not_intrinsic},
150 {
"log", Intrinsic::log},
151 {
"log10", Intrinsic::log10},
152 {
"expm1", Intrinsic::not_intrinsic},
153 {
"log1p", Intrinsic::not_intrinsic},
154 {
"log2", Intrinsic::log2},
155 {
"logb", Intrinsic::not_intrinsic},
156 {
"pow", Intrinsic::pow},
157 {
"sqrt", Intrinsic::sqrt},
158 {
"cbrt", Intrinsic::not_intrinsic},
159 {
"hypot", Intrinsic::not_intrinsic},
161 {
"__mulsc3", Intrinsic::not_intrinsic},
162 {
"__muldc3", Intrinsic::not_intrinsic},
163 {
"__multc3", Intrinsic::not_intrinsic},
164 {
"__mulxc3", Intrinsic::not_intrinsic},
166 {
"__divsc3", Intrinsic::not_intrinsic},
167 {
"__divdc3", Intrinsic::not_intrinsic},
168 {
"__divtc3", Intrinsic::not_intrinsic},
169 {
"__divxc3", Intrinsic::not_intrinsic},
171 {
"Faddeeva_erf", Intrinsic::not_intrinsic},
172 {
"Faddeeva_erfc", Intrinsic::not_intrinsic},
173 {
"Faddeeva_erfcx", Intrinsic::not_intrinsic},
174 {
"Faddeeva_erfi", Intrinsic::not_intrinsic},
175 {
"Faddeeva_dawson", Intrinsic::not_intrinsic},
176 {
"Faddeeva_erf_re", Intrinsic::not_intrinsic},
177 {
"Faddeeva_erfc_re", Intrinsic::not_intrinsic},
178 {
"Faddeeva_erfcx_re", Intrinsic::not_intrinsic},
179 {
"Faddeeva_erfi_re", Intrinsic::not_intrinsic},
180 {
"Faddeeva_dawson_re", Intrinsic::not_intrinsic},
181 {
"erf", Intrinsic::not_intrinsic},
182 {
"erfi", Intrinsic::not_intrinsic},
183 {
"erfc", Intrinsic::not_intrinsic},
184 {
"erfinv", Intrinsic::not_intrinsic},
186 {
"__fd_sincos_1", Intrinsic::not_intrinsic},
187 {
"sincospi", Intrinsic::not_intrinsic},
188 {
"cmplx_inv", Intrinsic::not_intrinsic},
191 {
"j0", Intrinsic::not_intrinsic},
192 {
"j1", Intrinsic::not_intrinsic},
193 {
"jn", Intrinsic::not_intrinsic},
194 {
"y0", Intrinsic::not_intrinsic},
195 {
"y1", Intrinsic::not_intrinsic},
196 {
"yn", Intrinsic::not_intrinsic},
197 {
"tgamma", Intrinsic::not_intrinsic},
198 {
"lgamma", Intrinsic::not_intrinsic},
199 {
"logabsgamma", Intrinsic::not_intrinsic},
200 {
"ceil", Intrinsic::ceil},
201 {
"__nv_ceil", Intrinsic::ceil},
202 {
"floor", Intrinsic::floor},
203 {
"fmod", Intrinsic::not_intrinsic},
204 {
"trunc", Intrinsic::trunc},
205 {
"round", Intrinsic::round},
206 {
"rint", Intrinsic::rint},
207 {
"nearbyint", Intrinsic::nearbyint},
208 {
"remainder", Intrinsic::not_intrinsic},
209 {
"copysign", Intrinsic::copysign},
210 {
"nextafter", Intrinsic::not_intrinsic},
211 {
"nexttoward", Intrinsic::not_intrinsic},
212 {
"fdim", Intrinsic::not_intrinsic},
213 {
"fmax", Intrinsic::maxnum},
214 {
"fmin", Intrinsic::minnum},
215 {
"fabs", Intrinsic::fabs},
216 {
"fma", Intrinsic::fma},
217 {
"ilogb", Intrinsic::not_intrinsic},
218 {
"scalbn", Intrinsic::not_intrinsic},
219 {
"scalbln", Intrinsic::not_intrinsic},
220 {
"powi", Intrinsic::powi},
221 {
"cabs", Intrinsic::not_intrinsic},
222 {
"ldexp", Intrinsic::not_intrinsic},
223 {
"fmod", Intrinsic::not_intrinsic},
224 {
"finite", Intrinsic::not_intrinsic},
225 {
"isinf", Intrinsic::not_intrinsic},
226 {
"isnan", Intrinsic::not_intrinsic},
227 {
"lround", Intrinsic::lround},
228 {
"llround", Intrinsic::llround},
229 {
"lrint", Intrinsic::lrint},
230 {
"llrint", Intrinsic::llrint}};
380 std::map<Value *, std::set<int64_t>> &intseen,
381 ScalarEvolution &SE)
const {
382 if (
auto constant = dyn_cast<ConstantInt>(val)) {
383#if LLVM_VERSION_MAJOR > 14
384 if (constant->getValue().getSignificantBits() > 64)
387 if (constant->getValue().getMinSignedBits() > 64)
390 return {constant->getSExtValue()};
393 if (isa<ConstantPointerNull>(val)) {
399 if (
auto arg = dyn_cast<llvm::Argument>(val)) {
403 llvm::errs() <<
" KnownValues[" << *pair.first <<
"] - "
404 << pair.first->getParent()->getName() <<
"\n";
406 llvm::errs() <<
" arg: " << *arg <<
" - " << arg->getParent()->getName()
410 return found->second;
413 if (intseen.find(val) != intseen.end())
417 if (
auto ci = dyn_cast<CastInst>(val)) {
421 auto insert = [&](int64_t v) {
422 if (intseen[val].size() == 0) {
423 intseen[val].insert(v);
425 if (intseen[val].size() == 1) {
427 if (abs(*intseen[val].begin()) > abs(v)) {
428 intseen[val].clear();
429 intseen[val].insert(v);
437 intseen[val].insert(v);
444 intseen[val].insert(v);
449 if (
auto II = dyn_cast<IntrinsicInst>(val)) {
450 switch (II->getIntrinsicID()) {
451#if LLVM_VERSION_MAJOR >= 12
458 case Intrinsic::nvvm_read_ptx_sreg_tid_x:
459 case Intrinsic::nvvm_read_ptx_sreg_tid_y:
460 case Intrinsic::nvvm_read_ptx_sreg_tid_z:
461 case Intrinsic::nvvm_read_ptx_sreg_ctaid_x:
462 case Intrinsic::nvvm_read_ptx_sreg_ctaid_y:
463 case Intrinsic::nvvm_read_ptx_sreg_ctaid_z:
464 case Intrinsic::amdgcn_workitem_id_x:
465 case Intrinsic::amdgcn_workitem_id_y:
466 case Intrinsic::amdgcn_workitem_id_z:
473 if (
auto LI = dyn_cast<LoadInst>(val)) {
474 if (
auto AI = dyn_cast<AllocaInst>(LI->getPointerOperand())) {
475 StoreInst *SI =
nullptr;
477 for (
auto u : AI->users()) {
478 if (
auto SIu = dyn_cast<StoreInst>(u)) {
479 if (SI && SIu->getValueOperand() == AI) {
484 }
else if (!isa<LoadInst>(u)) {
485 if (!cast<Instruction>(u)->mayReadOrWriteMemory() &&
486 cast<Instruction>(u)->use_empty())
488 if (
auto CI = dyn_cast<CallBase>(u)) {
489 if (
auto F = CI->getCalledFunction()) {
490 auto funcName = F->getName();
491 if (funcName ==
"__kmpc_for_static_init_4" ||
492 funcName ==
"__kmpc_for_static_init_4u" ||
493 funcName ==
"__kmpc_for_static_init_8" ||
494 funcName ==
"__kmpc_for_static_init_8u") {
503 if (SI && !failed && DT.dominates(SI, LI)) {
511 if (
auto pn = dyn_cast<PHINode>(val)) {
512 if (SE.isSCEVable(pn->getType()))
513 if (
auto S = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(pn))) {
514 if (
auto StartC = dyn_cast<SCEVConstant>(S->getStart())) {
515 auto L = S->getLoop();
516 auto BE = SE.getBackedgeTakenCount(L);
517 if (BE != SE.getCouldNotCompute()) {
518 if (
auto Iters = dyn_cast<SCEVConstant>(BE)) {
519 uint64_t ival = Iters->getAPInt().getZExtValue();
525 bool rotated =
false;
526 BasicBlock *Latch = L->getLoopLatch();
527 rotated = Latch && L->isLoopExiting(Latch);
537 if (
auto StepC = dyn_cast<SCEVConstant>(S->getOperand(1))) {
538 APInt StartI = StartC->getAPInt();
539 APInt A = StepC->getAPInt();
548 ival = std::min(ival, (uint64_t)0);
562 ival = std::min(ival, (uint64_t)0);
565 ival = std::min(ival, (uint64_t)0);
569 for (uint64_t i = istart; i <= ival; i++) {
570 if (
auto Val = dyn_cast<SCEVConstant>(S->evaluateAtIteration(
571 SE.getConstant(Iters->getType(), i,
false),
573 if (Val->getAPInt().getSignificantBits() <= 64)
574 insert(Val->getAPInt().getSExtValue());
583 for (
unsigned i = 0; i < pn->getNumIncomingValues(); ++i) {
584 auto a = pn->getIncomingValue(i);
585 auto b = pn->getIncomingBlock(i);
588 if (pn->getParent() == b || DT.dominates(pn, b)) {
595 for (
auto pval : inset) {
596 if (pval < 20 && pval > -20) {
604 if (
auto bo = dyn_cast<BinaryOperator>(a)) {
605 if (bo->getOperand(0) == pn || bo->getOperand(1) == pn) {
606 if (bo->getOpcode() == BinaryOperator::Add ||
607 bo->getOpcode() == BinaryOperator::Sub) {
616 if (
auto bo = dyn_cast<BinaryOperator>(val)) {
619 if (bo->getOpcode() == BinaryOperator::Mul) {
621 if (inset0.size() == 1 || inset1.size() == 1) {
622 for (
auto val0 : inset0) {
623 for (
auto val1 : inset1) {
629 if (inset0.count(0) || inset1.count(0)) {
630 intseen[val].insert(0);
634 if (bo->getOpcode() == BinaryOperator::Add) {
635 if (inset0.size() == 1 || inset1.size() == 1) {
636 for (
auto val0 : inset0) {
637 for (
auto val1 : inset1) {
643 if (bo->getOpcode() == BinaryOperator::Sub) {
644 if (inset0.size() == 1 || inset1.size() == 1) {
645 for (
auto val0 : inset0) {
646 for (
auto val1 : inset1) {
653 if (bo->getOpcode() == BinaryOperator::SDiv) {
654 if (inset0.size() == 1 || inset1.size() == 1) {
655 for (
auto val0 : inset0) {
656 for (
auto val1 : inset1) {
663 if (bo->getOpcode() == BinaryOperator::Shl) {
664 if (inset0.size() == 1 || inset1.size() == 1) {
665 for (
auto val0 : inset0) {
666 for (
auto val1 : inset1) {
667 insert(val0 << val1);
675 if (bo->getOpcode() == BinaryOperator::AShr ||
676 bo->getOpcode() == BinaryOperator::LShr) {
677 if (inset0.size() == 1 || inset1.size() == 1) {
678 for (
auto val0 : inset0) {
679 for (
auto val1 : inset1) {
680 insert(val0 >> val1);
1435 for (Instruction &I : BB) {
1436 if (
auto MD = I.getMetadata(
"enzyme_type")) {
1439 auto RegSize = (DL.getTypeSizeInBits(I.getType()) + 7) / 8;
1444 if (CallBase *call = dyn_cast<CallBase>(&I)) {
1445#if LLVM_VERSION_MAJOR >= 14
1446 size_t num_args = call->arg_size();
1448 size_t num_args = call->getNumArgOperands();
1451 if (call->getAttributes().hasAttribute(AttributeList::ReturnIndex,
1453 auto attr = call->getAttributes().getAttribute(
1454 AttributeList::ReturnIndex,
"enzyme_type");
1458 auto RegSize = I.getType()->isVoidTy()
1460 : (DL.getTypeSizeInBits(I.getType()) + 7) / 8;
1464 for (
size_t i = 0; i < num_args; i++) {
1465 if (call->getAttributes().hasParamAttr(i,
"enzyme_type")) {
1466 auto attr = call->getAttributes().getParamAttr(i,
"enzyme_type");
1469 auto argTy = call->getArgOperand(i)->getType();
1470 auto RegSize = (DL.getTypeSizeInBits(argTy) + 7) / 8;
1476 Function *F = call->getCalledFunction();
1479 if (F->getAttributes().hasAttribute(AttributeList::ReturnIndex,
1481 auto attr = F->getAttributes().getAttribute(
1482 AttributeList::ReturnIndex,
"enzyme_type");
1485 auto RegSize = I.getType()->isVoidTy()
1487 : (DL.getTypeSizeInBits(I.getType()) + 7) / 8;
1491 size_t f_num_args = F->arg_size();
1492 for (
size_t i = 0; i < f_num_args; i++) {
1493 if (F->getAttributes().hasParamAttr(i,
"enzyme_type")) {
1494 auto attr = F->getAttributes().getParamAttr(i,
"enzyme_type");
1497 auto argTy = call->getArgOperand(i)->getType();
1498 auto RegSize = (DL.getTypeSizeInBits(argTy) + 7) / 8;
1500 call->getArgOperand(i));
1506 if (
auto castinst = dyn_cast<ConstantExpr>(call->getCalledOperand())) {
1507 if (castinst->isCast())
1508 if (
auto fn = dyn_cast<Function>(castinst->getOperand(0))) {
1512 if (F && F->getName().contains(
"__enzyme_float")) {
1513 assert(num_args == 1 || num_args == 2);
1514 assert(call->getArgOperand(0)->getType()->isPointerTy());
1517 if (num_args == 2) {
1518 assert(isa<ConstantInt>(call->getArgOperand(1)));
1519 auto CI = cast<ConstantInt>(call->getArgOperand(1));
1520 if (CI->isNegative())
1523 num = CI->getLimitedValue();
1526 TT.
insert({(int)num}, Type::getFloatTy(call->getContext()));
1528 for (
size_t i = 0; i < (size_t)num; i += 4)
1529 TT.
insert({(int)i}, Type::getFloatTy(call->getContext()));
1533 if (F && F->getName().contains(
"__enzyme_double")) {
1534 assert(num_args == 1 || num_args == 2);
1535 assert(call->getArgOperand(0)->getType()->isPointerTy());
1538 if (num_args == 2) {
1539 assert(isa<ConstantInt>(call->getArgOperand(1)));
1540 num = cast<ConstantInt>(call->getArgOperand(1))->getLimitedValue();
1542 for (
size_t i = 0; i < num; i += 8)
1543 TT.
insert({(int)i}, Type::getDoubleTy(call->getContext()));
1547 if (F && F->getName().contains(
"__enzyme_integer")) {
1548 assert(num_args == 1 || num_args == 2);
1549 assert(call->getArgOperand(0)->getType()->isPointerTy());
1551 if (num_args == 2) {
1552 assert(isa<ConstantInt>(call->getArgOperand(1)));
1553 num = cast<ConstantInt>(call->getArgOperand(1))->getLimitedValue();
1556 for (
size_t i = 0; i < num; i++)
1561 if (F && F->getName().contains(
"__enzyme_pointer")) {
1562 assert(num_args == 1 || num_args == 2);
1563 assert(call->getArgOperand(0)->getType()->isPointerTy());
1566 if (num_args == 2) {
1567 assert(isa<ConstantInt>(call->getArgOperand(1)));
1568 num = cast<ConstantInt>(call->getArgOperand(1))->getLimitedValue();
1570 for (
size_t i = 0; i < num;
1571 i += ((DL.getPointerSizeInBits() + 7) / 8))
1577 static const StringSet<> JuliaKnownTypes = {
1578 "julia.gc_alloc_obj",
1579 "jl_alloc_array_1d",
1580 "jl_alloc_array_2d",
1581 "jl_alloc_array_3d",
1582 "ijl_alloc_array_1d",
1583 "ijl_alloc_array_2d",
1584 "ijl_alloc_array_3d",
1585 "jl_gc_alloc_typed",
1586 "ijl_gc_alloc_typed",
1587 "jl_alloc_genericmemory",
1588 "ijl_alloc_genericmemory",
1589 "jl_alloc_genericmemory_unchecked",
1590 "ijl_alloc_genericmemory_unchecked",
1593 if (JuliaKnownTypes.count(F->getName())) {
1607 if (CallBase *call = dyn_cast<CallBase>(&I)) {
1608 if (call->getCalledFunction() &&
1609 (call->getCalledFunction()->getIntrinsicID() == Intrinsic::memcpy ||
1610 call->getCalledFunction()->getIntrinsicID() ==
1611 Intrinsic::memmove)) {
1612 int64_t copySize = 1;
1615 copySize =
max(copySize, val);
1626 }
else if (call->getCalledFunction() &&
1627 (call->getCalledFunction()->getIntrinsicID() ==
1628 Intrinsic::memset ||
1629 call->getCalledFunction()->getName() ==
1630 "memset_pattern16")) {
1631 int64_t copySize = 1;
1634 copySize =
max(copySize, val);
1644#if LLVM_VERSION_MAJOR >= 20
1645 }
else if (call->getCalledFunction() &&
1646 (call->getCalledFunction()->getIntrinsicID() ==
1647 Intrinsic::experimental_memset_pattern)) {
1648 int64_t copySize = 1;
1651 copySize =
max(copySize, val);
1662 }
else if (call->getCalledFunction() &&
1663 call->getCalledFunction()->getIntrinsicID() ==
1664 Intrinsic::masked_gather) {
1665 auto VT = cast<VectorType>(call->getType());
1666 auto LoadSize = (DL.getTypeSizeInBits(VT) + 7) / 8;
1670 }
else if (call->getCalledFunction() &&
1671 call->getCalledFunction()->getIntrinsicID() ==
1672 Intrinsic::masked_scatter) {
1674 }
else if (call->getCalledFunction() &&
1675 call->getCalledFunction()->getIntrinsicID() ==
1676 Intrinsic::masked_load) {
1677 auto VT = cast<VectorType>(call->getType());
1678 auto LoadSize = (DL.getTypeSizeInBits(VT) + 7) / 8;
1682 }
else if (call->getCalledFunction() &&
1683 call->getCalledFunction()->getIntrinsicID() ==
1684 Intrinsic::masked_store) {
1686 }
else if (call->getType()->isPointerTy()) {
1689 llvm::errs() <<
" unknown tbaa call instruction user inst: " << I
1690 <<
" vdptr: " << vdptr.
str() <<
"\n";
1692 }
else if (
auto SI = dyn_cast<StoreInst>(&I)) {
1694 (DL.getTypeSizeInBits(SI->getValueOperand()->getType()) + 7) / 8;
1707 }
else if (
auto LI = dyn_cast<LoadInst>(&I)) {
1708 auto LoadSize = (DL.getTypeSizeInBits(
LI->getType()) + 7) / 8;
1722 llvm::errs() <<
" inst: " << I <<
" vdptr: " << vdptr.
str() <<
"\n";
1723 assert(0 &&
"unknown tbaa instruction user");
1724 llvm_unreachable(
"unknown tbaa instruction user");
3135 llvm::Instruction::BinaryOps Opcode,
3138 Instruction *origin) {
3139 if (Opcode == BinaryOperator::FAdd || Opcode == BinaryOperator::FSub ||
3140 Opcode == BinaryOperator::FMul || Opcode == BinaryOperator::FDiv ||
3141 Opcode == BinaryOperator::FRem) {
3142 auto ty = T->getScalarType();
3143 assert(ty->isFloatingPointTy());
3146 bool LegalOr =
true;
3151 raw_string_ostream ss(
str);
3152 ss <<
"Illegal updateAnalysis prev:" << LHS.
str()
3153 <<
" new: " << Data.
str() <<
"\n";
3154 ss <<
"val: " << *
Args[0];
3155 ss <<
"origin: " << *origin;
3158 wrap(origin),
nullptr);
3163 raw_string_ostream ss(
str);
3164 ss <<
"Illegal updateAnalysis prev:" << RHS.
str()
3165 <<
" new: " << Data.
str() <<
"\n";
3166 ss <<
"val: " << *
Args[1];
3167 ss <<
"origin: " << *origin;
3170 wrap(origin),
nullptr);
3176 auto AnalysisLHS = LHS.
Data0();
3177 auto AnalysisRHS = RHS.
Data0();
3178 auto AnalysisRet = Ret.
Data0();
3181 case BinaryOperator::Sub:
3188 LHS |=
TypeTree(AnalysisRHS[{}]).PurgeAnything().
Only(-1,
nullptr);
3189 RHS |=
TypeTree(AnalysisLHS[{}]).PurgeAnything().
Only(-1,
nullptr);
3202 case BinaryOperator::Add:
3203 case BinaryOperator::Mul:
3213 case BinaryOperator::Xor:
3215 for (
int i = 0; i < 2; ++i) {
3217 if (!(FT = Ret.
allFloat(origin, dl)))
3223 ((i == 0) ? RHS : LHS)
3224 .checkedOrIn(
TypeTree(FT).Only(-1,
nullptr),
3229 raw_string_ostream ss(
str);
3235 ss <<
"Illegal updateBinop (xor up) Analysis " << *origin <<
"\n";
3236 ss <<
" (i=" << i <<
") " << (i == 0 ?
"RHS" :
"LHS") <<
" "
3237 << ((i == 0) ? RHS : LHS).str() <<
" FT from ret: " << *FT
3242 wrap(origin),
nullptr);
3244 EmitFailure(
"IllegalUpdateAnalysis", origin->getDebugLoc(),
3246 report_fatal_error(
"Performed illegal updateAnalysis");
3251 case BinaryOperator::Or:
3252 for (
int i = 0; i < 2; ++i) {
3254 if (!(FT = Ret.
allFloat(origin, dl)))
3257 bool validXor =
false;
3258 if (
auto CIT = dyn_cast_or_null<ConstantInt>(
Args[i])) {
3259 if (dl.getTypeSizeInBits(FT) != dl.getTypeSizeInBits(CIT->getType()))
3261 auto CI = CIT->getValue();
3262#if LLVM_VERSION_MAJOR > 16
3265 if (CI.isNullValue())
3272#
if LLVM_VERSION_MAJOR > 16
3273 && (CI & ~0b01111111100000000000000000000000ULL).isZero()
3275 && (CI & ~0b01111111100000000000000000000000ULL).isNullValue()
3279#
if LLVM_VERSION_MAJOR > 16
3282 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3287 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3293 }
else if (
auto CV = dyn_cast_or_null<ConstantVector>(
Args[i])) {
3295 if (dl.getTypeSizeInBits(FT) !=
3296 dl.getTypeSizeInBits(CV->getOperand(i)->getType()))
3298 for (
size_t i = 0, end = CV->getNumOperands(); i < end; ++i) {
3299 auto CI = dyn_cast<ConstantInt>(CV->getOperand(i))->getValue();
3301#if LLVM_VERSION_MAJOR > 16
3304 if (CI.isNullValue())
3310#
if LLVM_VERSION_MAJOR > 16
3311 && (CI & ~0b01111111100000000000000000000000ULL).isZero()
3313 && (CI & ~0b01111111100000000000000000000000ULL).isNullValue()
3317#
if LLVM_VERSION_MAJOR > 16
3320 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3325 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3332 }
else if (
auto CV = dyn_cast_or_null<ConstantDataVector>(
Args[i])) {
3334 if (dl.getTypeSizeInBits(FT) !=
3335 dl.getTypeSizeInBits(CV->getElementType()))
3337 for (
size_t i = 0, end = CV->getNumElements(); i < end; ++i) {
3338 auto CI = CV->getElementAsAPInt(i);
3339#if LLVM_VERSION_MAJOR > 16
3342 if (CI.isNullValue())
3348#
if LLVM_VERSION_MAJOR > 16
3349 && (CI & ~0b01111111100000000000000000000000ULL).isZero()
3351 && (CI & ~0b01111111100000000000000000000000ULL).isNullValue()
3355#
if LLVM_VERSION_MAJOR > 16
3358 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3363 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3372 ((i == 0) ? RHS : LHS) |=
TypeTree(FT).
Only(-1,
nullptr);
3383 Result.
binopIn(Legal, AnalysisRHS, Opcode);
3386 raw_string_ostream ss(
str);
3392 ss <<
"Illegal updateBinop Analysis " << *origin <<
"\n";
3393 ss <<
"Illegal binopIn(down): " << Opcode <<
" lhs: " << Result.
str()
3394 <<
" rhs: " << AnalysisRHS.str() <<
"\n";
3398 wrap(origin),
nullptr);
3400 EmitFailure(
"IllegalUpdateAnalysis", origin->getDebugLoc(), origin,
3402 report_fatal_error(
"Performed illegal updateAnalysis");
3404 if (Opcode == BinaryOperator::And) {
3405 for (
int i = 0; i < 2; ++i) {
3406 bool isNegMask =
false;
3408 if (
auto CI = dyn_cast<ConstantInt>(
Args[i])) {
3411 if (CI->getValue().getSignificantBits() <= 64) {
3412 int64_t andval = CI->getSExtValue();
3413 if (andval < 0 && andval >= -64) {
3414 Result = (i == 0 ? AnalysisRHS : AnalysisLHS);
3422 if (andval <= 16 && andval >= 0) {
3424 }
else if (andval < 0 && andval >= -64) {
3428 Result = (i == 0 ? AnalysisRHS : AnalysisLHS);
3436 if (!isNegMask &&
Args[i] && isa<ConstantInt>(
Args[i]) &&
3437 (i == 0 ? AnalysisRHS : AnalysisLHS).Inner0() ==
3442 }
else if (Opcode == BinaryOperator::Add ||
3443 Opcode == BinaryOperator::Sub) {
3444 for (
int i = 0; i < 2; ++i) {
3445 if (i == 1 || Opcode == BinaryOperator::Add)
3446 if (
auto CI = dyn_cast_or_null<ConstantInt>(
Args[i])) {
3447 if (CI->isNegative() || CI->isZero() ||
3448 CI->getLimitedValue() <= 4096) {
3452 Result = (i == 0 ? AnalysisRHS : AnalysisLHS);
3456 }
else if (Opcode == BinaryOperator::Mul) {
3457 for (
int i = 0; i < 2; ++i) {
3460 if (
Args[i] && isa<ConstantInt>(
Args[i]) &&
3465 }
else if (Opcode == BinaryOperator::URem) {
3466 if (
auto CI = dyn_cast_or_null<ConstantInt>(
Args[1])) {
3468 if (CI->getLimitedValue() <= 4096) {
3472 }
else if (Opcode == BinaryOperator::Xor) {
3473 for (
int i = 0; i < 2; ++i) {
3475 if (!(FT = (i == 0 ? RHS : LHS).allFloat(
Args[1 - i], dl)))
3483 }
else if (Opcode == BinaryOperator::Or) {
3484 for (
int i = 0; i < 2; ++i) {
3486 if (!(FT = (i == 0 ? RHS : LHS).allFloat(
Args[1 - i], dl)))
3489 bool validXor =
false;
3490 if (
auto CIT = dyn_cast_or_null<ConstantInt>(
Args[i])) {
3491 if (dl.getTypeSizeInBits(FT) !=
3492 dl.getTypeSizeInBits(CIT->getType()))
3494 auto CI = CIT->getValue();
3495#if LLVM_VERSION_MAJOR > 16
3498 if (CI.isNullValue())
3505#
if LLVM_VERSION_MAJOR > 16
3506 && (CI & ~0b01111111100000000000000000000000ULL).isZero()
3508 && (CI & ~0b01111111100000000000000000000000ULL).isNullValue()
3512#
if LLVM_VERSION_MAJOR > 16
3515 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3520 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3526 }
else if (
auto CV = dyn_cast_or_null<ConstantVector>(
Args[i])) {
3528 if (dl.getTypeSizeInBits(FT) !=
3529 dl.getTypeSizeInBits(CV->getOperand(i)->getType()))
3531 for (
size_t i = 0, end = CV->getNumOperands(); i < end; ++i) {
3532 auto CI = dyn_cast<ConstantInt>(CV->getOperand(i))->getValue();
3533#if LLVM_VERSION_MAJOR > 16
3536 if (CI.isNullValue())
3542#
if LLVM_VERSION_MAJOR > 16
3543 && (CI & ~0b01111111100000000000000000000000ULL).isZero()
3546 (CI & ~0b01111111100000000000000000000000ULL).isNullValue()
3550#
if LLVM_VERSION_MAJOR > 16
3553 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3558 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3565 }
else if (
auto CV = dyn_cast_or_null<ConstantDataVector>(
Args[i])) {
3567 if (dl.getTypeSizeInBits(FT) !=
3568 dl.getTypeSizeInBits(CV->getElementType()))
3570 for (
size_t i = 0, end = CV->getNumElements(); i < end; ++i) {
3571 auto CI = CV->getElementAsAPInt(i);
3572#if LLVM_VERSION_MAJOR > 16
3575 if (CI.isNullValue())
3581#
if LLVM_VERSION_MAJOR > 16
3582 && (CI & ~0b01111111100000000000000000000000ULL).isZero()
3585 (CI & ~0b01111111100000000000000000000000ULL).isNullValue()
3589#
if LLVM_VERSION_MAJOR > 16
3592 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3597 ~0b0111111111110000000000000000000000000000000000000000000000000000ULL)
3611 Ret = Result.
Only(-1,
nullptr);
3711 switch (I.getIntrinsicID()) {
3712 case Intrinsic::ctpop:
3713 case Intrinsic::ctlz:
3714 case Intrinsic::cttz:
3715 case Intrinsic::nvvm_read_ptx_sreg_tid_x:
3716 case Intrinsic::nvvm_read_ptx_sreg_tid_y:
3717 case Intrinsic::nvvm_read_ptx_sreg_tid_z:
3718 case Intrinsic::nvvm_read_ptx_sreg_ntid_x:
3719 case Intrinsic::nvvm_read_ptx_sreg_ntid_y:
3720 case Intrinsic::nvvm_read_ptx_sreg_ntid_z:
3721 case Intrinsic::nvvm_read_ptx_sreg_ctaid_x:
3722 case Intrinsic::nvvm_read_ptx_sreg_ctaid_y:
3723 case Intrinsic::nvvm_read_ptx_sreg_ctaid_z:
3724 case Intrinsic::nvvm_read_ptx_sreg_nctaid_x:
3725 case Intrinsic::nvvm_read_ptx_sreg_nctaid_y:
3726 case Intrinsic::nvvm_read_ptx_sreg_nctaid_z:
3727 case Intrinsic::nvvm_read_ptx_sreg_warpsize:
3728 case Intrinsic::amdgcn_workitem_id_x:
3729 case Intrinsic::amdgcn_workitem_id_y:
3730 case Intrinsic::amdgcn_workitem_id_z:
3735#if LLVM_VERSION_MAJOR < 22
3736 case Intrinsic::nvvm_barrier0_popc:
3737 case Intrinsic::nvvm_barrier0_and:
3738 case Intrinsic::nvvm_barrier0_or:
3740 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
3741 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
3742 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
3743 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
3744 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
3745 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
3753 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f32_col:
3754 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f32_col_stride:
3755 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f32_row:
3756 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f32_row_stride:
3757 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f32_col:
3758 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f32_col_stride:
3759 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f32_row:
3760 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f32_row_stride:
3761 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f32_col:
3762 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f32_col_stride:
3763 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f32_row:
3764 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f32_row_stride: {
3767 TT.
insert({-1, 0}, Type::getFloatTy(I.getContext()));
3769 for (
int i = 1; i <= 9; i++)
3777 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f16_col:
3778 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f16_col_stride:
3779 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f16_row:
3780 case Intrinsic::nvvm_wmma_m16n16k16_store_d_f16_row_stride:
3781 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f16_col:
3782 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f16_col_stride:
3783 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f16_row:
3784 case Intrinsic::nvvm_wmma_m32n8k16_store_d_f16_row_stride:
3785 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f16_col:
3786 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f16_col_stride:
3787 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f16_row:
3788 case Intrinsic::nvvm_wmma_m8n32k16_store_d_f16_row_stride: {
3791 TT.
insert({-1, 0}, Type::getHalfTy(I.getContext()));
3793 for (
int i = 1; i <= 9; i++)
3801 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f32_col:
3802 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f32_col_stride:
3803 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f32_row:
3804 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f32_row_stride:
3805 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f32_col:
3806 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f32_col_stride:
3807 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f32_row:
3808 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f32_row_stride:
3809 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f32_col:
3810 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f32_col_stride:
3811 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f32_row:
3812 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f32_row_stride: {
3815 TT.
insert({-1, 0}, Type::getFloatTy(I.getContext()));
3824 case Intrinsic::nvvm_wmma_m16n16k16_load_a_f16_col:
3825 case Intrinsic::nvvm_wmma_m16n16k16_load_a_f16_col_stride:
3826 case Intrinsic::nvvm_wmma_m16n16k16_load_a_f16_row:
3827 case Intrinsic::nvvm_wmma_m16n16k16_load_a_f16_row_stride:
3828 case Intrinsic::nvvm_wmma_m16n16k16_load_b_f16_col:
3829 case Intrinsic::nvvm_wmma_m16n16k16_load_b_f16_col_stride:
3830 case Intrinsic::nvvm_wmma_m16n16k16_load_b_f16_row:
3831 case Intrinsic::nvvm_wmma_m16n16k16_load_b_f16_row_stride:
3832 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f16_col:
3833 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f16_col_stride:
3834 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f16_row:
3835 case Intrinsic::nvvm_wmma_m16n16k16_load_c_f16_row_stride:
3836 case Intrinsic::nvvm_wmma_m32n8k16_load_a_f16_col:
3837 case Intrinsic::nvvm_wmma_m32n8k16_load_a_f16_col_stride:
3838 case Intrinsic::nvvm_wmma_m32n8k16_load_a_f16_row:
3839 case Intrinsic::nvvm_wmma_m32n8k16_load_a_f16_row_stride:
3840 case Intrinsic::nvvm_wmma_m32n8k16_load_b_f16_col:
3841 case Intrinsic::nvvm_wmma_m32n8k16_load_b_f16_col_stride:
3842 case Intrinsic::nvvm_wmma_m32n8k16_load_b_f16_row:
3843 case Intrinsic::nvvm_wmma_m32n8k16_load_b_f16_row_stride:
3844 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f16_col:
3845 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f16_col_stride:
3846 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f16_row:
3847 case Intrinsic::nvvm_wmma_m32n8k16_load_c_f16_row_stride:
3848 case Intrinsic::nvvm_wmma_m8n32k16_load_a_f16_col:
3849 case Intrinsic::nvvm_wmma_m8n32k16_load_a_f16_col_stride:
3850 case Intrinsic::nvvm_wmma_m8n32k16_load_a_f16_row:
3851 case Intrinsic::nvvm_wmma_m8n32k16_load_a_f16_row_stride:
3852 case Intrinsic::nvvm_wmma_m8n32k16_load_b_f16_col:
3853 case Intrinsic::nvvm_wmma_m8n32k16_load_b_f16_col_stride:
3854 case Intrinsic::nvvm_wmma_m8n32k16_load_b_f16_row:
3855 case Intrinsic::nvvm_wmma_m8n32k16_load_b_f16_row_stride:
3856 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f16_col:
3857 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f16_col_stride:
3858 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f16_row:
3859 case Intrinsic::nvvm_wmma_m8n32k16_load_c_f16_row_stride: {
3862 TT.
insert({-1, 0}, Type::getHalfTy(I.getContext()));
3871 case Intrinsic::nvvm_wmma_m16n16k16_load_c_s32_col:
3872 case Intrinsic::nvvm_wmma_m16n16k16_load_c_s32_col_stride:
3873 case Intrinsic::nvvm_wmma_m16n16k16_load_a_s8_col:
3874 case Intrinsic::nvvm_wmma_m16n16k16_load_a_s8_col_stride:
3875 case Intrinsic::nvvm_wmma_m16n16k16_load_a_u8_col_stride:
3876 case Intrinsic::nvvm_wmma_m16n16k16_load_a_u8_col:
3877 case Intrinsic::nvvm_wmma_m16n16k16_load_a_s8_row:
3878 case Intrinsic::nvvm_wmma_m16n16k16_load_a_s8_row_stride:
3879 case Intrinsic::nvvm_wmma_m16n16k16_load_a_u8_row_stride:
3880 case Intrinsic::nvvm_wmma_m16n16k16_load_a_u8_row:
3881 case Intrinsic::nvvm_wmma_m16n16k16_load_b_s8_col:
3882 case Intrinsic::nvvm_wmma_m16n16k16_load_b_s8_col_stride:
3883 case Intrinsic::nvvm_wmma_m16n16k16_load_b_u8_col_stride:
3884 case Intrinsic::nvvm_wmma_m16n16k16_load_b_u8_col:
3885 case Intrinsic::nvvm_wmma_m16n16k16_load_b_s8_row:
3886 case Intrinsic::nvvm_wmma_m16n16k16_load_b_s8_row_stride:
3887 case Intrinsic::nvvm_wmma_m16n16k16_load_b_u8_row_stride:
3888 case Intrinsic::nvvm_wmma_m16n16k16_load_b_u8_row:
3889 case Intrinsic::nvvm_wmma_m16n16k16_load_c_s32_row:
3890 case Intrinsic::nvvm_wmma_m16n16k16_load_c_s32_row_stride:
3891 case Intrinsic::nvvm_wmma_m32n8k16_load_a_s8_col:
3892 case Intrinsic::nvvm_wmma_m32n8k16_load_a_s8_col_stride:
3893 case Intrinsic::nvvm_wmma_m32n8k16_load_a_u8_col_stride:
3894 case Intrinsic::nvvm_wmma_m32n8k16_load_a_u8_col:
3895 case Intrinsic::nvvm_wmma_m32n8k16_load_a_s8_row:
3896 case Intrinsic::nvvm_wmma_m32n8k16_load_a_s8_row_stride:
3897 case Intrinsic::nvvm_wmma_m32n8k16_load_a_u8_row_stride:
3898 case Intrinsic::nvvm_wmma_m32n8k16_load_a_u8_row:
3899 case Intrinsic::nvvm_wmma_m32n8k16_load_b_s8_col:
3900 case Intrinsic::nvvm_wmma_m32n8k16_load_b_s8_col_stride:
3901 case Intrinsic::nvvm_wmma_m32n8k16_load_b_u8_col_stride:
3902 case Intrinsic::nvvm_wmma_m32n8k16_load_b_u8_col:
3903 case Intrinsic::nvvm_wmma_m32n8k16_load_b_s8_row:
3904 case Intrinsic::nvvm_wmma_m32n8k16_load_b_s8_row_stride:
3905 case Intrinsic::nvvm_wmma_m32n8k16_load_b_u8_row_stride:
3906 case Intrinsic::nvvm_wmma_m32n8k16_load_b_u8_row:
3907 case Intrinsic::nvvm_wmma_m32n8k16_load_c_s32_col:
3908 case Intrinsic::nvvm_wmma_m32n8k16_load_c_s32_col_stride:
3909 case Intrinsic::nvvm_wmma_m32n8k16_load_c_s32_row:
3910 case Intrinsic::nvvm_wmma_m32n8k16_load_c_s32_row_stride:
3911 case Intrinsic::nvvm_wmma_m8n32k16_load_a_s8_col:
3912 case Intrinsic::nvvm_wmma_m8n32k16_load_a_s8_col_stride:
3913 case Intrinsic::nvvm_wmma_m8n32k16_load_a_u8_col_stride:
3914 case Intrinsic::nvvm_wmma_m8n32k16_load_a_u8_col:
3915 case Intrinsic::nvvm_wmma_m8n32k16_load_a_s8_row:
3916 case Intrinsic::nvvm_wmma_m8n32k16_load_a_s8_row_stride:
3917 case Intrinsic::nvvm_wmma_m8n32k16_load_a_u8_row_stride:
3918 case Intrinsic::nvvm_wmma_m8n32k16_load_a_u8_row:
3919 case Intrinsic::nvvm_wmma_m8n32k16_load_b_s8_col:
3920 case Intrinsic::nvvm_wmma_m8n32k16_load_b_s8_col_stride:
3921 case Intrinsic::nvvm_wmma_m8n32k16_load_b_u8_col_stride:
3922 case Intrinsic::nvvm_wmma_m8n32k16_load_b_u8_col:
3923 case Intrinsic::nvvm_wmma_m8n32k16_load_b_s8_row:
3924 case Intrinsic::nvvm_wmma_m8n32k16_load_b_s8_row_stride:
3925 case Intrinsic::nvvm_wmma_m8n32k16_load_b_u8_row_stride:
3926 case Intrinsic::nvvm_wmma_m8n32k16_load_b_u8_row:
3927 case Intrinsic::nvvm_wmma_m8n32k16_load_c_s32_col:
3928 case Intrinsic::nvvm_wmma_m8n32k16_load_c_s32_col_stride:
3929 case Intrinsic::nvvm_wmma_m8n32k16_load_c_s32_row:
3930 case Intrinsic::nvvm_wmma_m8n32k16_load_c_s32_row_stride:
3931 case Intrinsic::nvvm_wmma_m8n8k128_load_a_b1_row:
3932 case Intrinsic::nvvm_wmma_m8n8k128_load_a_b1_row_stride:
3933 case Intrinsic::nvvm_wmma_m8n8k128_load_b_b1_col:
3934 case Intrinsic::nvvm_wmma_m8n8k128_load_b_b1_col_stride:
3935 case Intrinsic::nvvm_wmma_m8n8k128_load_c_s32_col:
3936 case Intrinsic::nvvm_wmma_m8n8k128_load_c_s32_col_stride:
3937 case Intrinsic::nvvm_wmma_m8n8k128_load_c_s32_row:
3938 case Intrinsic::nvvm_wmma_m8n8k128_load_c_s32_row_stride:
3939 case Intrinsic::nvvm_wmma_m8n8k32_load_a_s4_row:
3940 case Intrinsic::nvvm_wmma_m8n8k32_load_a_s4_row_stride:
3941 case Intrinsic::nvvm_wmma_m8n8k32_load_a_u4_row_stride:
3942 case Intrinsic::nvvm_wmma_m8n8k32_load_a_u4_row:
3943 case Intrinsic::nvvm_wmma_m8n8k32_load_b_s4_col:
3944 case Intrinsic::nvvm_wmma_m8n8k32_load_b_s4_col_stride:
3945 case Intrinsic::nvvm_wmma_m8n8k32_load_b_u4_col_stride:
3946 case Intrinsic::nvvm_wmma_m8n8k32_load_b_u4_col:
3947 case Intrinsic::nvvm_wmma_m8n8k32_load_c_s32_col:
3948 case Intrinsic::nvvm_wmma_m8n8k32_load_c_s32_col_stride:
3949 case Intrinsic::nvvm_wmma_m8n8k32_load_c_s32_row:
3950 case Intrinsic::nvvm_wmma_m8n8k32_load_c_s32_row_stride: {
3955 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_col_f16_f16:
3956 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_row_f16_f16:
3957 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_col_f16_f16:
3958 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_row_f16_f16:
3959 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_col_f16_f16:
3960 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_row_f16_f16:
3961 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_col_f16_f16:
3962 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_row_f16_f16:
3963 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_col_f16_f16:
3964 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_row_f16_f16:
3965 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_col_f16_f16:
3966 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_row_f16_f16: {
3967 for (
int i = 0; i < 16; i++)
3972 for (
int i = 16; i < 16 + 8; i++)
3984 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_col_f16_f32:
3985 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_row_f16_f32:
3986 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_col_f16_f32:
3987 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_row_f16_f32:
3988 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_col_f16_f32:
3989 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_row_f16_f32:
3990 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_col_f16_f32:
3991 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_row_f16_f32:
3992 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_col_f16_f32:
3993 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_row_f16_f32:
3994 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_col_f16_f32:
3995 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_row_f16_f32: {
3996 for (
int i = 0; i < 16; i++)
4001 for (
int i = 16; i < 16 + 8; i++)
4013 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_col_f32_f16:
4014 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_row_f32_f16:
4015 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_col_f32_f16:
4016 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_row_f32_f16:
4017 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_col_f32_f16:
4018 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_row_f32_f16:
4019 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_col_f32_f16:
4020 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_row_f32_f16:
4021 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_col_f32_f16:
4022 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_row_f32_f16:
4023 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_col_f32_f16:
4024 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_row_f32_f16: {
4025 for (
int i = 0; i < 16; i++)
4030 for (
int i = 16; i < 16 + 8; i++)
4042 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_col_f32_f32:
4043 case Intrinsic::nvvm_wmma_m16n16k16_mma_col_row_f32_f32:
4044 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_col_f32_f32:
4045 case Intrinsic::nvvm_wmma_m16n16k16_mma_row_row_f32_f32:
4046 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_col_f32_f32:
4047 case Intrinsic::nvvm_wmma_m32n8k16_mma_col_row_f32_f32:
4048 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_col_f32_f32:
4049 case Intrinsic::nvvm_wmma_m32n8k16_mma_row_row_f32_f32:
4050 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_col_f32_f32:
4051 case Intrinsic::nvvm_wmma_m8n32k16_mma_col_row_f32_f32:
4052 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_col_f32_f32:
4053 case Intrinsic::nvvm_wmma_m8n32k16_mma_row_row_f32_f32: {
4054 for (
int i = 0; i < 16; i++)
4059 for (
int i = 16; i < 16 + 8; i++)
4071#if LLVM_VERSION_MAJOR < 20
4072 case Intrinsic::nvvm_ldg_global_i:
4073 case Intrinsic::nvvm_ldg_global_p:
4074 case Intrinsic::nvvm_ldg_global_f:
4076 case Intrinsic::nvvm_ldu_global_i:
4077 case Intrinsic::nvvm_ldu_global_p:
4078 case Intrinsic::nvvm_ldu_global_f: {
4079 auto &DL = I.getParent()->getParent()->getParent()->getDataLayout();
4080 auto LoadSize = (DL.getTypeSizeInBits(I.getType()) + 7) / 8;
4085 DL, 0, LoadSize, 0);
4093 case Intrinsic::log:
4094 case Intrinsic::log2:
4095 case Intrinsic::log10:
4096 case Intrinsic::exp:
4097 case Intrinsic::exp2:
4098 case Intrinsic::sin:
4099 case Intrinsic::cos:
4100#if LLVM_VERSION_MAJOR >= 18
4101 case Intrinsic::exp10:
4103#if LLVM_VERSION_MAJOR >= 19
4104 case Intrinsic::sinh:
4105 case Intrinsic::cosh:
4106 case Intrinsic::tanh:
4107 case Intrinsic::tan:
4108 case Intrinsic::asin:
4109 case Intrinsic::acos:
4110 case Intrinsic::atan:
4112 case Intrinsic::floor:
4113 case Intrinsic::ceil:
4114 case Intrinsic::trunc:
4115 case Intrinsic::rint:
4116 case Intrinsic::nearbyint:
4117 case Intrinsic::round:
4118 case Intrinsic::sqrt:
4119#if LLVM_VERSION_MAJOR >= 21
4120 case Intrinsic::nvvm_fabs:
4121 case Intrinsic::nvvm_fabs_ftz:
4123 case Intrinsic::nvvm_fabs_f:
4124 case Intrinsic::nvvm_fabs_d:
4125 case Intrinsic::nvvm_fabs_ftz_f:
4127 case Intrinsic::fabs:
4140#if LLVM_VERSION_MAJOR >= 20
4141 case Intrinsic::sincos: {
4144 Type *T = I.getOperand(0)->getType()->getScalarType();
4146 if (!I.getOperand(0)->getType()->isVectorTy()) {
4147 auto &DL = I.getParent()->getParent()->getParent()->getDataLayout();
4148 auto *ST = cast<StructType>(I.getType());
4149 auto *SL = DL.getStructLayout(ST);
4151 for (
unsigned i = 0; i < 2; i++)
4153 .
Only((
int)(
size_t)SL->getElementOffset(i), &I);
4160 case Intrinsic::lround:
4161 case Intrinsic::llround:
4162 case Intrinsic::lrint:
4163 case Intrinsic::llrint:
4164#if LLVM_VERSION_MAJOR >= 12
4165 case Intrinsic::fptosi_sat:
4166 case Intrinsic::fptoui_sat:
4179 case Intrinsic::fmuladd:
4180 case Intrinsic::fma:
4205 case Intrinsic::powi:
4221#if LLVM_VERSION_MAJOR >= 12
4222 case Intrinsic::vector_reduce_fadd:
4223 case Intrinsic::vector_reduce_fmul:
4225 case Intrinsic::experimental_vector_reduce_v2_fadd:
4226 case Intrinsic::experimental_vector_reduce_v2_fmul:
4228 case Intrinsic::copysign:
4229 case Intrinsic::maxnum:
4230 case Intrinsic::minnum:
4231#if LLVM_VERSION_MAJOR >= 15
4232 case Intrinsic::maximum:
4233 case Intrinsic::minimum:
4235#if LLVM_VERSION_MAJOR >= 20
4236 case Intrinsic::maximumnum:
4237 case Intrinsic::minimumnum:
4239 case Intrinsic::nvvm_fmax_f:
4240 case Intrinsic::nvvm_fmax_d:
4241 case Intrinsic::nvvm_fmax_ftz_f:
4242 case Intrinsic::nvvm_fmin_f:
4243 case Intrinsic::nvvm_fmin_d:
4244 case Intrinsic::nvvm_fmin_ftz_f:
4245 case Intrinsic::pow:
4246#if LLVM_VERSION_MAJOR >= 20
4247 case Intrinsic::atan2:
4266#if LLVM_VERSION_MAJOR >= 12
4267 case Intrinsic::smax:
4268 case Intrinsic::smin:
4269 case Intrinsic::umax:
4270 case Intrinsic::umin:
4279 auto opType0 =
getAnalysis(I.getOperand(0))[{-1}];
4280 auto opType1 =
getAnalysis(I.getOperand(1))[{-1}];
4281 if (opType0 == opType1 &&
4294 case Intrinsic::umul_with_overflow:
4295 case Intrinsic::smul_with_overflow:
4296 case Intrinsic::ssub_with_overflow:
4297 case Intrinsic::usub_with_overflow:
4298 case Intrinsic::sadd_with_overflow:
4299 case Intrinsic::uadd_with_overflow: {
4303 BinaryOperator::BinaryOps opcode;
4305 switch (I.getIntrinsicID()) {
4306 case Intrinsic::ssub_with_overflow:
4307 case Intrinsic::usub_with_overflow: {
4312 opcode = BinaryOperator::Sub;
4316 case Intrinsic::smul_with_overflow:
4317 case Intrinsic::umul_with_overflow: {
4318 opcode = BinaryOperator::Mul;
4323 case Intrinsic::sadd_with_overflow:
4324 case Intrinsic::uadd_with_overflow: {
4325 opcode = BinaryOperator::Add;
4331 llvm_unreachable(
"unknown binary operator");
4345 raw_string_ostream ss(
str);
4351 ss <<
"Illegal updateBinopIntr Analysis " << I <<
"\n";
4352 ss <<
"Illegal binopIn(intr): " << I <<
" lhs: " << vd.
str()
4359 EmitFailure(
"IllegalUpdateAnalysis", I.getDebugLoc(), &I, ss.str());
4360 report_fatal_error(
"Performed illegal updateAnalysis");
4362 auto &dl = I.getParent()->getParent()->getParent()->getDataLayout();
4363 int sz = (dl.getTypeSizeInBits(I.getOperand(0)->getType()) + 7) / 8;
4366 int sz2 = (dl.getTypeSizeInBits(I.getType()) + 7) / 8;
4714 if (
auto iasm = dyn_cast<InlineAsm>(call.getCalledOperand())) {
4716 if (StringRef(iasm->getAsmString()).contains(
"cpuid")) {
4718#if LLVM_VERSION_MAJOR >= 14
4719 for (
auto &arg : call.args())
4721 for (
auto &arg : call.arg_operands())
4729 if (call.hasFnAttr(
"enzyme_ta_norecur"))
4735 if (ci->getAttributes().hasAttribute(AttributeList::FunctionIndex,
4736 "enzyme_ta_norecur"))
4744#include "BlasTA.inc"
4748 const char* NoTARecurStartsWith[] = {
4749 "std::__u::basic_ostream<wchar_t, std::__u::char_traits<wchar_t>>& std::__u::operator<<",
4753 std::string demangledName = llvm::demangle(funcName.str());
4756 while ((start = demangledName.find(
"> >", start)) != std::string::npos) {
4757 demangledName.replace(start, 3,
">>");
4759 for (
auto Name : NoTARecurStartsWith)
4772 if (
startsWith(funcName,
"llvm.intel.subscript")) {
4773 assert(isa<IntrinsicInst>(call));
4785 if (
startsWith(funcName,
"julia.atomicmodify.")) {
4787 auto *RT = cast<StructType>(call.getType());
4788 auto *SL = DL.getStructLayout(RT);
4789 auto LoadSize = (DL.getTypeSizeInBits(RT->getElementType(0)) + 7) / 8;
4790 int Off[2] = {(int)SL->getElementOffset(0), (int)SL->getElementOffset(1)};
4791 Value *ptr = call.getArgOperand(0);
4799 auto updateLocation = [&](
const TypeTree &Loc) {
4808 auto updateResult = [&](
const TypeTree &Loc) {
4811 for (
int i = 0; i < 2; i++)
4817 for (
int i = 0; i < 2; i++)
4820 updateResult(Pointee);
4822 Function *op = dyn_cast<Function>(call.getArgOperand(1));
4823 if (op && !op->empty() && !op->isVarArg() &&
4824 call.arg_size() - 3 == op->getFunctionType()->getNumParams()) {
4828 bool unknown =
false;
4829 for (
size_t i = 0; i < LoadSize;) {
4830 auto CT = Pointee[{(int)i}];
4831 if (
auto flt = CT.isFloat()) {
4832 i += (DL.getTypeSizeInBits(flt) + 7) / 8;
4834 i += DL.getPointerSize(0);
4842 for (
size_t i = 4; !unknown && i < call.arg_size(); i++) {
4843 Value *arg = call.getArgOperand(i);
4844 if (!isa<ConstantData>(arg) && !
getAnalysis(arg).IsFullyDetermined())
4854 for (
auto &arg : op->args()) {
4855 Value *src = argnum == 0 ? nullptr : call.getArgOperand(argnum + 3);
4857 if (arg.getType()->isIntOrIntVectorTy() &&
4861 std::pair<Argument *, TypeTree>(&arg, dt));
4862 std::set<int64_t> bounded;
4871 std::pair<Argument *, std::set<int64_t>>(&arg, bounded));
4875 typeInfo.
Return = Pointee;
4879 llvm::errs() <<
" starting IPO of ";
4880 call.print(llvm::errs(), *
MST);
4881 llvm::errs() <<
"\n";
4887 llvm::errs() <<
" ending IPO of ";
4888 call.print(llvm::errs(), *
MST);
4889 llvm::errs() <<
"\n";
4893 updateLocation(OpRet);
4894 updateResult(OpRet);
4897 for (
auto &arg : op->args()) {
4909#define CONSIDER(fn) \
4910 if (funcName == #fn) { \
4911 analyzeFuncTypes(::fn, call, *this); \
4915#define CONSIDER2(fn, ...) \
4916 if (funcName == #fn) { \
4917 analyzeFuncTypesNoFn<__VA_ARGS__>(call, *this); \
4924 SmallVector<TypeTree, 4> args;
4925 SmallVector<std::set<int64_t>, 4> knownValues;
4926#if LLVM_VERSION_MAJOR >= 14
4927 for (
auto &arg : call.args())
4929 for (
auto &arg : call.arg_operands())
4933 knownValues.push_back(
4937 bool err = customrule->second(
direction, returnAnalysis, args,
4938 knownValues, &call,
this);
4945#if LLVM_VERSION_MAJOR >= 14
4946 for (
auto &arg : call.args())
4948 for (
auto &arg : call.arg_operands())
4960 if (
startsWith(funcName,
"_ZN3std2io5stdio6_print") ||
4965 if (funcName ==
"dgemm_64" || funcName ==
"dgemm_64_" ||
4966 funcName ==
"dgemm" || funcName ==
"dgemm_") {
4971 for (
int i : {0, 1, 2, 3, 4, 7, 9, 12})
4976 ptrdbl.
insert({-1, 0}, Type::getDoubleTy(call.getContext()));
4979 for (
int i : {5, 6, 8, 10, 11})
4984 if (funcName ==
"__kmpc_fork_call") {
4985 Function *fn = dyn_cast<Function>(call.getArgOperand(2));
4987 if (
auto castinst = dyn_cast<ConstantExpr>(call.getArgOperand(2)))
4988 if (castinst->isCast())
4989 fn = dyn_cast<Function>(castinst->getOperand(0));
4992#if LLVM_VERSION_MAJOR >= 14
4993 if (call.arg_size() - 3 != fn->getFunctionType()->getNumParams() - 2)
4996 if (call.getNumArgOperands() - 3 !=
4997 fn->getFunctionType()->getNumParams() - 2)
5009 for (
auto &arg : fn->args()) {
5012 std::pair<Argument *, TypeTree>(&arg, IntPtr));
5014 std::pair<Argument *, std::set<int64_t>>(&arg, {0}));
5016 typeInfo.
Arguments.insert(std::pair<Argument *, TypeTree>(
5017 &arg,
getAnalysis(call.getArgOperand(argnum - 2 + 3))));
5018 std::set<int64_t> bounded;
5020 call.getArgOperand(argnum - 2 + 3),
DT, intseen,
SE)) {
5026 std::pair<Argument *, std::set<int64_t>>(&arg, bounded));
5033 llvm::errs() <<
" starting omp IPO of ";
5034 call.print(llvm::errs(), *
MST);
5035 llvm::errs() <<
"\n";
5038 auto a = fn->arg_begin();
5042#if LLVM_VERSION_MAJOR >= 14
5043 for (
unsigned i = 3; i < call.arg_size(); ++i)
5045 for (
unsigned i = 3; i < call.getNumArgOperands(); ++i)
5048 auto dt = STR.
query(a);
5056 if (funcName ==
"__kmpc_for_static_init_4" ||
5057 funcName ==
"__kmpc_for_static_init_4u" ||
5058 funcName ==
"__kmpc_for_static_init_8" ||
5059 funcName ==
"__kmpc_for_static_init_8u") {
5062 size_t numBytes = 4;
5063 if (funcName ==
"__kmpc_for_static_init_8" ||
5064 funcName ==
"__kmpc_for_static_init_8u")
5066 for (
size_t i = 0; i < numBytes; i++)
5078 if (funcName ==
"omp_get_max_threads" || funcName ==
"omp_get_thread_num" ||
5079 funcName ==
"omp_get_num_threads" ||
5080 funcName ==
"__kmpc_global_thread_num") {
5084 if (funcName ==
"_ZNSt6localeC1Ev") {
5092 if (
startsWith(funcName,
"_ZNKSt3__14hash")) {
5097 if (
startsWith(funcName,
"_ZNKSt3__112basic_string") ||
5098 startsWith(funcName,
"_ZNSt3__112basic_string") ||
5099 startsWith(funcName,
"_ZNSt3__112__hash_table") ||
5100 startsWith(funcName,
"_ZNKSt3__115basic_stringbuf")) {
5104 if (funcName ==
"__dynamic_cast" ||
5105 funcName ==
"_ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base" ||
5106 funcName ==
"_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base" ||
5107 funcName ==
"_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base" ||
5108 funcName ==
"_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base") {
5112 if (funcName ==
"memcmp") {
5124 if (funcName ==
"cuDeviceGet") {
5133 if (funcName ==
"cuDeviceGetName") {
5142 if (funcName ==
"cudaRuntimeGetVersion" ||
5143 funcName ==
"cuDriverGetVersion" || funcName ==
"cuDeviceGetCount") {
5152 if (funcName ==
"cuMemGetInfo_v2") {
5162 if (funcName ==
"cuDevicePrimaryCtxRetain" ||
5163 funcName ==
"cuCtxGetCurrent") {
5170 if (funcName ==
"cuStreamQuery") {
5175 if (funcName ==
"cuMemAllocAsync" || funcName ==
"cuMemAlloc" ||
5176 funcName ==
"cuMemAlloc_v2" || funcName ==
"cudaMalloc" ||
5177 funcName ==
"cudaMallocAsync" || funcName ==
"cudaMallocHost" ||
5178 funcName ==
"cudaMallocFromPoolAsync") {
5188 if (funcName ==
"jl_hrtime" || funcName ==
"ijl_hrtime") {
5192 if (funcName ==
"jl_get_task_tid" || funcName ==
"ijl_get_task_tid") {
5196 if (funcName ==
"jl_get_binding_or_error" ||
5197 funcName ==
"ijl_get_binding_or_error") {
5201 if (funcName ==
"julia.gc_loaded") {
5208 if (funcName ==
"julia.pointer_from_objref") {
5215 if (funcName ==
"_ZNSt6chrono3_V212steady_clock3nowEv") {
5222 funcName = funcName.substr(1);
5223 if (funcName ==
"MPI_Init") {
5236 if (funcName ==
"MPI_Comm_size" || funcName ==
"MPI_Comm_rank" ||
5237 funcName ==
"MPI_Get_processor_name") {
5245 if (funcName ==
"MPI_Barrier" || funcName ==
"MPI_Finalize") {
5249 if (funcName ==
"MPI_Send" || funcName ==
"MPI_Ssend" ||
5250 funcName ==
"MPI_Bsend" || funcName ==
"MPI_Recv" ||
5251 funcName ==
"MPI_Brecv" || funcName ==
"PMPI_Send" ||
5252 funcName ==
"PMPI_Ssend" || funcName ==
"PMPI_Bsend" ||
5253 funcName ==
"PMPI_Recv" || funcName ==
"PMPI_Brecv") {
5256 if (Constant *C = dyn_cast<Constant>(call.getOperand(2))) {
5257 while (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
5258 C = CE->getOperand(0);
5260 if (
auto GV = dyn_cast<GlobalVariable>(C)) {
5261 if (GV->getName() ==
"ompi_mpi_double") {
5262 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5263 }
else if (GV->getName() ==
"ompi_mpi_float") {
5264 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5265 }
else if (GV->getName() ==
"ompi_mpi_cxx_bool") {
5268 }
else if (
auto CI = dyn_cast<ConstantInt>(C)) {
5270 if (CI->getValue() == 1275070475) {
5271 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5272 }
else if (CI->getValue() == 1275069450) {
5273 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5287 if (funcName ==
"MPI_Isend" || funcName ==
"MPI_Irecv" ||
5288 funcName ==
"PMPI_Isend" || funcName ==
"PMPI_Irecv") {
5291 if (Constant *C = dyn_cast<Constant>(call.getOperand(2))) {
5292 while (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
5293 C = CE->getOperand(0);
5295 if (
auto GV = dyn_cast<GlobalVariable>(C)) {
5296 if (GV->getName() ==
"ompi_mpi_double") {
5297 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5298 }
else if (GV->getName() ==
"ompi_mpi_float") {
5299 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5300 }
else if (GV->getName() ==
"ompi_mpi_cxx_bool") {
5303 }
else if (
auto CI = dyn_cast<ConstantInt>(C)) {
5305 if (CI->getValue() == 1275070475) {
5306 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5307 }
else if (CI->getValue() == 1275069450) {
5308 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5324 if (funcName ==
"MPI_Wait") {
5332 if (funcName ==
"MPI_Waitany") {
5344 if (funcName ==
"MPI_Waitall") {
5354 if (funcName ==
"MPI_Bcast") {
5372 if (Constant *C = dyn_cast<Constant>(call.getOperand(3))) {
5373 while (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
5374 C = CE->getOperand(0);
5376 if (
auto GV = dyn_cast<GlobalVariable>(C)) {
5377 if (GV->getName() ==
"ompi_mpi_double") {
5378 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5379 }
else if (GV->getName() ==
"ompi_mpi_float") {
5380 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5381 }
else if (GV->getName() ==
"ompi_mpi_cxx_bool") {
5384 }
else if (
auto CI = dyn_cast<ConstantInt>(C)) {
5386 if (CI->getValue() == 1275070475) {
5387 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5388 }
else if (CI->getValue() == 1275069450) {
5389 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5423 auto &dl = call.getParent()->getParent()->getParent()->getDataLayout();
5436 res = res.
Only(-1, &call);
5451 if (Constant *C = dyn_cast<Constant>(call.getOperand(3))) {
5452 while (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
5453 C = CE->getOperand(0);
5455 if (
auto GV = dyn_cast<GlobalVariable>(C)) {
5456 if (GV->getName() ==
"ompi_mpi_double") {
5457 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5458 }
else if (GV->getName() ==
"ompi_mpi_float") {
5459 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5460 }
else if (GV->getName() ==
"ompi_mpi_cxx_bool") {
5463 }
else if (
auto CI = dyn_cast<ConstantInt>(C)) {
5465 if (CI->getValue() == 1275070475) {
5466 buf.
insert({0}, Type::getDoubleTy(C->getContext()));
5467 }
else if (CI->getValue() == 1275069450) {
5468 buf.
insert({0}, Type::getFloatTy(C->getContext()));
5501 auto &dl = call.getParent()->getParent()->getParent()->getDataLayout();
5514 res = res.
Only(-1, &call);
5521 if (funcName ==
"MPI_Sendrecv_replace") {
5539 if (funcName ==
"MPI_Sendrecv") {
5591 auto &dl = call.getParent()->getParent()->getParent()->getDataLayout();
5604 res = res.
Only(-1, &call);
5611 if (funcName ==
"MPI_Allgather") {
5626 if (ci->hasFnAttribute(
"enzyme_notypeanalysis")) {
5632 if (funcName ==
"_FortranAAssign" && call.arg_size() == 4) {
5633 auto &DL = call.getParent()->getParent()->getParent()->getDataLayout();
5634 for (
int i = 0; i < 2; i++) {
5645 if (funcName ==
"memcpy" || funcName ==
"memmove") {
5650 if (funcName ==
"posix_memalign") {
5662 if (funcName ==
"calloc") {
5672 unsigned index = (size_t)*opidx;
5673 if (
auto CI = dyn_cast<ConstantInt>(call.getOperand(index))) {
5674 auto &DL = call.getParent()->getParent()->getParent()->getDataLayout();
5675 auto LoadSize = CI->getZExtValue();
5685 if (funcName ==
"malloc") {
5687 if (
auto CI = dyn_cast<ConstantInt>(call.getOperand(0))) {
5688 auto &DL = call.getParent()->getParent()->getParent()->getDataLayout();
5689 auto LoadSize = CI->getZExtValue();
5699 if (funcName ==
"__size_returning_new_experiment") {
5701 auto &DL = call.getParent()->getParent()->getParent()->getDataLayout();
5702 if (
auto CI = dyn_cast<ConstantInt>(call.getOperand(0))) {
5703 auto LoadSize = CI->getZExtValue();
5708 ptr = ptr.Only(0, &call);
5715 if (funcName ==
"julia.gc_alloc_obj" || funcName ==
"jl_gc_alloc_typed" ||
5716 funcName ==
"ijl_gc_alloc_typed") {
5718 if (
auto CI = dyn_cast<ConstantInt>(call.getOperand(1))) {
5719 auto &DL = call.getParent()->getParent()->getParent()->getDataLayout();
5720 auto LoadSize = CI->getZExtValue();
5730 if (funcName ==
"julia.except_enter" || funcName ==
"ijl_excstack_state" ||
5731 funcName ==
"jl_excstack_state") {
5735 if (funcName ==
"jl_array_copy" || funcName ==
"ijl_array_copy" ||
5736 funcName ==
"jl_inactive_inout" ||
5737 funcName ==
"jl_genericmemory_copy_slice" ||
5738 funcName ==
"ijl_genericmemory_copy_slice") {
5748 for (
auto &Arg : ci->args()) {
5749 if (Arg.getType()->isIntegerTy()) {
5755 assert(ci->getReturnType()->isPointerTy());
5758 funcName !=
"swift_allocObject") {
5760 if (
auto CI = dyn_cast<ConstantInt>(
5761 call.getOperand(funcName ==
"aligned_alloc" ? 1 : 0))) {
5763 call.getParent()->getParent()->getParent()->getDataLayout();
5764 auto LoadSize = CI->getZExtValue();
5773 if (funcName ==
"malloc_usable_size" || funcName ==
"malloc_size" ||
5774 funcName ==
"_msize") {
5780 if (funcName ==
"realloc") {
5785 sz =
max(sz, (
size_t)val);
5789 auto &dl = call.getParent()->getParent()->getParent()->getDataLayout();
5797 res.
orIn(res2,
false);
5799 res = res.
Only(-1, &call);
5808 if (funcName ==
"sigaction") {
5818 if (funcName ==
"mmap") {
5834 if (funcName ==
"munmap") {
5842 if (funcName ==
"pthread_mutex_lock" ||
5843 funcName ==
"pthread_mutex_trylock" ||
5844 funcName ==
"pthread_rwlock_rdlock" ||
5845 funcName ==
"pthread_rwlock_unlock" ||
5846 funcName ==
"pthread_attr_init" || funcName ==
"pthread_attr_destroy" ||
5847 funcName ==
"pthread_rwlock_unlock" ||
5848 funcName ==
"pthread_mutex_unlock") {
5857 for (
auto &Arg : ci->args()) {
5860 if (Idx == 0 && cudaFree) {
5866 if (Arg.getType()->isIntegerTy()) {
5870 if (Arg.getType()->isPointerTy()) {
5876 if (!ci->getReturnType()->isVoidTy()) {
5881 assert(ci->getReturnType()->isVoidTy());
5884 if (funcName ==
"memchr" || funcName ==
"memrchr") {
5892 if (funcName ==
"strlen") {
5898 if (funcName ==
"strcmp") {
5906 if (funcName ==
"bcmp") {
5916 if (funcName ==
"getcwd") {
5924 if (funcName ==
"sysconf") {
5930 if (funcName ==
"dladdr") {
5938 if (funcName ==
"__errno_location") {
5945 if (funcName ==
"getenv") {
5954 if (funcName ==
"getcwd") {
5962 if (funcName ==
"mprotect") {
5972 if (funcName ==
"memcmp") {
5982 if (funcName ==
"signal") {
5990 if (funcName ==
"write" || funcName ==
"read" || funcName ==
"writev" ||
5991 funcName ==
"readv") {
6003 if (funcName ==
"gsl_sf_legendre_array_e") {
6014 CONSIDER2(modf,
double,
double,
double *)
6018 CONSIDER2(remquo,
double,
double,
double,
int *)
6023#if LLVM_VERSION_MAJOR >= 14
6024 for (
size_t i = 0; i < call.arg_size(); ++i)
6026 for (
size_t i = 0; i < call.getNumArgOperands(); ++i)
6029 Type *T = call.getArgOperand(i)->getType();
6030 if (T->isFloatingPointTy()) {
6032 call.getArgOperand(i),
6034 call.getArgOperand(i)->getType()->getScalarType()))
6037 }
else if (T->isIntegerTy()) {
6040 }
else if (
auto ST = dyn_cast<StructType>(T)) {
6041 assert(ST->getNumElements() >= 1);
6042 for (
size_t i = 1; i < ST->getNumElements(); ++i) {
6043 assert(ST->getTypeAtIndex((
unsigned)0) == ST->getTypeAtIndex(i));
6045 if (ST->getTypeAtIndex((
unsigned)0)->isFloatingPointTy())
6047 call.getArgOperand(i),
6049 ST->getTypeAtIndex((
unsigned)0)->getScalarType()))
6052 else if (ST->getTypeAtIndex((
unsigned)0)->isIntegerTy()) {
6056 llvm::errs() << *T <<
" - " << call <<
"\n";
6057 llvm_unreachable(
"Unknown type for libm");
6059 }
else if (
auto AT = dyn_cast<ArrayType>(T)) {
6060 assert(AT->getNumElements() >= 1);
6061 if (AT->getElementType()->isFloatingPointTy())
6063 call.getArgOperand(i),
6067 else if (AT->getElementType()->isIntegerTy()) {
6071 llvm::errs() << *T <<
" - " << call <<
"\n";
6072 llvm_unreachable(
"Unknown type for libm");
6075 llvm::errs() << *T <<
" - " << call <<
"\n";
6076 llvm_unreachable(
"Unknown type for libm");
6079 Type *T = call.getType();
6080 if (T->isFloatingPointTy()) {
6085 }
else if (T->isIntegerTy()) {
6088 }
else if (T->isVoidTy()) {
6089 }
else if (
auto ST = dyn_cast<StructType>(T)) {
6090 assert(ST->getNumElements() >= 1);
6092 auto &DL = call.getParent()->getParent()->getParent()->getDataLayout();
6093 for (
size_t i = 0; i < ST->getNumElements(); ++i) {
6094 auto T = ST->getTypeAtIndex(i);
6100 if (i + 1 == ST->getNumElements())
6101 nextOffset = (DL.getTypeSizeInBits(ST) + 7) / 8;
6105 if (T->isFloatingPointTy()) {
6107 }
else if (T->isIntegerTy()) {
6113 nextOffset - Offset,
6117 auto Size = (DL.getTypeSizeInBits(ST) + 7) / 8;
6120 }
else if (
auto AT = dyn_cast<ArrayType>(T)) {
6121 assert(AT->getNumElements() >= 1);
6122 if (AT->getElementType()->isFloatingPointTy())
6129 llvm::errs() << *T <<
" - " << call <<
"\n";
6130 llvm_unreachable(
"Unknown type for libm");
6133 llvm::errs() << *T <<
" - " << call <<
"\n";
6134 llvm_unreachable(
"Unknown type for libm");
6138 if (funcName ==
"__lgamma_r_finite") {
6140 call.getArgOperand(0),
6153 if (funcName ==
"__fd_sincos_1" || funcName ==
"__fd_sincos_1f" ||
6154 funcName ==
"__fd_sincos_1l") {
6164 if (funcName ==
"frexp" || funcName ==
"frexpf" || funcName ==
"frexpl") {
6174#if LLVM_VERSION_MAJOR < 17
6176 objSize = DL.getTypeSizeInBits(
6177 call.getOperand(1)->getType()->getPointerElementType()) /
6180 for (
size_t i = 0; i < objSize; ++i) {
6187 if (funcName ==
"__cxa_guard_acquire" || funcName ==
"printf" ||
6188 funcName ==
"vprintf" || funcName ==
"puts" || funcName ==
"fputc" ||
6189 funcName ==
"fprintf") {
6196 if (!ci->empty() && !
hasMetadata(ci,
"enzyme_gradient") &&