[llvm] b1295dd - RegisterCoalescer: Handle implicit-def of a super register when rematerializing
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 2 03:11:33 PDT 2023
Author: Matt Arsenault
Date: 2023-10-02T13:11:22+03:00
New Revision: b1295dd5c923c6828775406b4063de1531fd4782
URL: https://github.com/llvm/llvm-project/commit/b1295dd5c923c6828775406b4063de1531fd4782
DIFF: https://github.com/llvm/llvm-project/commit/b1295dd5c923c6828775406b4063de1531fd4782.diff
LOG: RegisterCoalescer: Handle implicit-def of a super register when rematerializing
Permit an implicit-def of a virtual register when rematerializing if
it defines a super register of a subregister def. The
rematerialization pre-legality check should really have been checking
the implicit operands, but that should be fixed separately.
https://reviews.llvm.org/D156331
Added:
Modified:
llvm/lib/CodeGen/RegisterCoalescer.cpp
llvm/test/CodeGen/X86/rematerialize-sub-super-reg.mir
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 516095a699ea1e8..d6a584d0579139b 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -1317,6 +1317,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
if (SrcIdx && DstIdx)
return false;
+ const unsigned DefSubIdx = DefMI->getOperand(0).getSubReg();
const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF);
if (!DefMI->isImplicitDef()) {
if (DstReg.isPhysical()) {
@@ -1396,7 +1397,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
MachineOperand &MO = CopyMI->getOperand(I);
if (MO.isReg()) {
assert(MO.isImplicit() && "No explicit operands after implicit operands.");
- assert(MO.getReg().isPhysical() && "unexpected implicit virtual register def");
+ assert((MO.getReg().isPhysical() ||
+ (MO.getSubReg() == 0 && MO.getReg() == DstOperand.getReg())) &&
+ "unexpected implicit virtual register def");
ImplicitOps.push_back(MO);
}
}
@@ -1407,14 +1410,37 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
// NewMI may have dead implicit defs (E.g. EFLAGS for MOV<bits>r0 on X86).
// We need to remember these so we can add intervals once we insert
// NewMI into SlotIndexes.
+ //
+ // We also expect to have tied implicit-defs of super registers originating
+ // from SUBREG_TO_REG, such as:
+ // $edi = MOV32r0 implicit-def dead $eflags, implicit-def $rdi
+ // undef %0.sub_32bit = MOV32r0 implicit-def dead $eflags, implicit-def %0
+
SmallVector<MCRegister, 4> NewMIImplDefs;
for (unsigned i = NewMI.getDesc().getNumOperands(),
e = NewMI.getNumOperands();
i != e; ++i) {
MachineOperand &MO = NewMI.getOperand(i);
if (MO.isReg() && MO.isDef()) {
- assert(MO.isImplicit() && MO.isDead() && MO.getReg().isPhysical());
- NewMIImplDefs.push_back(MO.getReg().asMCReg());
+ assert(MO.isImplicit());
+ if (MO.getReg().isPhysical()) {
+ assert(MO.isImplicit() && MO.getReg().isPhysical() &&
+ (MO.isDead() ||
+ (DefSubIdx && (TRI->getSubReg(MO.getReg(), DefSubIdx) ==
+ MCRegister(NewMI.getOperand(0).getReg())))));
+ NewMIImplDefs.push_back(MO.getReg().asMCReg());
+ } else {
+ assert(MO.getReg() == NewMI.getOperand(0).getReg() &&
+ MO.getSubReg() == 0);
+ // We're only expecting another def of the main output, so the range
+ // should get updated with the regular output range.
+ //
+ // FIXME: The range updating below probably needs updating to look at
+ // the super register if subranges are tracked.
+ assert(!MRI->shouldTrackSubRegLiveness(DstReg) &&
+ "subrange update for implicit-def of super register may not be "
+ "properly handled");
+ }
}
}
diff --git a/llvm/test/CodeGen/X86/rematerialize-sub-super-reg.mir b/llvm/test/CodeGen/X86/rematerialize-sub-super-reg.mir
index b6be21f5f85c78b..a8b957d4562ab1c 100644
--- a/llvm/test/CodeGen/X86/rematerialize-sub-super-reg.mir
+++ b/llvm/test/CodeGen/X86/rematerialize-sub-super-reg.mir
@@ -114,30 +114,58 @@ body: |
...
-# FIXME: This currently asserts
-# ---
-# name: rematerialize_subregister_into_superreg_def_with_impdef_physreg
-# tracksRegLiveness: true
-# body: |
-# bb.0:
-# undef %t1.sub_32bit:gr64_with_sub_8bit = MOV32ri -11, implicit-def %t1
-# CMP64ri8 %t1, 1, implicit-def $eflags
-# JCC_1 %bb.2, 4, implicit killed $eflags
-# JMP_1 %bb.1
-
-# bb.1:
-# %t2:gr64 = COPY %t1
-# $rax = COPY %t2
-# CMP64ri8 %t2, 1, implicit-def $eflags
-# JCC_1 %bb.1, 4, implicit killed $eflags
-# RET 0, $rax
-
-# bb.2:
-# %t3:gr64 = COPY %t1
-# %t3:gr64 = ADD64ri8 %t3, 10, implicit-def $eflags
-
-# bb.3:
-# $rax = COPY %t3
-# RET 0, $rax
-
-# ...
+# Handle that rematerializing an instruction with an implicit def of a
+# virtual super register into a physical register works.
+#
+# FIXME: Resulting rematerializing has a redundant implicit-def
+---
+name: rematerialize_subregister_into_superreg_def_with_impdef_physreg
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: rematerialize_subregister_into_superreg_def_with_impdef_physreg
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: undef %t3.sub_32bit:gr64_with_sub_8bit = MOV32ri -11, implicit-def %t3
+ ; CHECK-NEXT: CMP64ri8 %t3, 1, implicit-def $eflags
+ ; CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags
+ ; CHECK-NEXT: JMP_1 %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.1(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: dead $eax = MOV32ri -11, implicit-def $rax, implicit-def $rax
+ ; CHECK-NEXT: CMP64ri8 %t3, 1, implicit-def $eflags
+ ; CHECK-NEXT: JCC_1 %bb.1, 4, implicit killed $eflags
+ ; CHECK-NEXT: RET 0, $rax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %t3:gr64_with_sub_8bit = ADD64ri8 %t3, 10, implicit-def $eflags
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3:
+ ; CHECK-NEXT: $rax = COPY %t3
+ ; CHECK-NEXT: RET 0, $rax
+ bb.0:
+ undef %t1.sub_32bit:gr64_with_sub_8bit = MOV32ri -11, implicit-def %t1
+ CMP64ri8 %t1, 1, implicit-def $eflags
+ JCC_1 %bb.2, 4, implicit killed $eflags
+ JMP_1 %bb.1
+
+ bb.1:
+ %t2:gr64 = COPY %t1
+ $rax = COPY %t2
+ CMP64ri8 %t2, 1, implicit-def $eflags
+ JCC_1 %bb.1, 4, implicit killed $eflags
+ RET 0, $rax
+
+ bb.2:
+ %t3:gr64 = COPY %t1
+ %t3:gr64 = ADD64ri8 %t3, 10, implicit-def $eflags
+
+ bb.3:
+ $rax = COPY %t3
+ RET 0, $rax
+
+...
More information about the llvm-commits
mailing list