Skip to content

Commit 18fddac

Browse files
committed
[GlobalISel] Diagnose inline assembly constraint lowering errors
Instead of printing something to dbgs (which is not visible to all users), emit a diagnostic like the DAG does. We still crash later because we fail to select the inline assembly, but at least now users will know why it's crashing. In a future patch we could also recover from the error like the DAG does, so the lowering can keep going until it either crashes or gives a different error later.
1 parent 0f52649 commit 18fddac

File tree

1 file changed

+42
-33
lines changed

1 file changed

+42
-33
lines changed

llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/CodeGen/MachineOperand.h"
1717
#include "llvm/CodeGen/MachineRegisterInfo.h"
1818
#include "llvm/CodeGen/TargetLowering.h"
19+
#include "llvm/IR/DiagnosticInfo.h"
1920
#include "llvm/IR/Module.h"
2021

2122
#define DEBUG_TYPE "inline-asm-lowering"
@@ -212,6 +213,17 @@ static bool buildAnyextOrCopy(Register Dst, Register Src,
212213
return true;
213214
}
214215

216+
static bool reportInlineAsmConstraintError(const CallBase &Call,
217+
const GISelAsmOperandInfo &Info,
218+
Twine Msg) {
219+
LLVMContext &Ctx = Call.getContext();
220+
Ctx.diagnose(DiagnosticInfoInlineAsm(
221+
Call, "invalid constraint '" + Info.ConstraintCode + "': " + Msg));
222+
// TODO(?): Allow selection to continue by recovering/leaving the gMIR in a
223+
// good state, like the DAG does.
224+
return false;
225+
}
226+
215227
bool InlineAsmLowering::lowerInlineAsm(
216228
MachineIRBuilder &MIRBuilder, const CallBase &Call,
217229
std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
@@ -243,8 +255,8 @@ bool InlineAsmLowering::lowerInlineAsm(
243255
OpInfo.CallOperandVal = const_cast<Value *>(Call.getArgOperand(ArgNo));
244256

245257
if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
246-
LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
247-
return false;
258+
return reportInlineAsmConstraintError(
259+
Call, OpInfo, "basic block input operands not supported yet");
248260
}
249261

250262
Type *OpTy = OpInfo.CallOperandVal->getType();
@@ -258,9 +270,8 @@ bool InlineAsmLowering::lowerInlineAsm(
258270

259271
// FIXME: Support aggregate input operands
260272
if (!OpTy->isSingleValueType()) {
261-
LLVM_DEBUG(
262-
dbgs() << "Aggregate input operands are not supported yet\n");
263-
return false;
273+
return reportInlineAsmConstraintError(
274+
Call, OpInfo, "aggregate input operands not supported yet");
264275
}
265276

266277
OpInfo.ConstraintVT =
@@ -344,9 +355,8 @@ bool InlineAsmLowering::lowerInlineAsm(
344355

345356
// Find a register that we can use.
346357
if (OpInfo.Regs.empty()) {
347-
LLVM_DEBUG(dbgs()
348-
<< "Couldn't allocate output register for constraint\n");
349-
return false;
358+
return reportInlineAsmConstraintError(
359+
Call, OpInfo, "couldn't allocate output register for constraint");
350360
}
351361

352362
// Add information to the INLINEASM instruction to know that this
@@ -389,13 +399,14 @@ bool InlineAsmLowering::lowerInlineAsm(
389399

390400
const InlineAsm::Flag MatchedOperandFlag(Inst->getOperand(InstFlagIdx).getImm());
391401
if (MatchedOperandFlag.isMemKind()) {
392-
LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
393-
"supported. This should be target specific.\n");
394-
return false;
402+
return reportInlineAsmConstraintError(
403+
Call, OpInfo,
404+
"matching input constraint to mem operand not supported; this "
405+
"should be target specific");
395406
}
396407
if (!MatchedOperandFlag.isRegDefKind() && !MatchedOperandFlag.isRegDefEarlyClobberKind()) {
397-
LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
398-
return false;
408+
return reportInlineAsmConstraintError(Call, OpInfo,
409+
"unknown matching constraint");
399410
}
400411

401412
// We want to tie input to register in next operand.
@@ -425,9 +436,10 @@ bool InlineAsmLowering::lowerInlineAsm(
425436

426437
if (OpInfo.ConstraintType == TargetLowering::C_Other &&
427438
OpInfo.isIndirect) {
428-
LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
429-
"not supported yet\n");
430-
return false;
439+
return reportInlineAsmConstraintError(
440+
Call, OpInfo,
441+
"indirect input operands with unknown constraint not supported "
442+
"yet");
431443
}
432444

433445
if (OpInfo.ConstraintType == TargetLowering::C_Immediate ||
@@ -437,9 +449,8 @@ bool InlineAsmLowering::lowerInlineAsm(
437449
if (!lowerAsmOperandForConstraint(OpInfo.CallOperandVal,
438450
OpInfo.ConstraintCode, Ops,
439451
MIRBuilder)) {
440-
LLVM_DEBUG(dbgs() << "Don't support constraint: "
441-
<< OpInfo.ConstraintCode << " yet\n");
442-
return false;
452+
return reportInlineAsmConstraintError(Call, OpInfo,
453+
"unsupported constraint");
443454
}
444455

445456
assert(Ops.size() > 0 &&
@@ -456,9 +467,9 @@ bool InlineAsmLowering::lowerInlineAsm(
456467
if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
457468

458469
if (!OpInfo.isIndirect) {
459-
LLVM_DEBUG(dbgs()
460-
<< "Cannot indirectify memory input operands yet\n");
461-
return false;
470+
return reportInlineAsmConstraintError(
471+
Call, OpInfo,
472+
"indirect memory input operands are not supported yet");
462473
}
463474

464475
assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
@@ -482,18 +493,15 @@ bool InlineAsmLowering::lowerInlineAsm(
482493
"Unknown constraint type!");
483494

484495
if (OpInfo.isIndirect) {
485-
LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
486-
"for constraint '"
487-
<< OpInfo.ConstraintCode << "'\n");
488-
return false;
496+
return reportInlineAsmConstraintError(
497+
Call, OpInfo, "indirect register inputs are not supported yet");
489498
}
490499

491500
// Copy the input into the appropriate registers.
492501
if (OpInfo.Regs.empty()) {
493-
LLVM_DEBUG(
494-
dbgs()
495-
<< "Couldn't allocate input register for register constraint\n");
496-
return false;
502+
return reportInlineAsmConstraintError(
503+
Call, OpInfo,
504+
"couldn't allocate input register for register constraint");
497505
}
498506

499507
unsigned NumRegs = OpInfo.Regs.size();
@@ -503,9 +511,10 @@ bool InlineAsmLowering::lowerInlineAsm(
503511
"source registers");
504512

505513
if (NumRegs > 1) {
506-
LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
507-
"not supported yet\n");
508-
return false;
514+
return reportInlineAsmConstraintError(
515+
Call, OpInfo,
516+
"input operands with multiple input registers are not supported "
517+
"yet");
509518
}
510519

511520
InlineAsm::Flag Flag(InlineAsm::Kind::RegUse, NumRegs);

0 commit comments

Comments
 (0)