Skip to content

Commit 17e680d

Browse files
committed
abstract parts of call code; disallow operand bundles for callbr in verifier
1 parent 789a729 commit 17e680d

File tree

6 files changed

+237
-144
lines changed

6 files changed

+237
-144
lines changed

llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ class IRTranslator : public MachineFunctionPass {
297297
/// \pre \p U is a call instruction.
298298
bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
299299

300+
bool translateTargetIntrinsic(
301+
const CallBase &CB, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder,
302+
TargetLowering::IntrinsicInfo *TgtMemIntrinsicInfo = nullptr);
303+
300304
/// When an invoke or a cleanupret unwinds to the next EH pad, there are
301305
/// many places it could ultimately go. In the IR, we have a single unwind
302306
/// destination, but in the machine CFG, we enumerate all the possible blocks.
@@ -313,6 +317,7 @@ class IRTranslator : public MachineFunctionPass {
313317
bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
314318

315319
bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
320+
bool translateCallBrIntrinsic(const CallBrInst &I, MachineIRBuilder &MIRBuilder);
316321

317322
bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
318323

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 84 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,59 +2750,27 @@ bool IRTranslator::translateCallBase(const CallBase &CB,
27502750
return Success;
27512751
}
27522752

2753-
bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
2754-
if (containsBF16Type(U))
2755-
return false;
2756-
2757-
const CallInst &CI = cast<CallInst>(U);
2758-
const Function *F = CI.getCalledFunction();
2759-
2760-
// FIXME: support Windows dllimport function calls and calls through
2761-
// weak symbols.
2762-
if (F && (F->hasDLLImportStorageClass() ||
2763-
(MF->getTarget().getTargetTriple().isOSWindows() &&
2764-
F->hasExternalWeakLinkage())))
2765-
return false;
2766-
2767-
// FIXME: support control flow guard targets.
2768-
if (CI.countOperandBundlesOfType(LLVMContext::OB_cfguardtarget))
2769-
return false;
2770-
2771-
// FIXME: support statepoints and related.
2772-
if (isa<GCStatepointInst, GCRelocateInst, GCResultInst>(U))
2773-
return false;
2774-
2775-
if (CI.isInlineAsm())
2776-
return translateInlineAsm(CI, MIRBuilder);
2777-
2778-
diagnoseDontCall(CI);
2779-
2780-
Intrinsic::ID ID = Intrinsic::not_intrinsic;
2781-
if (F && F->isIntrinsic())
2782-
ID = F->getIntrinsicID();
2783-
2784-
if (!F || !F->isIntrinsic() || ID == Intrinsic::not_intrinsic)
2785-
return translateCallBase(CI, MIRBuilder);
2786-
2787-
assert(ID != Intrinsic::not_intrinsic && "unknown intrinsic");
2788-
2789-
if (translateKnownIntrinsic(CI, ID, MIRBuilder))
2790-
return true;
2791-
2753+
/// Translate a call or callbr to a target intrinsic.
2754+
/// Depending on whether TLI->getTgtMemIntrinsic() is true, TgtMemIntrinsicInfo
2755+
/// is a pointer to the correspondingly populated IntrinsicInfo object.
2756+
/// Otherwise, this pointer is null.
2757+
bool IRTranslator::translateTargetIntrinsic(
2758+
const CallBase &CB, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder,
2759+
TargetLowering::IntrinsicInfo *TgtMemIntrinsicInfo) {
27922760
ArrayRef<Register> ResultRegs;
2793-
if (!CI.getType()->isVoidTy())
2794-
ResultRegs = getOrCreateVRegs(CI);
2761+
if (!CB.getType()->isVoidTy())
2762+
ResultRegs = getOrCreateVRegs(CB);
27952763

27962764
// Ignore the callsite attributes. Backend code is most likely not expecting
27972765
// an intrinsic to sometimes have side effects and sometimes not.
27982766
MachineInstrBuilder MIB = MIRBuilder.buildIntrinsic(ID, ResultRegs);
2799-
if (isa<FPMathOperator>(CI))
2800-
MIB->copyIRFlags(CI);
2767+
if (isa<FPMathOperator>(CB))
2768+
MIB->copyIRFlags(CB);
28012769

2802-
for (const auto &Arg : enumerate(CI.args())) {
2770+
for (const auto &Arg : enumerate(CB.args())) {
28032771
// If this is required to be an immediate, don't materialize it in a
28042772
// register.
2805-
if (CI.paramHasAttr(Arg.index(), Attribute::ImmArg)) {
2773+
if (CB.paramHasAttr(Arg.index(), Attribute::ImmArg)) {
28062774
if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg.value())) {
28072775
// imm arguments are more convenient than cimm (and realistically
28082776
// probably sufficient), so use them.
@@ -2831,29 +2799,31 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
28312799
}
28322800

28332801
// Add a MachineMemOperand if it is a target mem intrinsic.
2834-
TargetLowering::IntrinsicInfo Info;
2835-
// TODO: Add a GlobalISel version of getTgtMemIntrinsic.
2836-
if (TLI->getTgtMemIntrinsic(Info, CI, *MF, ID)) {
2837-
Align Alignment = Info.align.value_or(
2838-
DL->getABITypeAlign(Info.memVT.getTypeForEVT(F->getContext())));
2839-
LLT MemTy = Info.memVT.isSimple()
2840-
? getLLTForMVT(Info.memVT.getSimpleVT())
2841-
: LLT::scalar(Info.memVT.getStoreSizeInBits());
2802+
if (TgtMemIntrinsicInfo) {
2803+
const Function *F = CB.getCalledFunction();
2804+
2805+
Align Alignment = TgtMemIntrinsicInfo->align.value_or(DL->getABITypeAlign(
2806+
TgtMemIntrinsicInfo->memVT.getTypeForEVT(F->getContext())));
2807+
LLT MemTy =
2808+
TgtMemIntrinsicInfo->memVT.isSimple()
2809+
? getLLTForMVT(TgtMemIntrinsicInfo->memVT.getSimpleVT())
2810+
: LLT::scalar(TgtMemIntrinsicInfo->memVT.getStoreSizeInBits());
28422811

28432812
// TODO: We currently just fallback to address space 0 if getTgtMemIntrinsic
28442813
// didn't yield anything useful.
28452814
MachinePointerInfo MPI;
2846-
if (Info.ptrVal)
2847-
MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
2848-
else if (Info.fallbackAddressSpace)
2849-
MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
2815+
if (TgtMemIntrinsicInfo->ptrVal)
2816+
MPI = MachinePointerInfo(TgtMemIntrinsicInfo->ptrVal,
2817+
TgtMemIntrinsicInfo->offset);
2818+
else if (TgtMemIntrinsicInfo->fallbackAddressSpace)
2819+
MPI = MachinePointerInfo(*TgtMemIntrinsicInfo->fallbackAddressSpace);
28502820
MIB.addMemOperand(MF->getMachineMemOperand(
2851-
MPI, Info.flags, MemTy, Alignment, CI.getAAMetadata(),
2852-
/*Ranges=*/nullptr, Info.ssid, Info.order, Info.failureOrder));
2821+
MPI, TgtMemIntrinsicInfo->flags, MemTy, Alignment, CI.getAAMetadata(),
2822+
/*Ranges=*/nullptr, TgtMemIntrinsicInfo->ssid, TgtMemIntrinsicInfo->order, TgtMemIntrinsicInfo->failureOrder));
28532823
}
28542824

2855-
if (CI.isConvergent()) {
2856-
if (auto Bundle = CI.getOperandBundle(LLVMContext::OB_convergencectrl)) {
2825+
if (CB.isConvergent()) {
2826+
if (auto Bundle = CB.getOperandBundle(LLVMContext::OB_convergencectrl)) {
28572827
auto *Token = Bundle->Inputs[0].get();
28582828
Register TokenReg = getOrCreateVReg(*Token);
28592829
MIB.addUse(TokenReg, RegState::Implicit);
@@ -2863,6 +2833,53 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
28632833
return true;
28642834
}
28652835

2836+
bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
2837+
if (containsBF16Type(U))
2838+
return false;
2839+
2840+
const CallInst &CI = cast<CallInst>(U);
2841+
const Function *F = CI.getCalledFunction();
2842+
2843+
// FIXME: support Windows dllimport function calls and calls through
2844+
// weak symbols.
2845+
if (F && (F->hasDLLImportStorageClass() ||
2846+
(MF->getTarget().getTargetTriple().isOSWindows() &&
2847+
F->hasExternalWeakLinkage())))
2848+
return false;
2849+
2850+
// FIXME: support control flow guard targets.
2851+
if (CI.countOperandBundlesOfType(LLVMContext::OB_cfguardtarget))
2852+
return false;
2853+
2854+
// FIXME: support statepoints and related.
2855+
if (isa<GCStatepointInst, GCRelocateInst, GCResultInst>(U))
2856+
return false;
2857+
2858+
if (CI.isInlineAsm())
2859+
return translateInlineAsm(CI, MIRBuilder);
2860+
2861+
diagnoseDontCall(CI);
2862+
2863+
Intrinsic::ID ID = Intrinsic::not_intrinsic;
2864+
if (F && F->isIntrinsic())
2865+
ID = F->getIntrinsicID();
2866+
2867+
if (!F || !F->isIntrinsic() || ID == Intrinsic::not_intrinsic)
2868+
return translateCallBase(CI, MIRBuilder);
2869+
2870+
assert(ID != Intrinsic::not_intrinsic && "unknown intrinsic");
2871+
2872+
if (translateKnownIntrinsic(CI, ID, MIRBuilder))
2873+
return true;
2874+
2875+
TargetLowering::IntrinsicInfo Info;
2876+
// TODO: Add a GlobalISel version of getTgtMemIntrinsic.
2877+
bool IsTgtMemIntrinsic = TLI->getTgtMemIntrinsic(Info, CI, *MF, ID);
2878+
2879+
return translateTargetIntrinsic(CI, ID, MIRBuilder,
2880+
IsTgtMemIntrinsic ? &Info : nullptr);
2881+
}
2882+
28662883
bool IRTranslator::findUnwindDestinations(
28672884
const BasicBlock *EHPadBB,
28682885
BranchProbability Prob,
@@ -3006,15 +3023,16 @@ bool IRTranslator::translateInvoke(const User &U,
30063023
return true;
30073024
}
30083025

3026+
/// The intrinsics currently supported by callbr are implicit control flow
3027+
/// intrinsics such as amdgcn.kill.
30093028
bool IRTranslator::translateCallBr(const User &U,
30103029
MachineIRBuilder &MIRBuilder) {
3030+
if (containsBF16Type(U))
3031+
return false; // see translateCall
3032+
30113033
const CallBrInst &I = cast<CallBrInst>(U);
30123034
MachineBasicBlock *CallBrMBB = &MIRBuilder.getMBB();
30133035

3014-
// TODO: operand bundles (see SelDAG implementation of callbr)?
3015-
assert(!I.hasOperandBundles() &&
3016-
"Cannot lower callbrs with operand bundles yet");
3017-
30183036
if (I.isInlineAsm()) {
30193037
// FIXME: inline asm not yet supported
30203038
if (!translateInlineAsm(I, MIRBuilder))
@@ -3024,15 +3042,7 @@ bool IRTranslator::translateCallBr(const User &U,
30243042
default:
30253043
report_fatal_error("Unsupported intrinsic for callbr");
30263044
case Intrinsic::amdgcn_kill:
3027-
if (I.getNumIndirectDests() != 1)
3028-
report_fatal_error(
3029-
"amdgcn.kill supportes exactly one indirect destination");
3030-
CallInst *CI =
3031-
CallInst::Create(I.getFunctionType(), I.getCalledFunction(),
3032-
SmallVector<Value *, 1>(I.args()));
3033-
bool Success = translateCall(*CI, MIRBuilder);
3034-
CI->deleteValue();
3035-
if (!Success)
3045+
if (!translateTargetIntrinsic(I, Intrinsic::amdgcn_kill, MIRBuilder))
30363046
return false;
30373047
break;
30383048
}

0 commit comments

Comments
 (0)