1# RUN: llc -start-before=x86-avoid-trailing-call %s -o - | FileCheck %s 2 3# If there is a trailing unreachable block, make sure it is non-empty. 4 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) { 9# try { 10# if (c1) 11# mythrow(); 12# if (c2) 13# mythrow(); 14# if (c3) 15# mythrow(); 16# } catch (...) { 17# return 1; 18# } 19# return 0; 20# } 21 22# CHECK-LABEL: "?multi_throw@@YAH_N00@Z": # @"?multi_throw@@YAH_N00@Z" 23# CHECK: retq 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 31# CHECK-NEXT: int3 32# CHECK: .seh_endproc 33# CHECK: # %catch 34 35--- | 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" 40 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*) { 43 entry: 44 br i1 %c1, label %if.then, label %if.end 45 46 if.then: ; preds = %entry 47 invoke void @mythrow() 48 to label %unreachable unwind label %catch.dispatch 49 50 unreachable: ; preds = %if.then8, %if.then4, %if.then 51 unreachable 52 53 if.end: ; preds = %entry 54 br i1 %c2, label %if.then4, label %if.end6 55 56 if.then4: ; preds = %if.end 57 invoke void @mythrow() 58 to label %unreachable unwind label %catch.dispatch 59 60 if.end6: ; preds = %if.end 61 br i1 %c3, label %if.then8, label %return 62 63 if.then8: ; preds = %if.end6 64 invoke void @mythrow() 65 to label %unreachable unwind label %catch.dispatch 66 67 catch.dispatch: ; preds = %if.then8, %if.then4, %if.then 68 %0 = catchswitch within none [label %catch] unwind to caller 69 70 catch: ; preds = %catch.dispatch 71 %1 = catchpad within %0 [i8* null, i32 64, i8* null] 72 catchret from %1 to label %return 73 74 return: ; preds = %catch, %if.end6 75 %retval.0 = phi i32 [ 1, %catch ], [ 0, %if.end6 ] 76 ret i32 %retval.0 77 } 78 79 declare dso_local void @mythrow() 80 81 declare dso_local i32 @__CxxFrameHandler3(...) 82 83 attributes #0 = { uwtable } 84 85 !llvm.module.flags = !{!0, !1} 86 87 !0 = !{i32 1, !"wchar_size", i32 2} 88 !1 = !{i32 7, !"PIC Level", i32 2} 89 90... 91--- 92name: '?multi_throw@@YAH_N00@Z' 93alignment: 16 94exposesReturnsTwice: false 95legalized: false 96regBankSelected: false 97selected: false 98failedISel: false 99tracksRegLiveness: true 100hasWinCFI: true 101registers: [] 102liveins: 103 - { reg: '$cl', virtual-reg: '' } 104 - { reg: '$dl', virtual-reg: '' } 105 - { reg: '$r8b', virtual-reg: '' } 106frameInfo: 107 isFrameAddressTaken: false 108 isReturnAddressTaken: false 109 hasStackMap: false 110 hasPatchPoint: false 111 stackSize: 56 112 offsetAdjustment: -56 113 maxAlignment: 8 114 adjustsStack: true 115 hasCalls: true 116 stackProtector: '' 117 maxCallFrameSize: 32 118 cvBytesOfCalleeSavedRegisters: 0 119 hasOpaqueSPAdjustment: true 120 hasVAStart: false 121 hasMustTailInVarArgFunc: false 122 localFrameSize: 0 123 savePoint: '' 124 restorePoint: '' 125fixedStack: 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: '' } 133stack: 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: '' } 137callSites: [] 138constants: [] 139machineFunctionInfo: {} 140body: | 141 bb.0.entry: 142 successors: %bb.1(0x00000001), %bb.3(0x7fffffff) 143 liveins: $cl, $dl, $r8b 144 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 8 into %fixed-stack.0) 153 TEST8rr killed renamable $cl, renamable $cl, implicit-def $eflags 154 JCC_1 %bb.1, 5, implicit $eflags 155 156 bb.3.if.end: 157 successors: %bb.4(0x00000001), %bb.5(0x7fffffff) 158 liveins: $dl, $r8b 159 160 TEST8rr killed renamable $dl, renamable $dl, implicit-def $eflags 161 JCC_1 %bb.4, 5, implicit $eflags 162 163 bb.5.if.end6: 164 successors: %bb.6(0x00000001), %bb.8(0x7fffffff) 165 liveins: $r8b 166 167 MOV32mi $rbp, 1, $noreg, -12, $noreg, 0 :: (store 4 into %stack.0) 168 TEST8rr killed renamable $r8b, renamable $r8b, implicit-def $eflags 169 JCC_1 %bb.6, 5, implicit $eflags 170 171 bb.8.return (address-taken): 172 $eax = MOV32rm $rbp, 1, $noreg, -12, $noreg :: (load 4 from %stack.0) 173 SEH_Epilogue 174 $rsp = frame-destroy ADD64ri8 $rsp, 48, implicit-def dead $eflags 175 $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp 176 RETQ $eax 177 178 bb.1.if.then: 179 successors: %bb.2(0x7ffff800), %bb.7(0x00000800) 180 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> 184 JMP_1 %bb.2 185 186 bb.4.if.then4: 187 successors: %bb.2(0x7ffff800), %bb.7(0x00000800) 188 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> 192 JMP_1 %bb.2 193 194 bb.6.if.then8: 195 successors: %bb.2(0x7ffff800), %bb.7(0x00000800) 196 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> 200 201 bb.2.unreachable: 202 successors: 203 204 205 bb.7.catch (landing-pad, ehfunclet-entry): 206 successors: %bb.8(0x80000000) 207 liveins: $rdx 208 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 4 into %stack.0) 217 $rax = LEA64r $rip, 0, $noreg, %bb.8, $noreg 218 SEH_Epilogue 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 222 223... 224