[llvm-dev] LLVM X86 MachineBasicBlock inserting push and pop instructions causes segmentation fault

vignesh babu via llvm-dev llvm-dev at lists.llvm.org
Mon Nov 16 12:51:29 PST 2020


Hi Craig,

Sorry for the late reply, I was travelling. Thank you very much for your
suggestion. This turned out to be the exact problem.

I was able to get around it by disabling red-zone or by decrementing the
stack pointer by 128 bytes (typical size of red-zone) before pushing
anything and reverting the stack pointer after any pop operations.

Thanks,
Vignesh

On Thu, Nov 12, 2020 at 12:48 PM Craig Topper <craig.topper at gmail.com>
wrote:

> Best guess is that you're clobbering something in the red zone.
> https://en.wikipedia.org/wiki/Red_zone_(computing).  It's not guarantee
> that the area of the stack above the stack pointer is unused. I think you
> can check if the redzone is used by checking getUsesRedZone() in
> X86MachineFunctionInfo. If the red zone is used, its not safe to insert a
> push/pop. I think you can turn off the red zone by passing -mno-red-zone to
> clang.
>
>
>
> ~Craig
>
>
> On Thu, Nov 12, 2020 at 10:18 AM vignesh babu via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> Hello,
>>
>> I am working on a project where I need to insert some logic before each
>> machine basic block.
>> In particular, it involves setting some global variables and calling a
>> function. I'm able to add the instructions and verify they get added, but
>> when the compiled program runs, it stops with a segfault.
>>
>> For brevity, I'm not sharing the whole code here but basically I have a
>> X86 MachineFunctionPass added to addPreEmitPass2 stage which simply inserts
>> a push rcx immediately followed by pop rcx before each basic block (only
>> the relevant logic portions are included):
>>
>> /* Inserts push rcx followed by pop rcx before each MachineBasicBlock */
>> void VirtualTimeManager::__insertVtlLogic(MachineFunction &MF,
>>     MachineBasicBlock* origMBB) {
>>     const llvm::TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
>>     auto MMI = &MF.getMMI();
>>     llvm::Module &M = const_cast<Module &>(*MMI->getModule());
>>     if (origMBB->empty() || !origMBB->isLegalToHoistInto())
>>          return;
>>     llvm::BuildMI(*origMBB, origMBB->begin(), DebugLoc(),
>>         TII.get(X86::POP64r)).addReg(X86::RCX);
>>     /* SOME ADDITIONAL LOGIC COMMENTED OUT */
>>     llvm::BuildMI(*origMBB, origMBB->begin(), DebugLoc(),
>>         TII.get(X86::PUSH64r)).addReg(X86::RCX);
>> }
>> bool VirtualTimeManager::runOnMachineFunction(MachineFunction &MF) {
>>          for (auto &MBB : MF) {
>>                MachineBasicBlock* origMBB = &MBB;
>>                 __insertVtlLogic(MF, origMBB);
>>         }
>>        return true;
>> }
>>
>> When I compile and run a program (e.g from SPEC-2006 benchmark (sjeng)),
>> using this pass, the program segfaults. I don't understand how simply
>> adding a push, followed by pop is affecting the program execution. Could
>> anyone please offer some insights. It would be greatly appreciated. I'm new
>> to LLVM and struggling to understand what is causing this issue.
>>
>> Thanks,
>> Vignesh
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201116/c99edd09/attachment.html>


More information about the llvm-dev mailing list