@@ -101,6 +101,60 @@ bool LiveRangeEdit::anyRematerializable() {
101101 return !Remattable.empty ();
102102}
103103
104+ // / allUsesAvailableAt - Return true if all registers used by OrigMI at
105+ // / OrigIdx are also available with the same value at UseIdx.
106+ bool LiveRangeEdit::allUsesAvailableAt (const MachineInstr *OrigMI,
107+ SlotIndex OrigIdx,
108+ SlotIndex UseIdx) const {
109+ OrigIdx = OrigIdx.getRegSlot (true );
110+ UseIdx = std::max (UseIdx, UseIdx.getRegSlot (true ));
111+ for (const MachineOperand &MO : OrigMI->operands ()) {
112+ if (!MO.isReg () || !MO.getReg () || !MO.readsReg ())
113+ continue ;
114+
115+ // We can't remat physreg uses, unless it is a constant or target wants
116+ // to ignore this use.
117+ if (MO.getReg ().isPhysical ()) {
118+ if (MRI.isConstantPhysReg (MO.getReg ()) || TII.isIgnorableUse (MO))
119+ continue ;
120+ return false ;
121+ }
122+
123+ LiveInterval &li = LIS.getInterval (MO.getReg ());
124+ const VNInfo *OVNI = li.getVNInfoAt (OrigIdx);
125+ if (!OVNI)
126+ continue ;
127+
128+ // Don't allow rematerialization immediately after the original def.
129+ // It would be incorrect if OrigMI redefines the register.
130+ // See PR14098.
131+ if (SlotIndex::isSameInstr (OrigIdx, UseIdx))
132+ return false ;
133+
134+ if (OVNI != li.getVNInfoAt (UseIdx))
135+ return false ;
136+
137+ // Check that subrange is live at UseIdx.
138+ if (li.hasSubRanges ()) {
139+ const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo ();
140+ unsigned SubReg = MO.getSubReg ();
141+ LaneBitmask LM = SubReg ? TRI->getSubRegIndexLaneMask (SubReg)
142+ : MRI.getMaxLaneMaskForVReg (MO.getReg ());
143+ for (LiveInterval::SubRange &SR : li.subranges ()) {
144+ if ((SR.LaneMask & LM).none ())
145+ continue ;
146+ if (!SR.liveAt (UseIdx))
147+ return false ;
148+ // Early exit if all used lanes are checked. No need to continue.
149+ LM &= ~SR.LaneMask ;
150+ if (LM.none ())
151+ break ;
152+ }
153+ }
154+ }
155+ return true ;
156+ }
157+
104158bool LiveRangeEdit::canRematerializeAt (Remat &RM, VNInfo *OrigVNI,
105159 SlotIndex UseIdx) {
106160 assert (ScannedRemattable && " Call anyRematerializable first" );
@@ -110,10 +164,12 @@ bool LiveRangeEdit::canRematerializeAt(Remat &RM, VNInfo *OrigVNI,
110164 return false ;
111165
112166 // No defining instruction provided.
167+ SlotIndex DefIdx;
113168 assert (RM.OrigMI && " No defining instruction for remattable value" );
169+ DefIdx = LIS.getInstructionIndex (*RM.OrigMI );
114170
115171 // Verify that all used registers are available with the same values.
116- if (!LIS. allUsesAvailableAt (* RM.OrigMI , UseIdx))
172+ if (!allUsesAvailableAt (RM.OrigMI , DefIdx , UseIdx))
117173 return false ;
118174
119175 return true ;
@@ -174,7 +230,8 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
174230
175231 // Since we're moving the DefMI load, make sure we're not extending any live
176232 // ranges.
177- if (!LIS.allUsesAvailableAt (*DefMI, LIS.getInstructionIndex (*UseMI)))
233+ if (!allUsesAvailableAt (DefMI, LIS.getInstructionIndex (*DefMI),
234+ LIS.getInstructionIndex (*UseMI)))
178235 return false ;
179236
180237 // We also need to make sure it is safe to move the load.
0 commit comments