How to insert a JNE instruction (jump not equal) using buildmi in LLVM x86 machine function pass

48 Views Asked by At

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

1

There are 1 best solutions below

0
Nelly On

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.