@@ -305,7 +305,11 @@ namespace {
305
305
// / number if it is not zero. If DstReg is a physical register and the
306
306
// / existing subregister number of the def / use being updated is not zero,
307
307
// / make sure to set it to the correct physical subregister.
308
- void updateRegDefsUses (Register SrcReg, Register DstReg, unsigned SubIdx);
308
+ // /
309
+ // / If \p IsSubregToReg, we are coalescing a DstReg = SUBREG_TO_REG
310
+ // / SrcReg. This introduces an implicit-def of DstReg on coalesced users.
311
+ void updateRegDefsUses (Register SrcReg, Register DstReg, unsigned SubIdx,
312
+ bool IsSubregToReg);
309
313
310
314
// / If the given machine operand reads only undefined lanes add an undef
311
315
// / flag.
@@ -1323,8 +1327,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
1323
1327
if (DstReg.isPhysical ()) {
1324
1328
Register NewDstReg = DstReg;
1325
1329
1326
- unsigned NewDstIdx = TRI->composeSubRegIndices (CP.getSrcIdx (),
1327
- DefMI->getOperand (0 ).getSubReg ());
1330
+ unsigned NewDstIdx = TRI->composeSubRegIndices (CP.getSrcIdx (), DefSubIdx);
1328
1331
if (NewDstIdx)
1329
1332
NewDstReg = TRI->getSubReg (DstReg, NewDstIdx);
1330
1333
@@ -1473,7 +1476,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
1473
1476
MRI->setRegClass (DstReg, NewRC);
1474
1477
1475
1478
// Update machine operands and add flags.
1476
- updateRegDefsUses (DstReg, DstReg, DstIdx);
1479
+ updateRegDefsUses (DstReg, DstReg, DstIdx, false );
1477
1480
NewMI.getOperand (0 ).setSubReg (NewIdx);
1478
1481
// updateRegDefUses can add an "undef" flag to the definition, since
1479
1482
// it will replace DstReg with DstReg.DstIdx. If NewIdx is 0, make
@@ -1788,7 +1791,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
1788
1791
}
1789
1792
1790
1793
void RegisterCoalescer::updateRegDefsUses (Register SrcReg, Register DstReg,
1791
- unsigned SubIdx) {
1794
+ unsigned SubIdx, bool IsSubregToReg ) {
1792
1795
bool DstIsPhys = DstReg.isPhysical ();
1793
1796
LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval (DstReg);
1794
1797
@@ -1828,16 +1831,22 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
1828
1831
if (DstInt && !Reads && SubIdx && !UseMI->isDebugInstr ())
1829
1832
Reads = DstInt->liveAt (LIS->getInstructionIndex (*UseMI));
1830
1833
1834
+ bool FullDef = true ;
1835
+
1831
1836
// Replace SrcReg with DstReg in all UseMI operands.
1832
1837
for (unsigned i = 0 , e = Ops.size (); i != e; ++i) {
1833
1838
MachineOperand &MO = UseMI->getOperand (Ops[i]);
1834
1839
1835
1840
// Adjust <undef> flags in case of sub-register joins. We don't want to
1836
1841
// turn a full def into a read-modify-write sub-register def and vice
1837
1842
// versa.
1838
- if (SubIdx && MO.isDef ())
1843
+ if (SubIdx && MO.isDef ()) {
1839
1844
MO.setIsUndef (!Reads);
1840
1845
1846
+ if (!Reads)
1847
+ FullDef = false ;
1848
+ }
1849
+
1841
1850
// A subreg use of a partially undef (super) register may be a complete
1842
1851
// undef use now and then has to be marked that way.
1843
1852
if (MO.isUse () && !DstIsPhys) {
@@ -1869,6 +1878,25 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
1869
1878
MO.substVirtReg (DstReg, SubIdx, *TRI);
1870
1879
}
1871
1880
1881
+ if (IsSubregToReg && !FullDef) {
1882
+ // If the coalesed instruction doesn't fully define the register, we need
1883
+ // to preserve the original super register liveness for SUBREG_TO_REG.
1884
+ //
1885
+ // We pretended SUBREG_TO_REG was a regular copy for coalescing purposes,
1886
+ // but it introduces liveness for other subregisters. Downstream users may
1887
+ // have been relying on those bits, so we need to ensure their liveness is
1888
+ // captured with a def of other lanes.
1889
+
1890
+ // FIXME: Need to add new subrange if tracking subranges. We could also
1891
+ // skip adding this if we knew the other lanes are dead, and only for
1892
+ // other lanes.
1893
+
1894
+ assert (!MRI->shouldTrackSubRegLiveness (DstReg) &&
1895
+ " this should update subranges" );
1896
+ MachineInstrBuilder MIB (*MF, UseMI);
1897
+ MIB.addReg (DstReg, RegState::ImplicitDefine);
1898
+ }
1899
+
1872
1900
LLVM_DEBUG ({
1873
1901
dbgs () << " \t\t updated: " ;
1874
1902
if (!UseMI->isDebugInstr ())
@@ -2068,6 +2096,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
2068
2096
});
2069
2097
}
2070
2098
2099
+ const bool IsSubregToReg = CopyMI->isSubregToReg ();
2100
+
2071
2101
ShrinkMask = LaneBitmask::getNone ();
2072
2102
ShrinkMainRange = false ;
2073
2103
@@ -2135,9 +2165,12 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
2135
2165
2136
2166
// Rewrite all SrcReg operands to DstReg.
2137
2167
// Also update DstReg operands to include DstIdx if it is set.
2138
- if (CP.getDstIdx ())
2139
- updateRegDefsUses (CP.getDstReg (), CP.getDstReg (), CP.getDstIdx ());
2140
- updateRegDefsUses (CP.getSrcReg (), CP.getDstReg (), CP.getSrcIdx ());
2168
+ if (CP.getDstIdx ()) {
2169
+ assert (!IsSubregToReg && " can this happen?" );
2170
+ updateRegDefsUses (CP.getDstReg (), CP.getDstReg (), CP.getDstIdx (), false );
2171
+ }
2172
+ updateRegDefsUses (CP.getSrcReg (), CP.getDstReg (), CP.getSrcIdx (),
2173
+ IsSubregToReg);
2141
2174
2142
2175
// Shrink subregister ranges if necessary.
2143
2176
if (ShrinkMask.any ()) {
0 commit comments