[LLVMdev] Virtual register problem in X86 backend

Rinaldini Julien julien.rinaldini at heig-vd.ch
Mon Dec 8 05:56:35 PST 2014


Hi,

I'm having trouble using virtual register in the X86 backend.

I implemented a new intrinsic and I use a custom inserter. The goal of
the intrinsic is to set the content of the stack to zero at the end of
each function.

Here is my code:

MachineBasicBlock *
X86TargetLowering::EmitBURNSTACKWithCustomInserter(
                     MachineInstr *MI,
                     MachineBasicBlock *MBB) const {
    DebugLoc db = MI->getDebugLoc();
    const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
    const BasicBlock *LLVM_BB = MBB->getBasicBlock();
    MachineFunction *F = MBB->getParent();

    // Create all the basicblocks
    MachineBasicBlock *MBB_cond = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *MBB_erase = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *MBB_end = F->CreateMachineBasicBlock(LLVM_BB);

    // Insert the new basicblocks
    F->insert(MBB, MBB_cond);
    F->insert(MBB, MBB_erase);
    F->insert(MBB, MBB_end);

    // Split the last MBB in two
    MBB_end->splice(MBB_end->begin(), MBB,
next(MachineBasicBlock::iterator(MI)), MBB->end());
    MBB_end->transferSuccessorsAndUpdatePHIs(MBB);

    // Move MBB at the right place
    MBB_end->moveAfter(MBB);
    MBB_erase->moveAfter(MBB);
    MBB_cond->moveAfter(MBB);

    // Set the new successors
    MBB->addSuccessor(MBB_cond);
    MBB_cond->addSuccessor(MBB_erase);
    MBB_cond->addSuccessor(MBB_end);
    MBB_erase->addSuccessor(MBB_cond);
    MBB_erase->addSuccessor(MBB_end);

    MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
    const TargetRegisterClass *AddrRegClass = getRegClassFor(MVT::i64);
    unsigned regA = MRI.createVirtualRegister(AddrRegClass);
    unsigned regB = MRI.createVirtualRegister(AddrRegClass);
    unsigned regC = MRI.createVirtualRegister(AddrRegClass);

    // Set the indice
    BuildMI(*MBB, MI, db,
TII->get(X86::MOV64rr)).addReg(regA).addReg(X86::RSP);

    // Check condition
    BuildMI(*MBB_cond, MBB_cond->end(), db, TII->get(X86::PHI),
regB).addReg(regA).addMBB(MBB).addReg(regC).addMBB(MBB_erase);
    BuildMI(*MBB_cond, MBB_cond->end(), db,
TII->get(X86::CMP64rr)).addReg(regB).addReg(X86::RBP);
    BuildMI(*MBB_cond, MBB_cond->end(), db,
TII->get(X86::JE_4)).addMBB(MBB_end);

    // mov dword[reg], 0x0
    BuildMI(*MBB_erase, MBB_erase->end(), db,
TII->get(X86::MOV32mi)).addReg(regB).addImm(1).addReg(0).addImm(0).addReg(0).addImm(0);
   BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::ADD64ri32),
regC).addReg(regB).addImm(8);
    BuildMI(*MBB_cond, MBB_erase->end(), db,
TII->get(X86::JMP_4)).addMBB(MBB_cond);

    // Erase intrinsic
    MI->eraseFromParent();
    MBB->getParent()->dump();
    return MBB_erase;
}

I run it on this sample code:

#include <stdio.h>

int main(int argc, char **argv) {
  printf("MAIN\n");
  return 0;
}

And it generate this X86 assembly:

/ (fcn) sym.main 115
|          0x004004f0 b  55           push rbp
|          0x004004f1    4889e5       mov rbp, rsp
|          0x004004f4    4883ec30     sub rsp, 0x30
|          0x004004f8    48b8f405400. mov rax, str.MAIN ;  0x004005f4
|          0x00400502    c745fc00000. mov dword [rbp-0x4], 0x0
|          0x00400509    897df8       mov [rbp-0x8], edi
|          0x0040050c    488975f0     mov [rbp-0x10], rsi
|          0x00400510    4889c7       mov rdi, rax
|          0x00400513    b000         mov al, 0x0
|          0x00400515    e8a6feffff   call sym.imp.printf
|             sym.imp.printf(unk)
|          0x0040051a    b900000000   mov ecx, 0x0
|          0x0040051f    488b75e8     mov rsi, [rbp-0x18]
|          0x00400523    4889e6       mov rsi, rsp
|          0x00400526    8945e4       mov [rbp-0x1c], eax
|          0x00400529    894de0       mov [rbp-0x20], ecx
|          0x0040052c    48897dd8     mov [rbp-0x28], rdi
|     .    ; CODE (CALL) XREF from 0x00400555 (fcn.004004bc)
|- loc.00400530 51
|     .--> 0x00400530    488b45d8     mov rax, [rbp-0x28]
|     |    0x00400534    4839e8       cmp rax, rbp
|     |    0x00400537    488945d0     mov [rbp-0x30], rax
|     |,=< 0x0040053b    0f8419000000 je 0x40055a
|     ||   0x00400541    488b45d0     mov rax, [rbp-0x30]
|     ||   0x00400545    c70000000000 mov dword [rax], 0x0
|     ||   0x0040054b    480508000000 add rax, 0x8
|     ||   0x00400551    488945d8     mov [rbp-0x28], rax
|     |    ; CODE (CALL) XREF from 0x00400530 (fcn.004004bc)
|     `==< 0x00400555    e9d6ffffff   jmp loc.00400530
|      `-> 0x0040055a    8b45e0       mov eax, [rbp-0x20]
|          0x0040055d    4883c430     add rsp, 0x30
|          0x00400561    5d           pop rbp
\          0x00400562    c3           ret


As we can see, it moves RSP in RSI, but then, generates the rest of the
code with RAX, so it fails.

Am I missing something?

Cheers



More information about the llvm-dev mailing list