-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[GlobalISel] Diagnose inline assembly constraint lowering errors #135782
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GlobalISel] Diagnose inline assembly constraint lowering errors #135782
Conversation
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-llvm-globalisel Author: Pierre van Houtryve (Pierre-vh) ChangesInstead of printing something to dbgs (which is not visible to all users), In a future patch we could also recover from the error like the DAG does, so the Full diff: https://github.com/llvm/llvm-project/pull/135782.diff 1 Files Affected:
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);
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs tests
// TODO(?): Allow selection to continue by recovering/leaving the gMIR in a | ||
// good state, like the DAG does. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this needs to be done
Until we have some form of error recovery testing will be difficult because the compiler crashes on failure |
It certainly should not crash |
I just realized it doesn't have to crash, I can just enable the fallback path. And for recovery, I'm thinking of just using |
18fddac
to
2a3f542
Compare
I added some tests, do you want me to test every message? |
Call, "invalid constraint '" + Info.ConstraintCode + "' in '" + | ||
MF.getName() + "': " + Msg)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using getName, it's broken for anonymous functions. The context should be reported by the caller based on the context instructions, you shouldn't need to include it here
Comprehensive tests are always best
Should fix those too |
✅ With the latest revision this PR passed the undef deprecator. |
llvm/test/CodeGen/AMDGPU/GlobalISel/inline-asm-lowering-errors.ll
Outdated
Show resolved
Hide resolved
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.
b9c9e1e
to
ef0316a
Compare
I had to update some tests. Is this still good to land? |
Merge activity
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/15701 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/15617 Here is the relevant piece of the build log for the reference
|
Reverted this because I wonder if this should be a warning instead, so compilation keeps going? |
…rors (#135782) The initial patch caused issues because it emits an error, and llc is sensitive to it. It also caused compiler-rt/lib/scudo/standalone/tests/wrappers_cpp_test.cpp to fail. Use warnings instead + reject lowering. That way, the fallback path is used without llc/clang returning a failure code. If fallback isn't enabled then the warnings provide context as to why lowering failed. Original commit description: --- 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.
…rors (#139049) The initial patch (#135782 caused issues because it emits an error, and llc is sensitive to it. It also caused compiler-rt/lib/scudo/standalone/tests/wrappers_cpp_test.cpp to fail. Use warnings instead + reject lowering. That way, the fallback path is used without llc/clang returning a failure code. If fallback isn't enabled then the warnings provide context as to why lowering failed. Original commit description for #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.
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.