[LLVMdev] Problem in X86 backend (again)

Rinaldini Julien julien.rinaldini at heig-vd.ch
Tue Oct 28 13:55:01 PDT 2014


Hi,


I'm still having problems implementing my custom inserter in the X86 backend.

I found a solution to my last problem (http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-October/078296.html), by using a virtual register.


The binary works when it's compiled in -O0, but not in -O1,-O2,...

I really can't figure what I'm doing wrong... Any idea?


Here is the code of my custom inserter... The goal of this code is to erase the stack in the epilogue of a function:

MachineBasicBlock *
X86TargetLowering::EmitBURNSTACKWithCustomInserter(
MachineInstr *MI,
MachineBasicBlock *MBB) const {
MBB->getParent()->dump();
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_erase->addSuccessor(MBB_cond);
MBB_cond->addSuccessor(MBB_end);
MBB_cond->addSuccessor(MBB_erase);
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
const TargetRegisterClass *AddrRegClass = getRegClassFor(MVT::i64);
unsigned reg = MRI.createVirtualRegister(AddrRegClass);
// Set the indice
BuildMI(*MBB, MI, db, TII->get(X86::MOV64rr)).addReg(reg).addReg(X86::RSP);
// Create the for loop condition
BuildMI(*MBB_cond, MBB_cond->end(), db, TII->get(X86::CMP64rr)).addReg(reg).addReg(X86::RBP);
BuildMI(*MBB_cond, MBB_cond->end(), db, TII->get(X86::JE_4)).addMBB(MBB_end);
// Update phi node
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::PHI), reg).addReg(reg).addMBB(MBB).addReg(reg).addMBB(MBB_erase);
// Erase content of stack
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::MOV32mi))
.addReg(reg).addImm(1).addReg(0).addImm(0).addReg(0)
.addImm(0);
// Increment loop variable and jmp
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::ADD64ri32), reg).addReg(reg).addImm(8);
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::JMP_4)).addMBB(MBB_cond);
// Erase intrinsic
MI->eraseFromParent();
MBB->getParent()->dump();
return MBB_cond;
}

Here is the dump of the original function before my custom inserter (it's basically a main function with a printf and a return inside it):

# Machine code for function main: SSA
BB#0: derived from LLVM BB %entry
ADJCALLSTACKDOWN64 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg2<def> = MOV32ri64 <ga:@str>; GR32:%vreg2
%vreg3<def> = SUBREG_TO_REG 0, %vreg2<kill>, 4; GR64:%vreg3 GR32:%vreg2
%RDI<def> = COPY %vreg3; GR64:%vreg3
CALL64pcrel32 <ga:@puts>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %EAX<imp-def>
ADJCALLSTACKUP64 0, 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg4<def> = COPY %EAX; GR32:%vreg4
BURNSTACK %EFLAGS<imp-def,dead>
%vreg5<def> = MOV32r0 %EFLAGS<imp-def,dead>; GR32:%vreg5
%EAX<def> = COPY %vreg5; GR32:%vreg5
RETQ %EAX
# End machine code for function main.


Here is the dump after my custom inserter (with the stacktrace):

# Machine code for function main: SSA
BB#0: derived from LLVM BB %entry
ADJCALLSTACKDOWN64 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg2<def> = MOV32ri64 <ga:@str>; GR32:%vreg2
%vreg3<def> = SUBREG_TO_REG 0, %vreg2<kill>, 4; GR64:%vreg3 GR32:%vreg2
%RDI<def> = COPY %vreg3; GR64:%vreg3
CALL64pcrel32 <ga:@puts>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %EAX<imp-def>
ADJCALLSTACKUP64 0, 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg4<def> = COPY %EAX; GR32:%vreg4
MOV64rr %vreg6, %RSP; GR64:%vreg6
Successors according to CFG: BB#1
BB#1: derived from LLVM BB %entry
Predecessors according to CFG: BB#0 BB#2
CMP64rr %vreg6, %RBP, %EFLAGS<imp-def>; GR64:%vreg6
JE_4 <BB#3>, %EFLAGS<imp-use>
Successors according to CFG: BB#3 BB#2
BB#2: derived from LLVM BB %entry
Predecessors according to CFG: BB#1
%vreg6<def> = PHI %vreg6, <BB#0>, %vreg6, <BB#2>; GR64:%vreg6
MOV32mi %vreg6, 1, %noreg, 0, %noreg, 0; GR64:%vreg6
%vreg6<def,tied1> = ADD64ri32 %vreg6<tied0>, 8, %EFLAGS<imp-def>; GR64:%vreg6
JMP_4 <BB#1>
Successors according to CFG: BB#1
BB#3: derived from LLVM BB %entry
Predecessors according to CFG: BB#1
%vreg5<def> = MOV32r0 %EFLAGS<imp-def,dead>; GR32:%vreg5
%EAX<def> = COPY %vreg5; GR32:%vreg5
RETQ %EAX
# End machine code for function main.
clang: /home/pyknite/work/ollvm/obfuscator-llvm/lib/CodeGen/MachineRegisterInfo.cpp:305: llvm::MachineInstr *llvm::MachineRegisterInfo::getVRegDef(unsigned int) const: Assertion `(I.atEnd() || std::next(I) == def_instr_end()) && "getVRegDef assumes a single definition or no definition"' failed.
0 clang 0x00000000027c3645 llvm::sys::PrintStackTrace(_IO_FILE*) + 37
1 clang 0x00000000027c3e33
2 libpthread.so.0 0x00007fba6de1b200
3 libc.so.6 0x00007fba6cbcc967 gsignal + 55
4 libc.so.6 0x00007fba6cbcdd3a abort + 362
5 libc.so.6 0x00007fba6cbc58ad
6 libc.so.6 0x00007fba6cbc5962
7 clang 0x00000000021a6a06 llvm::MachineRegisterInfo::getVRegDef(unsigned int) const + 118
8 clang 0x0000000002194ddc
9 clang 0x0000000002191986
10 clang 0x000000000218396c llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 124
11 clang 0x00000000026f8f3b llvm::FPPassManager::runOnFunction(llvm::Function&) + 539
12 clang 0x00000000026f91ab llvm::FPPassManager::runOnModule(llvm::Module&) + 43
13 clang 0x00000000026f9727 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 967
14 clang 0x00000000008e461d clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 7293
15 clang 0x00000000008e1b4a
16 clang 0x0000000000ace263 clang::ParseAST(clang::Sema&, bool, bool) + 467
17 clang 0x0000000000700cde clang::FrontendAction::Execute() + 62
18 clang 0x00000000006d5e13 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 851
19 clang 0x00000000006b7e60 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 3104
20 clang 0x00000000006aebe9 cc1_main(char const**, char const**, char const*, void*) + 665
21 clang 0x00000000006b538a main + 8154
22 libc.so.6 0x00007fba6cbb9040 __libc_start_main + 240
23 clang 0x00000000006ae87d

Cheers




More information about the llvm-dev mailing list