I'm writing an LLVM machine function pass that need to insert some instructions at the start of each basic block. What those instructions do is that it load a value from a place and compare it with a number, then jump to a basic block if the previous comparison is not equal, thus I'm trying to insert a instruction JNE jump not equal, but I couldn't get it to work.
Here's my code
void SomeFunction(llvm::MachineFunction &MF) {
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
// MachineRegisterInfo &MRI = MF.getRegInfo();
MachineBasicBlock *TrueBB = MF.CreateMachineBasicBlock();
MF.insert(MF.end(),TrueBB);
// get the false basic block ready
// this is stored at the end of the function that if in the previous block, if any of the jne actually jump into this block, it should terminate
// Location testing
llvm::BuildMI(*TrueBB, TrueBB->begin(), TrueBB->begin()->getDebugLoc(), TII->get(X86::MOV64mr))
.addReg(X86::RAX) // Base register for the destination address
.addImm(1) // Scale factor
.addReg(0) // Index register, none in this case
.addImm(0) // Displacement
.addReg(0) // Segment register, not used here
.addImm(0); // Immediate value to store
llvm::BuildMI(*TrueBB, TrueBB->begin(), TrueBB->begin()->getDebugLoc(), TII->get(X86::MOV64ri), X86::RAX).addImm(0);
llvm::BuildMI(*TrueBB, TrueBB->begin(), TrueBB->begin()->getDebugLoc(), TII->get(X86::NOOP));
// then for other basic blocks that are not the first and last
for (llvm::MachineFunction::iterator MBBItr = MF.begin(), MBBEnd = MF.end(); MBBItr != MBBEnd; MBBItr++){
llvm::MachineBasicBlock &MBB = *MBBItr;
if (&MBB != &MF.front() && &MBB != &MF.front()) {
MachineBasicBlock::iterator FirstMI = MBB.begin();
DebugLoc DL = FirstMI->getDebugLoc();
// Location indicator for debug purpose
BuildMI(MBB, FirstMI, DL, TII->get(X86::NOOP));
// Both way works
// Firstly load value from address stored in R14
// addRegOffset(llvm::BuildMI(MBB, FirstMI, DL, TII->get(llvm::X86::MOV64rm),llvm::X86::RAX),
// llvm::X86::R14, false, 0);
llvm::BuildMI(MBB, FirstMI, DL, TII->get(llvm::X86::MOV64rm),llvm::X86::RAX)
.addReg(llvm::X86::R14)
.addImm(1)
.addReg(llvm::X86::NoRegister)
.addImm(0)
.addReg(llvm::X86::NoRegister);
// Then Compare it with our value
llvm::BuildMI(MBB,FirstMI,DL,TII->get(llvm::X86::CMP64ri32))
.addReg(llvm::X86::RAX)
.addImm(0x11111111);
// if the value isn't the same, means interrupt happened, jump to terminate block
// This is the code that I couldn't get it to work
llvm::BuildMI(MBB, FirstMI, DL, TII->get(llvm::X86::JCC_1))
.addImm(llvm::X86::COND_NE)
.addMBB(TrueBB);
}
}
return;
}
LLVM was successfully built, then when I try to compile some code, something like this shows up
# %bb.3: # in Loop: Header=BB25_1 Depth=1
nop
movq (%r14), %rax
cmpq $286331153, %rax # imm = 0x11111111
jo 5
It didn't compile into JNE but JO, not sure why it went wrong.
I understand that within a basic block, there shouldn't be any branching, it's for academic purpose so I just want to get it to work. Thanks in advance
Firstly thanks Micheal for helping with the ordering. BuildMi do require things to be added in order. The other important thing is that I need to add
MBB.addSuccessor(TrueBB);as you need to declare which block is the successor of the inserted block.