llvm.org GIT mirror llvm / 04538c9
[WinEH] Make UnwindHelp a fixed stack object allocated after XMM CSRs Now the offset of UnwindHelp in our EH tables and the offset that we store to in the prologue agree. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253059 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 4 years ago
9 changed file(s) with 116 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
16951695 // RETADDR
16961696 // PUSH RBP <-- RBP points here
16971697 // PUSH CSRs
1698 // ~~~~~~~ <-- optional stack realignment dynamic adjustment
1698 // ~~~~~~~ <-- possible stack realignment (non-win64)
16991699 // ...
17001700 // STACK OBJECTS
17011701 // ... <-- RSP after prologue points here
1702 // ~~~~~~~ <-- possible stack realignment (win64)
17021703 //
17031704 // if (hasVarSizedObjects()):
17041705 // ... <-- "base pointer" (ESI/RBX) points here
17201721 // answer we give is relative to the SP after the prologue, and not the
17211722 // SP in the middle of the function.
17221723
1723 assert((!TRI->needsStackRealignment(MF) || !MFI->isFixedObjectIndex(FI)) &&
1724 assert((!MFI->isFixedObjectIndex(FI) || !TRI->needsStackRealignment(MF) ||
1725 STI.isTargetWin64()) &&
17241726 "offset from fixed object to SP is not static");
17251727
17261728 // We don't handle tail calls, and shouldn't be seeing them either.
26412643 Offset += getWinEHFuncletFrameSize(MF);
26422644 return Offset;
26432645 }
2646
2647 void X86FrameLowering::processFunctionBeforeFrameFinalized(
2648 MachineFunction &MF, RegScavenger *RS) const {
2649 // If this function isn't doing Win64-style C++ EH, we don't need to do
2650 // anything.
2651 const Function *Fn = MF.getFunction();
2652 if (!STI.is64Bit() || !Fn->hasPersonalityFn() ||
2653 classifyEHPersonality(MF.getFunction()->getPersonalityFn()) !=
2654 EHPersonality::MSVC_CXX)
2655 return;
2656
2657 // Win64 C++ EH needs to allocate the UnwindHelp object at some fixed offset
2658 // relative to RSP after the prologue. Find the offset of the last fixed
2659 // object, so that we can allocate a slot immediately following it. Fixed
2660 // objects have negative frame indices.
2661 MachineFrameInfo *MFI = MF.getFrameInfo();
2662 int64_t MinFixedObjOffset = 0;
2663 for (int I = MFI->getObjectIndexBegin(); I < 0; ++I)
2664 MinFixedObjOffset = std::min(MinFixedObjOffset, MFI->getObjectOffset(I));
2665
2666 int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize;
2667 int UnwindHelpFI =
2668 MFI->CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false);
2669 MF.getMMI().getWinEHFuncInfo(Fn).UnwindHelpFrameIdx = UnwindHelpFI;
2670
2671 // Store -2 into UnwindHelp on function entry. We have to scan forwards past
2672 // other frame setup instructions.
2673 MachineBasicBlock &MBB = MF.front();
2674 auto MBBI = MBB.begin();
2675 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
2676 ++MBBI;
2677
2678 DebugLoc DL = MBB.findDebugLoc(MBBI);
2679 addFrameReference(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mi32)),
2680 UnwindHelpFI)
2681 .addImm(-2);
2682 }
107107 MachineBasicBlock::iterator MI) const override;
108108
109109 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
110
111 void processFunctionBeforeFrameFinalized(MachineFunction &MF,
112 RegScavenger *RS) const override;
110113
111114 /// Check the instruction before/after the passed instruction. If
112115 /// it is an ADD/SUB/LEA instruction it is deleted argument and the
28792879
28802880 if (MMI.hasWinEHFuncInfo(Fn)) {
28812881 EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
2882 if (Personality == EHPersonality::MSVC_CXX) {
2883 if (Is64Bit) {
2884 int UnwindHelpFI = MFI->CreateStackObject(8, 8, /*isSS=*/false);
2885 SDValue StackSlot = DAG.getFrameIndex(UnwindHelpFI, MVT::i64);
2886 MMI.getWinEHFuncInfo(MF.getFunction()).UnwindHelpFrameIdx =
2887 UnwindHelpFI;
2888 SDValue Neg2 = DAG.getConstant(-2, dl, MVT::i64);
2889 Chain = DAG.getStore(Chain, dl, Neg2, StackSlot,
2890 MachinePointerInfo::getFixedStack(
2891 DAG.getMachineFunction(), UnwindHelpFI),
2892 /*isVolatile=*/true,
2893 /*isNonTemporal=*/false, /*Alignment=*/0);
2894 }
2895 } else if (Personality == EHPersonality::CoreCLR) {
2882 if (Personality == EHPersonality::CoreCLR) {
28962883 assert(Is64Bit);
28972884 // TODO: Add a mechanism to frame lowering that will allow us to indicate
28982885 // that we'd prefer this slot be allocated towards the bottom of the frame
0 ; RUN: llc -verify-machineinstrs < %s | FileCheck %s
1
2 ; We should store -2 into UnwindHelp in a slot immediately after the last XMM
3 ; CSR save.
4
5 declare void @g()
6 declare i32 @__CxxFrameHandler3(...)
7
8 @fp_global = global double 0.0
9
10 define void @f() personality i32 (...)* @__CxxFrameHandler3 {
11 %v = load double, double* @fp_global
12 call void @g()
13 %v1 = fadd double %v, 1.0
14 store double %v1, double* @fp_global
15 invoke void @g()
16 to label %return unwind label %catch
17
18 return:
19 ret void
20
21 catch:
22 %p = catchpad [i8* null, i32 64, i8* null]
23 to label %catchit unwind label %endpad
24
25 catchit:
26 catchret %p to label %return
27 endpad:
28 catchendpad unwind to caller
29 }
30
31 ; CHECK: f: # @f
32 ; CHECK: pushq %rbp
33 ; CHECK: .seh_pushreg 5
34 ; CHECK: subq $64, %rsp
35 ; CHECK: .seh_stackalloc 64
36 ; CHECK: leaq 64(%rsp), %rbp
37 ; CHECK: .seh_setframe 5, 64
38 ; CHECK: movaps %xmm6, -16(%rbp) # 16-byte Spill
39 ; CHECK: .seh_savexmm 6, 48
40 ; CHECK: .seh_endprologue
41 ; CHECK: movq $-2, -24(%rbp)
42 ; CHECK: movsd fp_global(%rip), %xmm6 # xmm6 = mem[0],zero
43 ; CHECK: callq g
44 ; CHECK: addsd __real@3ff0000000000000(%rip), %xmm6
45 ; CHECK: movsd %xmm6, fp_global(%rip)
46 ; CHECK: .Ltmp{{.*}}
47 ; CHECK: callq g
48 ; CHECK: .Ltmp{{.*}}
49 ; CHECK: .LBB{{.*}} # Block address taken
50 ; CHECK: movaps -16(%rbp), %xmm6
51 ; CHECK: addq $64, %rsp
52 ; CHECK: popq %rbp
53 ; CHECK: retq
54 ; CHECK: .seh_handlerdata
4949 ; X64: .seh_pushreg 5
5050 ; X64: pushq %rbx
5151 ; X64: .seh_pushreg 3
52 ; X64: subq $72, %rsp
53 ; X64: .seh_stackalloc 72
54 ; X64: leaq 64(%rsp), %rbp
55 ; X64: .seh_setframe 5, 64
52 ; X64: subq $104, %rsp
53 ; X64: .seh_stackalloc 104
54 ; X64: leaq 96(%rsp), %rbp
55 ; X64: .seh_setframe 5, 96
5656 ; X64: .seh_endprologue
5757 ; X64: andq $-32, %rsp
5858 ; X64: movq %rsp, %rbx
5959 ; RBP will reload from this offset.
60 ; X64: movq %rbp, 48(%rbx)
60 ; X64: movq %rbp, 56(%rbx)
61 ; X64: movq $-2, (%rbp)
6162
6263 ; X64-LABEL: "?dtor$2@?0?realigned_cleanup@4HA":
6364 ; X64: movq %rdx, 16(%rsp)
6768 ; X64: .seh_pushreg 3
6869 ; X64: subq $40, %rsp
6970 ; X64: .seh_stackalloc 40
70 ; X64: leaq 64(%rdx), %rbp
71 ; X64: leaq 96(%rdx), %rbp
7172 ; X64: .seh_endprologue
7273 ; X64: andq $-32, %rdx
7374 ; X64: movq %rdx, %rbx
105105 ; X64: leaq 32(%rsp), %rbp
106106 ; X64: .seh_setframe 5, 32
107107 ; X64: .seh_endprologue
108 ; X64: movq $-2, (%rbp)
108109 ; X64: callq getint
109110 ; X64: callq getint
110111 ; X64: callq getint
3737 ; X64: pushq %rsi
3838 ; X64: subq $56, %rsp
3939 ; X64: leaq 48(%rsp), %rbp
40 ; X64: movq $-2, (%rbp)
4041 ; X64: callq g
4142 ; X64: movl %esi, %eax
4243 ; X64: addq $56, %rsp
4344 ; X64: popq %rsi
4445 ; X64: popq %rbp
4546
46 ; X64: movl 4(%rbp), %esi
47 ; X64: movl -4(%rbp), %esi
4748 ; X64: jmp
4849
4950 ; X64-LABEL: "?catch$1@?0?f@4HA":
6364 ; - 48 for setframe
6465 ; = 40
6566 ; X64: movl 40(%rbp), %eax
66 ; X64: movl %eax, 4(%rbp)
67 ; X64: movl %eax, -4(%rbp)
6768 ; X64: leaq .LBB0_2(%rip), %rax
6869 ; X64: addq $40, %rsp
6970 ; X64: popq %rsi
137137 ; X64: leaq 48(%rsp), %rbp
138138 ; X64: .seh_setframe 5, 48
139139 ; X64: .seh_endprologue
140 ; X64: movq $-2, -8(%rbp)
140141 ; X64: .Ltmp0
141142 ; X64-DAG: leaq -[[local_offs:[0-9]+]](%rbp), %rdx
142143 ; X64-DAG: movl $1, %ecx
158159 ; X64: .seh_endprologue
159160 ; X64-DAG: .Ltmp4
160161 ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
161 ; X64-DAG: movl -4(%rbp), %ecx
162 ; X64-DAG: movl -12(%rbp), %ecx
162163 ; X64: callq f
163164 ; X64: leaq [[contbb]](%rip), %rax
164165 ; X64-NEXT: addq $32, %rsp
191192 ; X64-NEXT: .long ($tryMap$try_catch_catch)@IMGREL
192193 ; X64-NEXT: .long 4
193194 ; X64-NEXT: .long ($ip2state$try_catch_catch)@IMGREL
194 ; X64-NEXT: .long 32
195 ; X64-NEXT: .long 40
195196 ; X64-NEXT: .long 0
196197 ; X64-NEXT: .long 1
197198
205206 ; X64: $handlerMap$0$try_catch_catch:
206207 ; X64-NEXT: .long 0
207208 ; X64-NEXT: .long "??_R0H@8"@IMGREL
208 ; FIXME: This should probably be offset from rsp, not rbp.
209 ; X64-NEXT: .long 44
209 ; X64-NEXT: .long 36
210210 ; X64-NEXT: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL
211211 ; X64-NEXT: .long 56
212212 ; X64-NEXT: .long 64
141141 ; X64-NEXT: .long 0
142142 ; X64-NEXT: .long 5
143143 ; X64-NEXT: .long ($ip2state$nested_cleanup)@IMGREL
144 ; X64-NEXT: .long 40
144 ; X64-NEXT: .long 56
145145 ; X64-NEXT: .long 0
146146 ; X64-NEXT: .long 1
147147