Skip to content

Commit 764e922

Browse files
committed
AMDGPU: Avoid crashing on statepoint-like pseudoinstructions
At the moment the MIR tests are somewhat redundant. The waitcnt one is needed to ensure we actually have a load, given we are currently just emitting an error on ExternalSymbol. The asm printer one is more redundant for the moment, since it's stressed by the IR test. However I am planning to change the error path for the IR test, so it will soon not be redundant.
1 parent 01737c1 commit 764e922

File tree

13 files changed

+184
-3
lines changed

13 files changed

+184
-3
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,18 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
23502350

23512351
/// Returns the callee operand from the given \p MI.
23522352
virtual const MachineOperand &getCalleeOperand(const MachineInstr &MI) const {
2353-
return MI.getOperand(0);
2353+
assert(MI.isCall());
2354+
2355+
switch (MI.getOpcode()) {
2356+
case TargetOpcode::STATEPOINT:
2357+
case TargetOpcode::STACKMAP:
2358+
case TargetOpcode::PATCHPOINT:
2359+
return MI.getOperand(3);
2360+
default:
2361+
return MI.getOperand(0);
2362+
}
2363+
2364+
llvm_unreachable("impossible call instruction");
23542365
}
23552366

23562367
/// Return the uniformity behavior of the given instruction.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,17 @@ namespace llvm {
331331
MachineBasicBlock *
332332
TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
333333
MachineBasicBlock *MBB) const {
334+
switch (MI.getOpcode()) {
335+
case TargetOpcode::STATEPOINT:
336+
// As an implementation detail, STATEPOINT shares the STACKMAP format at
337+
// this point in the process. We diverge later.
338+
case TargetOpcode::STACKMAP:
339+
case TargetOpcode::PATCHPOINT:
340+
return emitPatchPoint(MI, MBB);
341+
default:
342+
break;
343+
}
344+
334345
#ifndef NDEBUG
335346
dbgs() << "If a target marks an instruction with "
336347
"'usesCustomInserter', it must implement "

llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,8 @@ void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl(
11451145
const CallBase *Call, SDValue Callee, const BasicBlock *EHPadBB,
11461146
bool VarArgDisallowed, bool ForceVoidReturnTy) {
11471147
StatepointLoweringInfo SI(DAG);
1148+
SI.CLI.CB = Call;
1149+
11481150
unsigned ArgBeginIndex = Call->arg_begin() - Call->op_begin();
11491151
populateCallLoweringInfo(
11501152
SI.CLI, Call, ArgBeginIndex, Call->arg_size(), Callee,

llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,16 @@ void AMDGPUAsmPrinter::emitInstruction(const MachineInstr *MI) {
406406
return;
407407
}
408408

409+
unsigned Opc = MI->getOpcode();
410+
if (LLVM_UNLIKELY(Opc == TargetOpcode::STATEPOINT ||
411+
Opc == TargetOpcode::STACKMAP ||
412+
Opc == TargetOpcode::PATCHPOINT)) {
413+
LLVMContext &Ctx = MI->getMF()->getFunction().getContext();
414+
Ctx.emitError("unhandled statepoint-like instruction");
415+
OutStreamer->emitRawComment("unsupported statepoint/stackmap/patchpoint");
416+
return;
417+
}
418+
409419
if (isVerbose())
410420
if (STI.getInstrInfo()->isBlockLoadStore(MI->getOpcode()))
411421
emitVGPRBlockComment(MI, STI.getInstrInfo(), STI.getRegisterInfo(),

llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,13 @@ AMDGPUResourceUsageAnalysisImpl::analyzeResourceUsage(
256256
// Pseudo used just to encode the underlying global. Is there a better
257257
// way to track this?
258258

259+
// TODO: Some of the generic call-like pseudos do not encode the callee,
260+
// so we overly conservatively treat this as an indirect call.
259261
const MachineOperand *CalleeOp =
260262
TII->getNamedOperand(MI, AMDGPU::OpName::callee);
261263

262-
const Function *Callee = getCalleeFunction(*CalleeOp);
264+
const Function *Callee =
265+
CalleeOp ? getCalleeFunction(*CalleeOp) : nullptr;
263266

264267
auto isSameFunction = [](const MachineFunction &MF, const Function *F) {
265268
return F == &MF.getFunction();

llvm/lib/Target/AMDGPU/SIISelLowering.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
275275
setTruncStoreAction(MVT::v16i64, MVT::v16i32, Expand);
276276

277277
setOperationAction(ISD::GlobalAddress, {MVT::i32, MVT::i64}, Custom);
278+
setOperationAction(ISD::ExternalSymbol, {MVT::i32, MVT::i64}, Custom);
278279

279280
setOperationAction(ISD::SELECT, MVT::i1, Promote);
280281
setOperationAction(ISD::SELECT, MVT::i64, Custom);
@@ -6838,6 +6839,8 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
68386839
SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
68396840
return LowerGlobalAddress(MFI, Op, DAG);
68406841
}
6842+
case ISD::ExternalSymbol:
6843+
return LowerExternalSymbol(Op, DAG);
68416844
case ISD::INTRINSIC_WO_CHAIN:
68426845
return LowerINTRINSIC_WO_CHAIN(Op, DAG);
68436846
case ISD::INTRINSIC_W_CHAIN:
@@ -9017,6 +9020,15 @@ SDValue SITargetLowering::LowerGlobalAddress(AMDGPUMachineFunction *MFI,
90179020
MachineMemOperand::MOInvariant);
90189021
}
90199022

9023+
SDValue SITargetLowering::LowerExternalSymbol(SDValue Op,
9024+
SelectionDAG &DAG) const {
9025+
// TODO: Handle this. It should be mostly the same as LowerGlobalAddress.
9026+
const Function &Fn = DAG.getMachineFunction().getFunction();
9027+
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
9028+
Fn, "unsupported external symbol", Op.getDebugLoc()));
9029+
return DAG.getPOISON(Op.getValueType());
9030+
}
9031+
90209032
SDValue SITargetLowering::copyToM0(SelectionDAG &DAG, SDValue Chain,
90219033
const SDLoc &DL, SDValue V) const {
90229034
// We can't use S_MOV_B32 directly, because there is no way to specify m0 as

llvm/lib/Target/AMDGPU/SIISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ class SITargetLowering final : public AMDGPUTargetLowering {
7979

8080
SDValue LowerGlobalAddress(AMDGPUMachineFunction *MFI, SDValue Op,
8181
SelectionDAG &DAG) const override;
82+
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
83+
8284
SDValue lowerImplicitZextParam(SelectionDAG &DAG, SDValue Op,
8385
MVT VT, unsigned Offset) const;
8486
SDValue lowerImage(SDValue Op, const AMDGPU::ImageDimIntrinsicInfo *Intr,

llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1955,7 +1955,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
19551955
// load). We also need to check WAW dependency with saved PC.
19561956
Wait = AMDGPU::Waitcnt();
19571957

1958-
const auto &CallAddrOp = *TII->getNamedOperand(MI, AMDGPU::OpName::src0);
1958+
const MachineOperand &CallAddrOp = TII->getCalleeOperand(MI);
19591959
if (CallAddrOp.isReg()) {
19601960
RegInterval CallAddrOpInterval =
19611961
ScoreBrackets.getRegInterval(&MI, CallAddrOp);

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10510,6 +10510,14 @@ unsigned SIInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
1051010510
return SchedModel.computeInstrLatency(&MI);
1051110511
}
1051210512

10513+
const MachineOperand &
10514+
SIInstrInfo::getCalleeOperand(const MachineInstr &MI) const {
10515+
if (const MachineOperand *CallAddrOp =
10516+
getNamedOperand(MI, AMDGPU::OpName::src0))
10517+
return *CallAddrOp;
10518+
return TargetInstrInfo::getCalleeOperand(MI);
10519+
}
10520+
1051310521
InstructionUniformity
1051410522
SIInstrInfo::getGenericInstructionUniformity(const MachineInstr &MI) const {
1051510523
const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();

llvm/lib/Target/AMDGPU/SIInstrInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,8 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
16411641
const MachineInstr &MI,
16421642
unsigned *PredCost = nullptr) const override;
16431643

1644+
const MachineOperand &getCalleeOperand(const MachineInstr &MI) const override;
1645+
16441646
InstructionUniformity
16451647
getInstructionUniformity(const MachineInstr &MI) const final;
16461648

0 commit comments

Comments
 (0)