[llvm] r248857 - [WinEH] Setup RBP correctly in Win64 funclet prologues

Bill Seurer via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 09:08:32 PDT 2015


On 09/30/2015 03:10 AM, Justin Bogner via llvm-commits wrote:
> Reid Kleckner via llvm-commits <llvm-commits at lists.llvm.org> writes:
>> Author: rnk
>> Date: Tue Sep 29 18:32:01 2015
>> New Revision: 248857
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=248857&view=rev
>> Log:
>> [WinEH] Setup RBP correctly in Win64 funclet prologues
>>
>> Previously local variable captures just didn't work in 64-bit. Now we
>> can access local variables more or less correctly.
>>
>> Modified:
>>      llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
>>      llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
>>      llvm/trunk/test/CodeGen/X86/win-catchpad.ll
>>      llvm/trunk/test/CodeGen/X86/win-cleanuppad.ll
>>      llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll
>>
>> Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=248857&r1=248856&r2=248857&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Tue Sep 29 18:32:01 2015
>> @@ -623,6 +623,7 @@ void X86FrameLowering::emitPrologue(Mach
>>     X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
>>     uint64_t MaxAlign = calculateMaxStackAlign(MF); // Desired stack alignment.
>>     uint64_t StackSize = MFI->getStackSize();    // Number of bytes to allocate.
>> +  bool IsFunclet = MBB.isEHFuncletEntry();
>>     bool HasFP = hasFP(MF);
>>     bool IsWin64CC = STI.isCallingConvWin64(Fn->getCallingConv());
>>     bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
>> @@ -700,46 +701,17 @@ void X86FrameLowering::emitPrologue(Mach
>>     uint64_t NumBytes = 0;
>>     int stackGrowth = -SlotSize;
>>
>> -  if (MBB.isEHFuncletEntry()) {
>> -    assert(STI.isOSWindows() && "funclets only supported on Windows");
>> -
>> -    // Set up the FramePtr and BasePtr physical registers using the address
>> -    // passed as EBP or RDX by the MSVC EH runtime.
>> -    if (STI.is32Bit()) {
>> -      // PUSH32r %ebp
>> -      BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
>> -          .addReg(MachineFramePtr, RegState::Kill)
>> -          .setMIFlag(MachineInstr::FrameSetup);
>> -      // Reset EBP / ESI to something good.
>> -      MBBI = restoreWin32EHStackPointers(MBB, MBBI, DL);
>> -    } else {
>> -      // Immediately spill RDX into the home slot. The runtime cares about this.
>> -      unsigned RDX = Uses64BitFramePtr ? X86::RDX : X86::EDX;
>> -      // MOV64mr %rdx, 16(%rsp)
>> -      unsigned MOVmr = Uses64BitFramePtr ? X86::MOV64mr : X86::MOV32mr;
>> -      addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(MOVmr)),
>> -                   StackPtr, true, 16)
>> +  unsigned RDX = Uses64BitFramePtr ? X86::RDX : X86::EDX;
>> +  if (IsWin64Prologue && IsFunclet) {
>> +    // Immediately spill RDX into the home slot. The runtime cares about this.
>> +    // MOV64mr %rdx, 16(%rsp)
>> +    unsigned MOVmr = Uses64BitFramePtr ? X86::MOV64mr : X86::MOV32mr;
>> +    addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(MOVmr)), StackPtr, true, 16)
>>           .addReg(RDX)
>>           .setMIFlag(MachineInstr::FrameSetup);
>> -      // PUSH64r %rbp
>> -      BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r))
>> -          .addReg(MachineFramePtr, RegState::Kill)
>> -          .setMIFlag(MachineInstr::FrameSetup);
>> -      BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_PushReg))
>> -          .addImm(MachineFramePtr)
>> -          .setMIFlag(MachineInstr::FrameSetup);
>> -      // MOV64rr %rdx, %rbp
>> -      unsigned MOVrr = Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr;
>> -      BuildMI(MBB, MBBI, DL, TII.get(MOVrr), FramePtr)
>> -          .addReg(RDX)
>> -          .setMIFlag(MachineInstr::FrameSetup);
>> -      assert(!TRI->hasBasePointer(MF) &&
>> -             "x64 funclets with base ptrs not yet implemented");
>> -    }
>> +  }
>>
>> -    // For EH funclets, only allocate enough space for outgoing calls.
>> -    NumBytes = MFI->getMaxCallFrameSize();
>> -  } else if (HasFP) {
>> +  if (HasFP) {
>>       // Calculate required stack adjustment.
>>       uint64_t FrameSize = StackSize - SlotSize;
>>       // If required, include space for extra hidden slot for stashing base pointer.
>> @@ -755,7 +727,11 @@ void X86FrameLowering::emitPrologue(Mach
>>       // Get the offset of the stack slot for the EBP register, which is
>>       // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
>>       // Update the frame offset adjustment.
>> -    MFI->setOffsetAdjustment(-NumBytes);
>> +    if (!IsFunclet)
>> +      MFI->setOffsetAdjustment(-NumBytes);
>> +    else
>> +      assert(MFI->getOffsetAdjustment() == -NumBytes &&
>> +             "should calculate same local variable offset for funclets");
>
> I get a -Wsign-compare warning after this change:
>
>    .../llvm/lib/Target/X86/X86FrameLowering.cpp:733:41: error: comparison of integers of different signs: 'int' and 'uint64_t' (aka 'unsigned long long') [-Werror,-Wsign-compare]
>          assert(MFI->getOffsetAdjustment() == -NumBytes &&
>                 ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~

It causes an error in the sanitizer (because of -Werror):


/home/buildbots/sanitizerslave1/sanitizer-ppc64-1/build/llvm/lib/Target/X86/X86FrameLowering.cpp:733:41: 
error: comparison of integers of different signs: 'int' and 'uint64_t' 
(aka 'unsigned long') [-Werror,-Wsign-compare]
       assert(MFI->getOffsetAdjustment() == -NumBytes &&
              ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~
/usr/include/assert.h:86:5: note: expanded from macro 'assert'
   ((expr)                                                               \
     ^~~~
1 error generated.
lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/build.make:169: recipe for 
target 
'lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/X86FrameLowering.cpp.o' failed
make[3]: *** 
[lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/X86FrameLowering.cpp.o] 
Error 1
CMakeFiles/Makefile2:8912: recipe for target 
'lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/all' failed
make[2]: *** [lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/all] Error 2
CMakeFiles/Makefile2:16842: recipe for target 
'tools/clang/runtime/CMakeFiles/check-asan-dynamic.dir/rule' failed
make[1]: *** 
[tools/clang/runtime/CMakeFiles/check-asan-dynamic.dir/rule] Error 2
Makefile:4643: recipe for target 'check-asan-dynamic' failed
make: *** [check-asan-dynamic] Error 2



-- 

-Bill Seurer



More information about the llvm-commits mailing list