[llvm] ba6bb69 - [RegAlloc] Fix register's live range for early-clobber (#152895)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 19 18:03:02 PDT 2025
Author: Luo, Yuanke
Date: 2025-08-20T09:02:59+08:00
New Revision: ba6bb6929e7eb934f86adb1a942d2d274d18b1dd
URL: https://github.com/llvm/llvm-project/commit/ba6bb6929e7eb934f86adb1a942d2d274d18b1dd
DIFF: https://github.com/llvm/llvm-project/commit/ba6bb6929e7eb934f86adb1a942d2d274d18b1dd.diff
LOG: [RegAlloc] Fix register's live range for early-clobber (#152895)
When rematerialize a virtual register the register may be early
clobbered.
However rematerializeAt(...) just return the slot index of Slot_Register
which cause mis-calculating live range for the register
---------
Co-authored-by: Yuanke Luo <ykluo at birentech.com>
Added:
llvm/test/CodeGen/X86/early-clobber.mir
Modified:
llvm/lib/CodeGen/LiveRangeEdit.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp
index a3858efbdc5e1..5514e4eb6cf3e 100644
--- a/llvm/lib/CodeGen/LiveRangeEdit.cpp
+++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp
@@ -190,9 +190,12 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB,
Rematted.insert(RM.ParentVNI);
++NumReMaterialization;
+ bool EarlyClobber = MI->getOperand(0).isEarlyClobber();
if (ReplaceIndexMI)
- return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI).getRegSlot();
- return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot();
+ return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI)
+ .getRegSlot(EarlyClobber);
+ return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot(
+ EarlyClobber);
}
void LiveRangeEdit::eraseVirtReg(Register Reg) {
diff --git a/llvm/test/CodeGen/X86/early-clobber.mir b/llvm/test/CodeGen/X86/early-clobber.mir
new file mode 100644
index 0000000000000..429331524d177
--- /dev/null
+++ b/llvm/test/CodeGen/X86/early-clobber.mir
@@ -0,0 +1,76 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=i386-unknown-linux-gnu -start-before=twoaddressinstruction -stop-after=postrapseudos -verify-machineinstrs -o - %s | FileCheck %s
+
+# Test register live range that is split from rematerializing. The live range should
+# start with Slot_EarlyClobber instead of Slot_Register. Machineverifer can check it.
+
+--- |
+
+ define void @test() nounwind {
+ ret void
+ }
+
+...
+---
+name: test
+alignment: 16
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 4
+fixedStack:
+ - { id: 0, size: 4, alignment: 16, isImmutable: true }
+machineFunctionInfo: {}
+body: |
+ ; CHECK-LABEL: name: test
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $ebp, $ebx, $edi, $esi
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: frame-setup PUSH32r killed $ebp, implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: frame-setup PUSH32r killed $ebx, implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: frame-setup PUSH32r killed $edi, implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: frame-setup PUSH32r killed $esi, implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: $esp = frame-setup SUB32ri $esp, 12, implicit-def dead $eflags
+ ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $ebp, 12 /* clobber */, implicit-def dead early-clobber $eax, 12 /* clobber */, implicit-def dead early-clobber $ebx, 12 /* clobber */, implicit-def dead early-clobber $ecx, 12 /* clobber */, implicit-def dead early-clobber $edx, 12 /* clobber */, implicit-def dead early-clobber $esi, 12 /* clobber */, implicit-def dead early-clobber $edi, 12 /* clobber */, implicit-def dead early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def dead early-clobber $eflags
+ ; CHECK-NEXT: early-clobber renamable $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
+ ; CHECK-NEXT: TEST8rr renamable $al, renamable $al, implicit-def $eflags
+ ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit $eflags
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.2(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $eax = MOV32ri 1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $esp = frame-destroy ADD32ri $esp, 12, implicit-def dead $eflags
+ ; CHECK-NEXT: $esi = frame-destroy POP32r implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: $edi = frame-destroy POP32r implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: $ebx = frame-destroy POP32r implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: $ebp = frame-destroy POP32r implicit-def $esp, implicit $esp
+ ; CHECK-NEXT: RET 0, $eax
+ bb.0:
+ successors: %bb.1, %bb.2
+
+ early-clobber %0:gr32_abcd = MOV32r0 implicit-def dead $eflags
+ INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $ebp, 12 /* clobber */, implicit-def dead early-clobber $eax, 12 /* clobber */, implicit-def dead early-clobber $ebx, 12 /* clobber */, implicit-def dead early-clobber $ecx, 12 /* clobber */, implicit-def dead early-clobber $edx, 12 /* clobber */, implicit-def dead early-clobber $esi, 12 /* clobber */, implicit-def dead early-clobber $edi, 12 /* clobber */, implicit-def dead early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def dead early-clobber $eflags
+ %4:gr8 = COPY %0.sub_8bit
+ TEST8rr killed %4, %4, implicit-def $eflags
+ JCC_1 %bb.2, 5, implicit killed $eflags
+ JMP_1 %bb.1
+
+ bb.1:
+ %1:gr32 = MOV32ri 1
+ %5:gr32 = COPY killed %1
+ JMP_1 %bb.3
+
+ bb.2:
+ %5:gr32 = COPY killed %0
+
+ bb.3:
+ %3:gr32 = COPY killed %5
+ $eax = COPY killed %3
+ RET 0, killed $eax
+
+...
More information about the llvm-commits
mailing list