Replacing an instruction in a post-RA pass

I’m writing a pass that looks at the operands of certain non-commutable instructions and swaps a couple of them if certain conditions exist (a register bank conflict in the instruction). If the conflict exists, I build a new instruction which has the 2nd and 3rd operands swapped (using BuildMI). Then I want to get rid of the original instruction. I had done some searching and found that eraseFromParent is used to do this so that’s what I’m using in the code below:

for (MachineFunction::iterator MFI = MF.begin(), E = MF.end();
MFI != E; ++MFI) {
// for each instr
MachineBasicBlock::instr_iterator II = MFI->instr_begin();
while( II != MFI->instr_end()) {
opcode = II->getOpcode();
if(II->isCommutable() || isLoadRR(opcode)){
MachineBasicBlock& MBB = *MFI;
MachineInstr& MI = *II;
DebugLoc DL = MI.getDebugLoc();

MachineOperand& reg1 = MI.getOperand(0);
MachineOperand& reg2 = MI.getOperand(1);
MachineOperand& reg3 = MI.getOperand(2);
if(reg1.isReg() && reg2.isReg() && reg3.isReg()){
if((reg1.getReg()-8)%4 == (reg3.getReg()-8)%4){
MachineBasicBlock::instr_iterator NII = std::next(II);
//conflict if reg1 and reg3 are in same bank
errs() << "Conflict: “;
errs() << " has " << num_operands << " register operands:\n”;
errs() << " r1: " << (reg1.getReg()-8) << " r2: " << (reg2.getReg()-8)
<< " r3: " << (reg3.getReg()-8) << “\n”;
//build the swapped version
BuildMI(MBB, II, DL, TII.get(opcode),reg1.getReg()).addReg(reg3.getReg()).addReg(reg2.getReg());

Unfortunately, this leads to a segfault. Is this the proper way to do this or is there another suggested way of doing it?


What if II is the last instruction?


Ah, yes, thank you very much for that hint.