@@ -136,6 +136,7 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB,
136136 SmallSetVector<Register, 8 > ExternUses;
137137 SmallSet<Register, 8 > KilledUseSet;
138138 SmallSet<Register, 8 > UndefUseSet;
139+ SmallVector<std::pair<Register, Register>> TiedOperands;
139140 for (auto MII = FirstMI; MII != LastMI; ++MII) {
140141 // Debug instructions have no effects to track.
141142 if (MII->isDebugInstr ())
@@ -161,6 +162,15 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB,
161162 // External def is now killed.
162163 KilledUseSet.insert (Reg);
163164 }
165+ if (MO.isTied () && Reg.isVirtual ()) {
166+ // Record tied operand constraints that involve virtual registers so
167+ // that bundles that are formed pre-register allocation reflect the
168+ // relevant constraints.
169+ unsigned TiedIdx = MII->findTiedOperandIdx (MO.getOperandNo ());
170+ MachineOperand &TiedMO = MII->getOperand (TiedIdx);
171+ Register DefReg = TiedMO.getReg ();
172+ TiedOperands.emplace_back (DefReg, Reg);
173+ }
164174 }
165175 }
166176
@@ -203,7 +213,17 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB,
203213 bool isKill = KilledUseSet.contains (Reg);
204214 bool isUndef = UndefUseSet.contains (Reg);
205215 MIB.addReg (Reg, getKillRegState (isKill) | getUndefRegState (isUndef) |
206- getImplRegState (true ));
216+ getImplRegState (true ));
217+ }
218+
219+ for (auto [DefReg, UseReg] : TiedOperands) {
220+ unsigned DefIdx =
221+ std::distance (LocalDefs.begin (), llvm::find (LocalDefs, DefReg));
222+ unsigned UseIdx =
223+ std::distance (ExternUses.begin (), llvm::find (ExternUses, UseReg));
224+ assert (DefIdx < LocalDefs.size ());
225+ assert (UseIdx < ExternUses.size ());
226+ MIB->tieOperands (DefIdx, LocalDefs.size () + UseIdx);
207227 }
208228}
209229
0 commit comments