Skip to content

Commit 19d65fb

Browse files
arsenmsdesmalen-arm
authored andcommitted
Reapply "RegisterCoalescer: Add implicit-def of super register when coalescing SUBREG_TO_REG"
This reverts commit c398fa0. PPC backend was fixed in 2f82662
1 parent fcec875 commit 19d65fb

6 files changed

+693
-55
lines changed

llvm/lib/CodeGen/RegisterCoalescer.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,11 @@ namespace {
306306
/// number if it is not zero. If DstReg is a physical register and the
307307
/// existing subregister number of the def / use being updated is not zero,
308308
/// make sure to set it to the correct physical subregister.
309-
void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx);
309+
///
310+
/// If \p IsSubregToReg, we are coalescing a DstReg = SUBREG_TO_REG
311+
/// SrcReg. This introduces an implicit-def of DstReg on coalesced users.
312+
void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx,
313+
bool IsSubregToReg);
310314

311315
/// If the given machine operand reads only undefined lanes add an undef
312316
/// flag.
@@ -1516,7 +1520,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
15161520
MRI->setRegClass(DstReg, NewRC);
15171521

15181522
// Update machine operands and add flags.
1519-
updateRegDefsUses(DstReg, DstReg, DstIdx);
1523+
updateRegDefsUses(DstReg, DstReg, DstIdx, false);
15201524
NewMI.getOperand(0).setSubReg(NewIdx);
15211525
// updateRegDefUses can add an "undef" flag to the definition, since
15221526
// it will replace DstReg with DstReg.DstIdx. If NewIdx is 0, make
@@ -1857,7 +1861,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
18571861
}
18581862

18591863
void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
1860-
unsigned SubIdx) {
1864+
unsigned SubIdx, bool IsSubregToReg) {
18611865
bool DstIsPhys = DstReg.isPhysical();
18621866
LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval(DstReg);
18631867

@@ -1900,16 +1904,22 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
19001904
if (DstInt && !Reads && SubIdx && !UseMI->isDebugInstr())
19011905
Reads = DstInt->liveAt(LIS->getInstructionIndex(*UseMI));
19021906

1907+
bool FullDef = true;
1908+
19031909
// Replace SrcReg with DstReg in all UseMI operands.
19041910
for (unsigned Op : Ops) {
19051911
MachineOperand &MO = UseMI->getOperand(Op);
19061912

19071913
// Adjust <undef> flags in case of sub-register joins. We don't want to
19081914
// turn a full def into a read-modify-write sub-register def and vice
19091915
// versa.
1910-
if (SubIdx && MO.isDef())
1916+
if (SubIdx && MO.isDef()) {
19111917
MO.setIsUndef(!Reads);
19121918

1919+
if (!Reads)
1920+
FullDef = false;
1921+
}
1922+
19131923
// A subreg use of a partially undef (super) register may be a complete
19141924
// undef use now and then has to be marked that way.
19151925
if (MO.isUse() && !MO.isUndef() && !DstIsPhys) {
@@ -1941,6 +1951,25 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
19411951
MO.substVirtReg(DstReg, SubIdx, *TRI);
19421952
}
19431953

1954+
if (IsSubregToReg && !FullDef) {
1955+
// If the coalesed instruction doesn't fully define the register, we need
1956+
// to preserve the original super register liveness for SUBREG_TO_REG.
1957+
//
1958+
// We pretended SUBREG_TO_REG was a regular copy for coalescing purposes,
1959+
// but it introduces liveness for other subregisters. Downstream users may
1960+
// have been relying on those bits, so we need to ensure their liveness is
1961+
// captured with a def of other lanes.
1962+
1963+
// FIXME: Need to add new subrange if tracking subranges. We could also
1964+
// skip adding this if we knew the other lanes are dead, and only for
1965+
// other lanes.
1966+
1967+
assert(!MRI->shouldTrackSubRegLiveness(DstReg) &&
1968+
"this should update subranges");
1969+
MachineInstrBuilder MIB(*MF, UseMI);
1970+
MIB.addReg(DstReg, RegState::ImplicitDefine);
1971+
}
1972+
19441973
LLVM_DEBUG({
19451974
dbgs() << "\t\tupdated: ";
19461975
if (!UseMI->isDebugInstr())
@@ -2142,6 +2171,8 @@ bool RegisterCoalescer::joinCopy(
21422171
});
21432172
}
21442173

2174+
const bool IsSubregToReg = CopyMI->isSubregToReg();
2175+
21452176
ShrinkMask = LaneBitmask::getNone();
21462177
ShrinkMainRange = false;
21472178

@@ -2211,9 +2242,12 @@ bool RegisterCoalescer::joinCopy(
22112242

22122243
// Rewrite all SrcReg operands to DstReg.
22132244
// Also update DstReg operands to include DstIdx if it is set.
2214-
if (CP.getDstIdx())
2215-
updateRegDefsUses(CP.getDstReg(), CP.getDstReg(), CP.getDstIdx());
2216-
updateRegDefsUses(CP.getSrcReg(), CP.getDstReg(), CP.getSrcIdx());
2245+
if (CP.getDstIdx()) {
2246+
assert(!IsSubregToReg && "can this happen?");
2247+
updateRegDefsUses(CP.getDstReg(), CP.getDstReg(), CP.getDstIdx(), false);
2248+
}
2249+
updateRegDefsUses(CP.getSrcReg(), CP.getDstReg(), CP.getSrcIdx(),
2250+
IsSubregToReg);
22172251

22182252
// Shrink subregister ranges if necessary.
22192253
if (ShrinkMask.any()) {

0 commit comments

Comments
 (0)