[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