[llvm] [GlobalISel] Diagnose inline assembly constraint lowering errors (PR #135782)
Pierre van Houtryve via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 15 05:12:21 PDT 2025
https://github.com/Pierre-vh created https://github.com/llvm/llvm-project/pull/135782
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.
>From 18fddacf58da2b2628fdfa5a30b4b59ec67ec35b Mon Sep 17 00:00:00 2001
From: pvanhout <pierre.vanhoutryve at amd.com>
Date: Tue, 15 Apr 2025 14:10:12 +0200
Subject: [PATCH] [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.
---
.../CodeGen/GlobalISel/InlineAsmLowering.cpp | 75 +++++++++++--------
1 file changed, 42 insertions(+), 33 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
index 81f25b21a0409..97d665c8fbf94 100644
--- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Module.h"
#define DEBUG_TYPE "inline-asm-lowering"
@@ -212,6 +213,17 @@ static bool buildAnyextOrCopy(Register Dst, Register Src,
return true;
}
+static bool reportInlineAsmConstraintError(const CallBase &Call,
+ const GISelAsmOperandInfo &Info,
+ Twine Msg) {
+ LLVMContext &Ctx = Call.getContext();
+ Ctx.diagnose(DiagnosticInfoInlineAsm(
+ Call, "invalid constraint '" + Info.ConstraintCode + "': " + Msg));
+ // TODO(?): Allow selection to continue by recovering/leaving the gMIR in a
+ // good state, like the DAG does.
+ return false;
+}
+
bool InlineAsmLowering::lowerInlineAsm(
MachineIRBuilder &MIRBuilder, const CallBase &Call,
std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
@@ -243,8 +255,8 @@ bool InlineAsmLowering::lowerInlineAsm(
OpInfo.CallOperandVal = const_cast<Value *>(Call.getArgOperand(ArgNo));
if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
- LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo, "basic block input operands not supported yet");
}
Type *OpTy = OpInfo.CallOperandVal->getType();
@@ -258,9 +270,8 @@ bool InlineAsmLowering::lowerInlineAsm(
// FIXME: Support aggregate input operands
if (!OpTy->isSingleValueType()) {
- LLVM_DEBUG(
- dbgs() << "Aggregate input operands are not supported yet\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo, "aggregate input operands not supported yet");
}
OpInfo.ConstraintVT =
@@ -344,9 +355,8 @@ bool InlineAsmLowering::lowerInlineAsm(
// Find a register that we can use.
if (OpInfo.Regs.empty()) {
- LLVM_DEBUG(dbgs()
- << "Couldn't allocate output register for constraint\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo, "couldn't allocate output register for constraint");
}
// Add information to the INLINEASM instruction to know that this
@@ -389,13 +399,14 @@ bool InlineAsmLowering::lowerInlineAsm(
const InlineAsm::Flag MatchedOperandFlag(Inst->getOperand(InstFlagIdx).getImm());
if (MatchedOperandFlag.isMemKind()) {
- LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
- "supported. This should be target specific.\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo,
+ "matching input constraint to mem operand not supported; this "
+ "should be target specific");
}
if (!MatchedOperandFlag.isRegDefKind() && !MatchedOperandFlag.isRegDefEarlyClobberKind()) {
- LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
- return false;
+ return reportInlineAsmConstraintError(Call, OpInfo,
+ "unknown matching constraint");
}
// We want to tie input to register in next operand.
@@ -425,9 +436,10 @@ bool InlineAsmLowering::lowerInlineAsm(
if (OpInfo.ConstraintType == TargetLowering::C_Other &&
OpInfo.isIndirect) {
- LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
- "not supported yet\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo,
+ "indirect input operands with unknown constraint not supported "
+ "yet");
}
if (OpInfo.ConstraintType == TargetLowering::C_Immediate ||
@@ -437,9 +449,8 @@ bool InlineAsmLowering::lowerInlineAsm(
if (!lowerAsmOperandForConstraint(OpInfo.CallOperandVal,
OpInfo.ConstraintCode, Ops,
MIRBuilder)) {
- LLVM_DEBUG(dbgs() << "Don't support constraint: "
- << OpInfo.ConstraintCode << " yet\n");
- return false;
+ return reportInlineAsmConstraintError(Call, OpInfo,
+ "unsupported constraint");
}
assert(Ops.size() > 0 &&
@@ -456,9 +467,9 @@ bool InlineAsmLowering::lowerInlineAsm(
if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
if (!OpInfo.isIndirect) {
- LLVM_DEBUG(dbgs()
- << "Cannot indirectify memory input operands yet\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo,
+ "indirect memory input operands are not supported yet");
}
assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
@@ -482,18 +493,15 @@ bool InlineAsmLowering::lowerInlineAsm(
"Unknown constraint type!");
if (OpInfo.isIndirect) {
- LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
- "for constraint '"
- << OpInfo.ConstraintCode << "'\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo, "indirect register inputs are not supported yet");
}
// Copy the input into the appropriate registers.
if (OpInfo.Regs.empty()) {
- LLVM_DEBUG(
- dbgs()
- << "Couldn't allocate input register for register constraint\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo,
+ "couldn't allocate input register for register constraint");
}
unsigned NumRegs = OpInfo.Regs.size();
@@ -503,9 +511,10 @@ bool InlineAsmLowering::lowerInlineAsm(
"source registers");
if (NumRegs > 1) {
- LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
- "not supported yet\n");
- return false;
+ return reportInlineAsmConstraintError(
+ Call, OpInfo,
+ "input operands with multiple input registers are not supported "
+ "yet");
}
InlineAsm::Flag Flag(InlineAsm::Kind::RegUse, NumRegs);
More information about the llvm-commits
mailing list