[llvm] 438a63e - RegAlloc: do not consider liveins to EH-pad successors as liveout.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 29 11:34:56 PDT 2021


Author: Tim Northover
Date: 2021-04-29T19:34:49+01:00
New Revision: 438a63e13bf89ebe21768940976a6eea6285f5ff

URL: https://github.com/llvm/llvm-project/commit/438a63e13bf89ebe21768940976a6eea6285f5ff
DIFF: https://github.com/llvm/llvm-project/commit/438a63e13bf89ebe21768940976a6eea6285f5ff.diff

LOG: RegAlloc: do not consider liveins to EH-pad successors as liveout.

These registers get defined by the runtime, not the block being allocated, and
treating them as preassigned in RegAllocFast adds extra pressure, sometimes
enough to make the function unallocatable.

Added: 
    llvm/test/CodeGen/X86/regalloc-tight-invoke.ll

Modified: 
    llvm/lib/CodeGen/RegAllocFast.cpp
    llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 6d4194006afd..994a1854a988 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -1002,7 +1002,7 @@ void RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO,
 #ifndef NDEBUG
 
 void RegAllocFast::dumpState() const {
-  for (unsigned Unit = 1, UnitE = TRI->getNumRegUnits(); Unit != UnitE;
+  for (unsigned Unit = 0, UnitE = TRI->getNumRegUnits(); Unit != UnitE;
        ++Unit) {
     switch (unsigned VirtReg = RegUnitStates[Unit]) {
     case regFree:
@@ -1440,6 +1440,11 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
   assert(LiveVirtRegs.empty() && "Mapping not cleared from last block?");
 
   for (MachineBasicBlock *Succ : MBB.successors()) {
+    // EH-pads get their liveins from the runtime, not whatever happens in this
+    // block.
+    if (Succ->isEHPad())
+      continue;
+
     for (const MachineBasicBlock::RegisterMaskPair &LI : Succ->liveins())
       setPhysRegState(LI.PhysReg, regPreAssigned);
   }

diff  --git a/llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll b/llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll
index 9a54c8711f37..e262448468eb 100644
--- a/llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll
+++ b/llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll
@@ -19,7 +19,7 @@ exit:
 ; 
diff erent basic block, so its operands aren't necessarily exported
 ; for cross-block usage.
 
-; CHECK: movb    %cl, [[OFS:[0-9]*]](%rsp)
+; CHECK: movb    %al, [[OFS:[0-9]*]](%rsp)
 ; CHECK: callq   {{_?}}bar
 ; CHECK: movb    [[OFS]](%rsp), %al
 

diff  --git a/llvm/test/CodeGen/X86/regalloc-tight-invoke.ll b/llvm/test/CodeGen/X86/regalloc-tight-invoke.ll
new file mode 100644
index 000000000000..5367ffb67100
--- /dev/null
+++ b/llvm/test/CodeGen/X86/regalloc-tight-invoke.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - | FileCheck %s
+declare void @foo(i32, ...)
+
+declare i32 @__gxx_personality_v0(...)
+
+; We were running out of registers for this invoke, because:
+
+;     1. The lshr/and pattern gets matched to a no-REX MOV so that ah/bh/... can
+;        be used instead, cutting available registers for %b.arg down to eax, ebx,
+;        ecx, edx, esi, edi.
+;     2. We have a base pointer taking ebx out of contention.
+;     3. The landingpad block convinced us we should be defining rax here.
+;     3. The al fiddling for the varargs call only noted down that al was spillable,
+;        not ah or hax.
+;
+; So by the time we need to allocate a register for the call all registers are
+; tied up and unspillable.
+
+; CHECK-LABEL: bar:
+; CHECK: xorl %edi, %edi
+; CHECK: movb %dil, {{[0-9]+}}(%rbx)
+; CHECK: movb {{[0-9]+}}(%rbx), %al
+define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d, ...) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+  %mem = alloca i32, i32 %a, align 32   ; Force rbx to be used as a base pointer
+  %b.tmp = lshr i32 %b, 8
+  %b.arg = and i32 %b.tmp, 255
+  invoke void(i32, ...) @foo(i32 42, i32* %mem, i32 %c, i32 %d, i32 %b.arg) to label %success unwind label %fail
+
+success:
+  ret i32 0
+fail:
+  %exc = landingpad { i8*, i32 } cleanup
+  %res = extractvalue { i8*, i32 } %exc, 1
+  ret i32 %res
+}


        


More information about the llvm-commits mailing list