1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
%eh.ThrowInfo = type { i32, i32, i32, i32 }
%rtti.TypeDescriptor2 = type { ptr, ptr, [3 x i8] }
@"\01??_7type_info@@6B@" = external constant ptr
@"\01??_R0H@8" = internal global %rtti.TypeDescriptor2 { ptr @"\01??_7type_info@@6B@", ptr null, [3 x i8] c".H\00" }
declare void @llvm.trap()
define void @test1(i1 %B) personality ptr @__CxxFrameHandler3 {
entry:
invoke void @g()
to label %unreachable unwind label %catch.dispatch
catch.dispatch:
%cs1 = catchswitch within none [label %catch] unwind to caller
catch:
%cp = catchpad within %cs1 [ptr null, i32 64, ptr null]
br label %catch.loop
catch.loop:
br i1 %B, label %catchret, label %catch.loop
catchret:
catchret from %cp to label %try.cont
try.cont:
ret void
unreachable:
call void @llvm.trap()
unreachable
}
; CHECK-LABEL: test1:
; The entry funclet contains %entry and %try.cont
; CHECK: # %entry
; CHECK: # %try.cont
; CHECK: retq
; The catch funclet contains %catch and %catchret
; CHECK: # %catch{{$}}
; CHECK: # %catchret
; CHECK: retq
declare void @g()
define i32 @test2(i1 %B) personality ptr @__CxxFrameHandler3 {
entry:
invoke void @_CxxThrowException(ptr null, ptr null) #1
to label %unreachable unwind label %catch.dispatch
catch.dispatch: ; preds = %entry
%cs1 = catchswitch within none [label %catch] unwind to caller
catch: ; preds = %catch.dispatch
%0 = catchpad within %cs1 [ptr null, i32 64, ptr null]
invoke void @_CxxThrowException(ptr null, ptr null) #1 ["funclet"(token %0)]
to label %unreachable unwind label %catch.dispatch.1
catch.dispatch.1: ; preds = %catch
%cs2 = catchswitch within %0 [label %catch.3] unwind to caller
catch.3: ; preds = %catch.dispatch.1
%1 = catchpad within %cs2 [ptr null, i32 64, ptr null]
catchret from %1 to label %try.cont
try.cont: ; preds = %catch.3
catchret from %0 to label %try.cont.5
try.cont.5: ; preds = %try.cont
ret i32 0
unreachable: ; preds = %catch, %entry
call void @llvm.trap()
unreachable
}
; CHECK-LABEL: test2:
; The parent function contains %entry and %try.cont.5
; CHECK: .seh_proc
; CHECK: # %entry
; CHECK: # %try.cont.5
; CHECK: retq
; The inner catch funclet contains %catch.3
; CHECK: .seh_proc
; CHECK: # %catch.3{{$}}
; CHECK: retq
; The outer catch funclet contains %catch
; CHECK: .seh_proc
; CHECK: # %catch{{$}}
; CHECK: callq _CxxThrowException
; CHECK: # %unreachable
; CHECK: ud2
define void @test3(i1 %V) #0 personality ptr @__CxxFrameHandler3 {
entry:
invoke void @g()
to label %try.cont unwind label %catch.dispatch
catch.dispatch: ; preds = %entry
%cs1 = catchswitch within none [label %catch.2] unwind label %catch.dispatch.1
catch.2: ; preds = %catch.dispatch
%0 = catchpad within %cs1 [ptr @"\01??_R0H@8", i32 0, ptr null]
tail call void @exit(i32 0) #2 [ "funclet"(token %0) ]
unreachable
catch.dispatch.1: ; preds = %catch.dispatch
%cs2 = catchswitch within none [label %catch] unwind to caller
catch: ; preds = %catch.dispatch.1
%1 = catchpad within %cs2 [ptr null, i32 64, ptr null]
tail call void @exit(i32 0) #2 [ "funclet"(token %1) ]
unreachable
try.cont: ; preds = %entry
br i1 %V, label %exit_one, label %exit_two
exit_one:
tail call void @g()
call void @llvm.trap()
unreachable
exit_two:
tail call void @g()
call void @llvm.trap()
unreachable
}
; CHECK-LABEL: test3:
; The entry funclet contains %entry and %try.cont
; CHECK: # %entry
; CHECK: # %try.cont
; CHECK: callq g
; CHECK-NOT: # exit_one
; CHECK-NOT: # exit_two
; CHECK: ud2
; The catch(...) funclet contains %catch.2
; CHECK: # %catch.2{{$}}
; CHECK: callq exit
; CHECK-NEXT: int3
; The catch(int) funclet contains %catch
; CHECK: # %catch{{$}}
; CHECK: callq exit
; CHECK-NEXT: int3
declare void @exit(i32) noreturn nounwind
declare void @_CxxThrowException(ptr, ptr)
declare i32 @__CxxFrameHandler3(...)
|