[llvm] ddd7d35 - [RegAlloc] Fix assertion failure caused by inline assembly
Bryan Chan via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 25 16:12:00 PDT 2023
Author: Qi Hu
Date: 2023-07-25T19:21:03-04:00
New Revision: ddd7d35c6c2697eec8d665e70d4e1395003cbec9
URL: https://github.com/llvm/llvm-project/commit/ddd7d35c6c2697eec8d665e70d4e1395003cbec9
DIFF: https://github.com/llvm/llvm-project/commit/ddd7d35c6c2697eec8d665e70d4e1395003cbec9.diff
LOG: [RegAlloc] Fix assertion failure caused by inline assembly
When inline assembly code requests more registers than available, the
MachineInstr::emitError function in the RegAllocFast pass emits an error
but doesn't stop the pass, and then the compiler crashes later with an
assertion failure. This commit, mimicking the RegAllocGreedy pass, assigns
a random physical register, and therefore avoids the crash after producing
the diagnostic. This problem has been observed for both rustc and clang,
while it doesn't occur in gcc.
Added:
llvm/test/CodeGen/X86/inline-asm-assertion.ll
Modified:
llvm/lib/CodeGen/RegAllocFast.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 864beb8720f439..e2a1b8f07e6118 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -932,9 +932,18 @@ bool RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
}
}
}
- if (LRI->PhysReg == 0)
+ if (LRI->PhysReg == 0) {
allocVirtReg(MI, *LRI, 0, LookAtPhysRegUses);
- else {
+ // If no physical register is available for LRI, we assign one at random
+ // and bail out of this function immediately.
+ if (LRI->Error) {
+ const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
+ ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC);
+ if (AllocationOrder.empty())
+ return setPhysReg(MI, MO, MCRegister::NoRegister);
+ return setPhysReg(MI, MO, *AllocationOrder.begin());
+ }
+ } else {
assert(!isRegUsedInInstr(LRI->PhysReg, LookAtPhysRegUses) &&
"TODO: preassign mismatch");
LLVM_DEBUG(dbgs() << "In def of " << printReg(VirtReg, TRI)
@@ -943,7 +952,6 @@ bool RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
}
MCPhysReg PhysReg = LRI->PhysReg;
- assert(PhysReg != 0 && "Register not assigned");
if (LRI->Reloaded || LRI->LiveOut) {
if (!MI.isImplicitDef()) {
MachineBasicBlock::iterator SpillBefore =
@@ -1024,6 +1032,8 @@ bool RegAllocFast::useVirtReg(MachineInstr &MI, unsigned OpNum,
if (LRI->Error) {
const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC);
+ if (AllocationOrder.empty())
+ return setPhysReg(MI, MO, MCRegister::NoRegister);
return setPhysReg(MI, MO, *AllocationOrder.begin());
}
}
diff --git a/llvm/test/CodeGen/X86/inline-asm-assertion.ll b/llvm/test/CodeGen/X86/inline-asm-assertion.ll
new file mode 100644
index 00000000000000..d5507a1c441703
--- /dev/null
+++ b/llvm/test/CodeGen/X86/inline-asm-assertion.ll
@@ -0,0 +1,62 @@
+; RUN: not llc -verify-machineinstrs -O0 < %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -verify-machineinstrs -O2 < %s 2>&1 | FileCheck %s --check-prefix=CHECK-O2
+; CHECK: error: inline assembly requires more registers than available
+; CHECK: .size main, .Lfunc_end0-main
+; CHECK-O2: error: inline assembly requires more registers than available
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @main() #0 {
+entry:
+ %r0 = alloca i32, align 4
+ %r1 = alloca i32, align 4
+ %r2 = alloca i32, align 4
+ %r3 = alloca i32, align 4
+ %r4 = alloca i32, align 4
+ %r5 = alloca i32, align 4
+ %r6 = alloca i32, align 4
+ %r7 = alloca i32, align 4
+ %r8 = alloca i32, align 4
+ %r9 = alloca i32, align 4
+ %r10 = alloca i32, align 4
+ %r11 = alloca i32, align 4
+ %r12 = alloca i32, align 4
+ %r13 = alloca i32, align 4
+ %r14 = alloca i32, align 4
+ %0 = call { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } asm "movl $$0, $0;movl $$1, $1;movl $$2, $2;movl $$3, $3;movl $$4, $4;movl $$5, $5;movl $$6, $6;movl $$7, $7;movl $$8, $8;movl $$9, $9;movl $$10, $10;movl $$11, $11;movl $$12, $12;movl $$13, $13;movl $$14, $14;", "=r,=r,=r,=r,=r,=r,=r,=r,=r,=r,=r,=r,=r,=r,=r,~{dirflag},~{fpsr},~{flags}"() #1
+ %asmresult = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 0
+ %asmresult1 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 1
+ %asmresult2 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 2
+ %asmresult3 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 3
+ %asmresult4 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 4
+ %asmresult5 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 5
+ %asmresult6 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 6
+ %asmresult7 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 7
+ %asmresult8 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 8
+ %asmresult9 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 9
+ %asmresult10 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 10
+ %asmresult11 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 11
+ %asmresult12 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 12
+ %asmresult13 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 13
+ %asmresult14 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %0, 14
+ store i32 %asmresult, ptr %r0, align 4
+ store i32 %asmresult1, ptr %r1, align 4
+ store i32 %asmresult2, ptr %r2, align 4
+ store i32 %asmresult3, ptr %r3, align 4
+ store i32 %asmresult4, ptr %r4, align 4
+ store i32 %asmresult5, ptr %r5, align 4
+ store i32 %asmresult6, ptr %r6, align 4
+ store i32 %asmresult7, ptr %r7, align 4
+ store i32 %asmresult8, ptr %r8, align 4
+ store i32 %asmresult9, ptr %r9, align 4
+ store i32 %asmresult10, ptr %r10, align 4
+ store i32 %asmresult11, ptr %r11, align 4
+ store i32 %asmresult12, ptr %r12, align 4
+ store i32 %asmresult13, ptr %r13, align 4
+ store i32 %asmresult14, ptr %r14, align 4
+ ret i32 0
+}
+
+attributes #0 = { "frame-pointer"="all" }
More information about the llvm-commits
mailing list