[LLVMdev] Virtual register problem in X86 backend

Quentin Colombet qcolombet at apple.com
Tue Dec 9 11:01:15 PST 2014


Hi Julien,

I have to admit that the way you build the virtual registers looks correct to me.

Could you attach the machine IR right before and after the insertion as well as the final assembly (i.e., not just the binary), to see if I can help you further.

Thanks,
-Quentin
On Dec 8, 2014, at 5:56 AM, Rinaldini Julien <julien.rinaldini at heig-vd.ch> wrote:

> 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
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev





More information about the llvm-dev mailing list