[LLVMdev] Problem in X86 backend (again)

Akira Hatanaka ahatanak at gmail.com
Tue Oct 28 14:23:33 PDT 2014


On Tue, Oct 28, 2014 at 1:55 PM, Rinaldini Julien <
julien.rinaldini at heig-vd.ch> wrote:

> 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);
>

It looks like this instruction is defining virtual register "reg" the
second time.


> 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
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141028/09dd450f/attachment.html>


More information about the llvm-dev mailing list