1 # RUN: llc -start-before=x86-avoid-trailing-call %s -o - | FileCheck %s
3 # If there is a trailing unreachable block, make sure it is non-empty.
5 # Manually modified the IR of the following C++ to share one unreachable block,
6 # as clang does for the real C++ throw:
7 # void __declspec(noreturn) mythrow();
8 # int multi_throw(bool c1, bool c2, bool c3) {
22 # CHECK-LABEL: "?multi_throw@@YAH_N00@Z": # @"?multi_throw@@YAH_N00@Z"
24 # CHECK: .LBB{{.*}} # %if.then
25 # CHECK: callq mythrow
26 # CHECK: .LBB{{.*}} # %if.then4
27 # CHECK: callq mythrow
28 # CHECK: .LBB{{.*}} # %if.then8
29 # CHECK: callq mythrow
30 # CHECK: .LBB{{.*}} # %unreachable
36 ; ModuleID = '../llvm/test/CodeGen/X86/win64-eh-empty-block-2.ll'
37 source_filename = "t.cpp"
38 target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
39 target triple = "x86_64-unknown-windows-msvc19.11.0"
41 ; Function Attrs: uwtable
42 define dso_local i32 @"?multi_throw@@YAH_N00@Z"(i1 zeroext %c1, i1 zeroext %c2, i1 zeroext %c3) local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
44 br i1 %c1, label %if.then, label %if.end
46 if.then: ; preds = %entry
47 invoke void @mythrow()
48 to label %unreachable unwind label %catch.dispatch
50 unreachable: ; preds = %if.then8, %if.then4, %if.then
53 if.end: ; preds = %entry
54 br i1 %c2, label %if.then4, label %if.end6
56 if.then4: ; preds = %if.end
57 invoke void @mythrow()
58 to label %unreachable unwind label %catch.dispatch
60 if.end6: ; preds = %if.end
61 br i1 %c3, label %if.then8, label %return
63 if.then8: ; preds = %if.end6
64 invoke void @mythrow()
65 to label %unreachable unwind label %catch.dispatch
67 catch.dispatch: ; preds = %if.then8, %if.then4, %if.then
68 %0 = catchswitch within none [label %catch] unwind to caller
70 catch: ; preds = %catch.dispatch
71 %1 = catchpad within %0 [i8* null, i32 64, i8* null]
72 catchret from %1 to label %return
74 return: ; preds = %catch, %if.end6
75 %retval.0 = phi i32 [ 1, %catch ], [ 0, %if.end6 ]
79 declare dso_local void @mythrow()
81 declare dso_local i32 @__CxxFrameHandler3(...)
83 attributes #0 = { uwtable }
85 !llvm.module.flags = !{!0, !1}
87 !0 = !{i32 1, !"wchar_size", i32 2}
88 !1 = !{i32 7, !"PIC Level", i32 2}
92 name: '?multi_throw@@YAH_N00@Z'
94 exposesReturnsTwice: false
96 regBankSelected: false
99 tracksRegLiveness: true
103 - { reg: '$cl', virtual-reg: '' }
104 - { reg: '$dl', virtual-reg: '' }
105 - { reg: '$r8b', virtual-reg: '' }
107 isFrameAddressTaken: false
108 isReturnAddressTaken: false
112 offsetAdjustment: -56
118 cvBytesOfCalleeSavedRegisters: 0
119 hasOpaqueSPAdjustment: true
121 hasMustTailInVarArgFunc: false
126 - { id: 0, type: default, offset: -24, size: 8, alignment: 8, stack-id: default,
127 isImmutable: false, isAliased: false, callee-saved-register: '',
128 callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
129 debug-info-location: '' }
130 - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
131 callee-saved-register: '', callee-saved-restored: true, debug-info-variable: '',
132 debug-info-expression: '', debug-info-location: '' }
134 - { id: 0, name: '', type: spill-slot, offset: -28, size: 4, alignment: 4,
135 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
136 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
139 machineFunctionInfo: {}
142 successors: %bb.1(0x00000001), %bb.3(0x7fffffff)
143 liveins: $cl, $dl, $r8b
145 frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
146 frame-setup SEH_PushReg 50
147 $rsp = frame-setup SUB64ri8 $rsp, 48, implicit-def dead $eflags
148 frame-setup SEH_StackAlloc 48
149 $rbp = LEA64r $rsp, 1, $noreg, 48, $noreg
150 frame-setup SEH_SetFrame 50, 48
151 frame-setup SEH_EndPrologue
152 MOV64mi32 $rbp, 1, $noreg, -8, $noreg, -2 :: (store (s64) into %fixed-stack.0)
153 TEST8rr killed renamable $cl, renamable $cl, implicit-def $eflags
154 JCC_1 %bb.1, 5, implicit $eflags
157 successors: %bb.4(0x00000001), %bb.5(0x7fffffff)
160 TEST8rr killed renamable $dl, renamable $dl, implicit-def $eflags
161 JCC_1 %bb.4, 5, implicit $eflags
164 successors: %bb.6(0x00000001), %bb.8(0x7fffffff)
167 MOV32mi $rbp, 1, $noreg, -12, $noreg, 0 :: (store (s32) into %stack.0)
168 TEST8rr killed renamable $r8b, renamable $r8b, implicit-def $eflags
169 JCC_1 %bb.6, 5, implicit $eflags
171 bb.8.return (machine-block-address-taken):
172 $eax = MOV32rm $rbp, 1, $noreg, -12, $noreg :: (load (s32) from %stack.0)
174 $rsp = frame-destroy ADD64ri8 $rsp, 48, implicit-def dead $eflags
175 $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
179 successors: %bb.2(0x7ffff800), %bb.7(0x00000800)
181 EH_LABEL <mcsymbol .Leh1>
182 CALL64pcrel32 @mythrow, csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
183 EH_LABEL <mcsymbol .Leh2>
187 successors: %bb.2(0x7ffff800), %bb.7(0x00000800)
189 EH_LABEL <mcsymbol .Leh3>
190 CALL64pcrel32 @mythrow, csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
191 EH_LABEL <mcsymbol .Leh4>
195 successors: %bb.2(0x7ffff800), %bb.7(0x00000800)
197 EH_LABEL <mcsymbol .Leh5>
198 CALL64pcrel32 @mythrow, csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
199 EH_LABEL <mcsymbol .Leh6>
205 bb.7.catch (landing-pad, ehfunclet-entry):
206 successors: %bb.8(0x80000000)
209 frame-setup MOV64mr killed $rsp, 1, $noreg, 16, $noreg, $rdx
210 frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
211 frame-setup SEH_PushReg 50
212 $rsp = frame-setup SUB64ri8 $rsp, 32, implicit-def dead $eflags
213 frame-setup SEH_StackAlloc 32
214 $rbp = LEA64r $rdx, 1, $noreg, 48, $noreg
215 frame-setup SEH_EndPrologue
216 MOV32mi $rbp, 1, $noreg, -12, $noreg, 1 :: (store (s32) into %stack.0)
217 $rax = LEA64r $rip, 0, $noreg, %bb.8, $noreg
219 $rsp = frame-destroy ADD64ri8 $rsp, 32, implicit-def dead $eflags
220 $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
221 CATCHRET %bb.8, %bb.0