[llvm] [RegAlloc] Fix the live range for early-clobber (PR #152895)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 17 01:14:30 PDT 2025
https://github.com/LuoYuanke updated https://github.com/llvm/llvm-project/pull/152895
>From 7baf18957d84d47479da1acf3997dc2cfb1272b8 Mon Sep 17 00:00:00 2001
From: Yuanke Luo <ykluo at birentech.com>
Date: Sun, 10 Aug 2025 10:40:51 +0800
Subject: [PATCH] [RegAlloc] Fix register's live range for early-clobber
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
---
llvm/lib/CodeGen/LiveRangeEdit.cpp | 7 ++-
llvm/test/CodeGen/X86/early-clobber.mir | 75 +++++++++++++++++++++++++
2 files changed, 80 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/early-clobber.mir
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp
index a3858efbdc5e1..0bd9b0dad740d 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(EearlyClobber);
+ 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..27c83d2a68c95
--- /dev/null
+++ b/llvm/test/CodeGen/X86/early-clobber.mir
@@ -0,0 +1,75 @@
+# RUN: llc -mtriple=i386-unknown-linux-gnu -start-before=twoaddressinstruction -verify-machineinstrs -o - %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.
+
+--- |
+ target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"
+ target triple = "i386-unknown-linux-gnu"
+
+ @g = external constant [2 x i32], align 4
+
+ ; Function Attrs: nounwind
+ define i32 @test(i32 noundef %a) #0 {
+ entry:
+ %0 = xor i32 %a, %a
+ tail call void asm sideeffect "", "~{ebp},~{eax},~{ebx},~{ecx},~{edx},~{esi},~{edi},~{dirflag},~{fpsr},~{flags}"()
+ br i1 undef, label %if, label %else
+
+ if: ; preds = %entry
+ %add = add i32 %0, 1
+ br label %exit
+
+ else: ; preds = %entry
+ %shl = shl i32 %0, 1
+ br label %exit
+
+ exit: ; preds = %else, %if
+ %phi = phi i32 [ %add, %if ], [ %shl, %else ]
+ ret i32 %phi
+ }
+
+ attributes #0 = { nounwind }
+
+...
+---
+name: test
+alignment: 16
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gr32_abcd }
+ - { id: 1, class: gr32 }
+ - { id: 2, class: gr32 }
+ - { id: 3, class: gr32 }
+ - { id: 4, class: gr8 }
+ - { id: 5, class: gr32 }
+frameInfo:
+ maxAlignment: 4
+fixedStack:
+ - { id: 0, size: 4, alignment: 16, isImmutable: true }
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ 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.if:
+ %1:gr32 = MOV32ri 1
+ %5:gr32 = COPY killed %1
+ JMP_1 %bb.3
+
+ bb.2.else:
+ %5:gr32 = COPY killed %0
+
+ bb.3.exit:
+ %3:gr32 = COPY killed %5
+ $eax = COPY killed %3
+ RET 0, killed $eax
+
+...
More information about the llvm-commits
mailing list