@@ -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.
@@ -1343,8 +1347,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
1343
1347
if (DstReg.isPhysical ()) {
1344
1348
Register NewDstReg = DstReg;
1345
1349
1346
- unsigned NewDstIdx = TRI->composeSubRegIndices (CP.getSrcIdx (),
1347
- DefMI->getOperand (0 ).getSubReg ());
1350
+ unsigned NewDstIdx = TRI->composeSubRegIndices (CP.getSrcIdx (), DefSubIdx);
1348
1351
if (NewDstIdx)
1349
1352
NewDstReg = TRI->getSubReg (DstReg, NewDstIdx);
1350
1353
@@ -1493,7 +1496,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
1493
1496
MRI->setRegClass (DstReg, NewRC);
1494
1497
1495
1498
// Update machine operands and add flags.
1496
- updateRegDefsUses (DstReg, DstReg, DstIdx);
1499
+ updateRegDefsUses (DstReg, DstReg, DstIdx, false );
1497
1500
NewMI.getOperand (0 ).setSubReg (NewIdx);
1498
1501
// updateRegDefUses can add an "undef" flag to the definition, since
1499
1502
// it will replace DstReg with DstReg.DstIdx. If NewIdx is 0, make
@@ -1814,7 +1817,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
1814
1817
}
1815
1818
1816
1819
void RegisterCoalescer::updateRegDefsUses (Register SrcReg, Register DstReg,
1817
- unsigned SubIdx) {
1820
+ unsigned SubIdx, bool IsSubregToReg ) {
1818
1821
bool DstIsPhys = DstReg.isPhysical ();
1819
1822
LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval (DstReg);
1820
1823
@@ -1854,16 +1857,22 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
1854
1857
if (DstInt && !Reads && SubIdx && !UseMI->isDebugInstr ())
1855
1858
Reads = DstInt->liveAt (LIS->getInstructionIndex (*UseMI));
1856
1859
1860
+ bool FullDef = true ;
1861
+
1857
1862
// Replace SrcReg with DstReg in all UseMI operands.
1858
1863
for (unsigned i = 0 , e = Ops.size (); i != e; ++i) {
1859
1864
MachineOperand &MO = UseMI->getOperand (Ops[i]);
1860
1865
1861
1866
// Adjust <undef> flags in case of sub-register joins. We don't want to
1862
1867
// turn a full def into a read-modify-write sub-register def and vice
1863
1868
// versa.
1864
- if (SubIdx && MO.isDef ())
1869
+ if (SubIdx && MO.isDef ()) {
1865
1870
MO.setIsUndef (!Reads);
1866
1871
1872
+ if (!Reads)
1873
+ FullDef = false ;
1874
+ }
1875
+
1867
1876
// A subreg use of a partially undef (super) register may be a complete
1868
1877
// undef use now and then has to be marked that way.
1869
1878
if (MO.isUse () && !DstIsPhys) {
@@ -1895,6 +1904,25 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
1895
1904
MO.substVirtReg (DstReg, SubIdx, *TRI);
1896
1905
}
1897
1906
1907
+ if (IsSubregToReg && !FullDef) {
1908
+ // If the coalesed instruction doesn't fully define the register, we need
1909
+ // to preserve the original super register liveness for SUBREG_TO_REG.
1910
+ //
1911
+ // We pretended SUBREG_TO_REG was a regular copy for coalescing purposes,
1912
+ // but it introduces liveness for other subregisters. Downstream users may
1913
+ // have been relying on those bits, so we need to ensure their liveness is
1914
+ // captured with a def of other lanes.
1915
+
1916
+ // FIXME: Need to add new subrange if tracking subranges. We could also
1917
+ // skip adding this if we knew the other lanes are dead, and only for
1918
+ // other lanes.
1919
+
1920
+ assert (!MRI->shouldTrackSubRegLiveness (DstReg) &&
1921
+ " this should update subranges" );
1922
+ MachineInstrBuilder MIB (*MF, UseMI);
1923
+ MIB.addReg (DstReg, RegState::ImplicitDefine);
1924
+ }
1925
+
1898
1926
LLVM_DEBUG ({
1899
1927
dbgs () << " \t\t updated: " ;
1900
1928
if (!UseMI->isDebugInstr ())
@@ -2094,6 +2122,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
2094
2122
});
2095
2123
}
2096
2124
2125
+ const bool IsSubregToReg = CopyMI->isSubregToReg ();
2126
+
2097
2127
ShrinkMask = LaneBitmask::getNone ();
2098
2128
ShrinkMainRange = false ;
2099
2129
@@ -2161,9 +2191,12 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
2161
2191
2162
2192
// Rewrite all SrcReg operands to DstReg.
2163
2193
// Also update DstReg operands to include DstIdx if it is set.
2164
- if (CP.getDstIdx ())
2165
- updateRegDefsUses (CP.getDstReg (), CP.getDstReg (), CP.getDstIdx ());
2166
- updateRegDefsUses (CP.getSrcReg (), CP.getDstReg (), CP.getSrcIdx ());
2194
+ if (CP.getDstIdx ()) {
2195
+ assert (!IsSubregToReg && " can this happen?" );
2196
+ updateRegDefsUses (CP.getDstReg (), CP.getDstReg (), CP.getDstIdx (), false );
2197
+ }
2198
+ updateRegDefsUses (CP.getSrcReg (), CP.getDstReg (), CP.getSrcIdx (),
2199
+ IsSubregToReg);
2167
2200
2168
2201
// Shrink subregister ranges if necessary.
2169
2202
if (ShrinkMask.any ()) {
0 commit comments