| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 1 | ; RUN: opt -mtriple=i686-pc-windows-msvc -S -x86-winehstate  < %s | FileCheck %s | 
|  | 2 |  | 
|  | 3 | target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" | 
|  | 4 | target triple = "i686-pc-windows-msvc" | 
|  | 5 |  | 
|  | 6 | %rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] } | 
|  | 7 | %eh.CatchableType = type { i32, i8*, i32, i32, i32, i32, i8* } | 
|  | 8 | %eh.CatchableTypeArray.1 = type { i32, [1 x %eh.CatchableType*] } | 
|  | 9 | %eh.ThrowInfo = type { i32, i8*, i8*, i8* } | 
|  | 10 |  | 
|  | 11 | $"\01??_R0H@8" = comdat any | 
|  | 12 |  | 
|  | 13 | $"_CT??_R0H@84" = comdat any | 
|  | 14 |  | 
|  | 15 | $_CTA1H = comdat any | 
|  | 16 |  | 
|  | 17 | $_TI1H = comdat any | 
|  | 18 |  | 
|  | 19 | @"\01??_7type_info@@6B@" = external constant i8* | 
|  | 20 | @"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat | 
|  | 21 | @"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat | 
|  | 22 | @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0H@84"] }, section ".xdata", comdat | 
|  | 23 | @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1H to i8*) }, section ".xdata", comdat | 
|  | 24 |  | 
|  | 25 | define i32 @main() #0 personality i32 (...)* @__CxxFrameHandler3 { | 
|  | 26 | entry: | 
|  | 27 | %tmp = alloca i32, align 4 | 
|  | 28 | ; CHECK: entry: | 
|  | 29 | ; CHECK:   store i32 -1 | 
|  | 30 | ; CHECK:   call void @g(i32 3) | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 31 | ; CHECK-NEXT:   call void @g(i32 4) | 
|  | 32 | ; CHECK-NEXT:   call void @g(i32 5) | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 33 | call void @g(i32 3) | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 34 | call void @g(i32 4) | 
|  | 35 | call void @g(i32 5) | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 36 | store i32 0, i32* %tmp, align 4 | 
|  | 37 | %0 = bitcast i32* %tmp to i8* | 
|  | 38 | ; CHECK:   store i32 0 | 
|  | 39 | ; CHECK:   invoke void @_CxxThrowException( | 
|  | 40 | invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* nonnull @_TI1H) #1 | 
|  | 41 | to label %unreachable.for.entry unwind label %catch.dispatch | 
|  | 42 |  | 
|  | 43 | catch.dispatch:                                   ; preds = %entry | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 44 | %cs1 = catchswitch within none [label %catch] unwind to caller | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 45 |  | 
|  | 46 | catch:                                            ; preds = %catch.dispatch | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 47 | %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null] | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 48 | ; CHECK: catch: | 
|  | 49 | ; CHECK:   store i32 2 | 
|  | 50 | ; CHECK:   invoke void @_CxxThrowException( | 
| Joseph Tremoulet | 81e8196 | 2016-01-10 04:30:02 +0000 | [diff] [blame] | 51 | invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) [ "funclet"(token %1) ] | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 52 | to label %unreachable unwind label %catch.dispatch.1 | 
|  | 53 |  | 
|  | 54 | catch.dispatch.1:                                 ; preds = %catch | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 55 | %cs2 = catchswitch within %1 [label %catch.3] unwind to caller | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 56 | catch.3:                                          ; preds = %catch.dispatch.1 | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 57 | %2 = catchpad within %cs2 [i8* null, i32 u0x40, i8* null] | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 58 | ; CHECK: catch.3: | 
|  | 59 | ; CHECK:   store i32 3 | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 60 | ; CHECK:   call void @g(i32 1) | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 61 | ; CHECK-NEXT:   call void @g(i32 2) | 
|  | 62 | ; CHECK-NEXT:   call void @g(i32 3) | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 63 | call void @g(i32 1) | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 64 | call void @g(i32 2) | 
|  | 65 | call void @g(i32 3) | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 66 | catchret from %2 to label %try.cont | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 67 |  | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 68 | try.cont:                                         ; preds = %catch.3 | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 69 | ; CHECK: try.cont: | 
|  | 70 | ; CHECK:   store i32 1 | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 71 | ; CHECK:   call void @g(i32 2) | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 72 | ; CHECK-NEXT:   call void @g(i32 3) | 
|  | 73 | ; CHECK-NEXT:   call void @g(i32 4) | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 74 | call void @g(i32 2) | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 75 | call void @g(i32 3) | 
|  | 76 | call void @g(i32 4) | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 77 | unreachable | 
|  | 78 |  | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 79 | unreachable:                                      ; preds = %catch | 
|  | 80 | unreachable | 
|  | 81 |  | 
|  | 82 | unreachable.for.entry:                            ; preds = %entry | 
|  | 83 | unreachable | 
|  | 84 | } | 
|  | 85 |  | 
| Reid Kleckner | 84ebff4 | 2015-09-16 17:19:44 +0000 | [diff] [blame] | 86 | define i32 @nopads() #0 personality i32 (...)* @__CxxFrameHandler3 { | 
|  | 87 | ret i32 0 | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | ; CHECK-LABEL: define i32 @nopads() | 
|  | 91 | ; CHECK-NEXT: ret i32 0 | 
|  | 92 | ; CHECK-NOT: __ehhandler$nopads | 
|  | 93 |  | 
| David Majnemer | c640f86 | 2015-12-23 03:59:04 +0000 | [diff] [blame] | 94 | ; CHECK-LABEL: define void @PR25926() | 
|  | 95 | define void @PR25926() personality i32 (...)* @__CxxFrameHandler3 { | 
|  | 96 | entry: | 
|  | 97 | ; CHECK: entry: | 
|  | 98 | ; CHECK:   store i32 -1 | 
|  | 99 | ; CHECK:   store i32 0 | 
|  | 100 | ; CHECK:   invoke void @_CxxThrowException( | 
|  | 101 | invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) | 
|  | 102 | to label %unreachable unwind label %catch.dispatch | 
|  | 103 |  | 
|  | 104 | catch.dispatch:                                   ; preds = %entry | 
|  | 105 | %0 = catchswitch within none [label %catch] unwind to caller | 
|  | 106 |  | 
|  | 107 | catch:                                            ; preds = %catch.dispatch | 
|  | 108 | %1 = catchpad within %0 [i8* null, i32 64, i8* null] | 
|  | 109 | ; CHECK: catch: | 
|  | 110 | ; CHECK:   store i32 3 | 
|  | 111 | ; CHECK:   invoke void @_CxxThrowException( | 
|  | 112 | invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) [ "funclet"(token %1) ] | 
|  | 113 | to label %unreachable1 unwind label %catch.dispatch1 | 
|  | 114 |  | 
|  | 115 | catch.dispatch1:                                  ; preds = %catch | 
|  | 116 | %2 = catchswitch within %1 [label %catch2] unwind label %ehcleanup | 
|  | 117 |  | 
|  | 118 | catch2:                                           ; preds = %catch.dispatch1 | 
|  | 119 | %3 = catchpad within %2 [i8* null, i32 64, i8* null] | 
|  | 120 | catchret from %3 to label %try.cont | 
|  | 121 |  | 
|  | 122 | try.cont:                                         ; preds = %catch2 | 
|  | 123 | ; CHECK: try.cont: | 
|  | 124 | ; CHECK:   store i32 1 | 
|  | 125 | ; CHECK:   call void @dtor() | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 126 | ; CHECK-NEXT:   call void @dtor() | 
|  | 127 | ; CHECK-NEXT:   call void @dtor() | 
|  | 128 | call void @dtor() #3 [ "funclet"(token %1) ] | 
|  | 129 | call void @dtor() #3 [ "funclet"(token %1) ] | 
| David Majnemer | c640f86 | 2015-12-23 03:59:04 +0000 | [diff] [blame] | 130 | call void @dtor() #3 [ "funclet"(token %1) ] | 
|  | 131 | catchret from %1 to label %try.cont4 | 
|  | 132 |  | 
|  | 133 | try.cont4:                                        ; preds = %try.cont | 
|  | 134 | ret void | 
|  | 135 |  | 
|  | 136 | ehcleanup:                                        ; preds = %catch.dispatch1 | 
|  | 137 | %4 = cleanuppad within %1 [] | 
|  | 138 | ; CHECK: ehcleanup: | 
| David Majnemer | c640f86 | 2015-12-23 03:59:04 +0000 | [diff] [blame] | 139 | ; CHECK:   call void @dtor() | 
|  | 140 | call void @dtor() #3 [ "funclet"(token %4) ] | 
|  | 141 | cleanupret from %4 unwind to caller | 
|  | 142 |  | 
|  | 143 | unreachable:                                      ; preds = %entry | 
|  | 144 | unreachable | 
|  | 145 |  | 
|  | 146 | unreachable1:                                     ; preds = %catch | 
|  | 147 | unreachable | 
|  | 148 | } | 
|  | 149 |  | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 150 | ; CHECK-LABEL: define void @required_state_store( | 
|  | 151 | define void @required_state_store(i1 zeroext %cond) personality i32 (...)* @_except_handler3 { | 
|  | 152 | entry: | 
|  | 153 | %__exception_code = alloca i32, align 4 | 
|  | 154 | call void (...) @llvm.localescape(i32* nonnull %__exception_code) | 
|  | 155 | ; CHECK:   store i32 -1 | 
|  | 156 | ; CHECK:   call void @g(i32 0) | 
|  | 157 | call void @g(i32 0) | 
|  | 158 | br i1 %cond, label %if.then, label %if.end | 
|  | 159 |  | 
|  | 160 | if.then:                                          ; preds = %entry | 
|  | 161 | ; CHECK:        store i32 0 | 
|  | 162 | ; CHECK-NEXT:   invoke void @g(i32 1) | 
|  | 163 | invoke void @g(i32 1) | 
|  | 164 | to label %if.end unwind label %catch.dispatch | 
|  | 165 |  | 
|  | 166 | catch.dispatch:                                   ; preds = %if.then | 
|  | 167 | %0 = catchswitch within none [label %__except.ret] unwind to caller | 
|  | 168 |  | 
|  | 169 | __except.ret:                                     ; preds = %catch.dispatch | 
|  | 170 | %1 = catchpad within %0 [i8* bitcast (i32 ()* @"\01?filt$0@0@required_state_store@@" to i8*)] | 
|  | 171 | catchret from %1 to label %if.end | 
|  | 172 |  | 
|  | 173 | if.end:                                           ; preds = %if.then, %__except.ret, %entry | 
|  | 174 | ; CHECK:        store i32 -1 | 
|  | 175 | ; CHECK-NEXT:   call void @dtor() | 
|  | 176 | call void @dtor() | 
|  | 177 | ret void | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | define internal i32 @"\01?filt$0@0@required_state_store@@"() { | 
|  | 181 | entry: | 
|  | 182 | %0 = tail call i8* @llvm.frameaddress(i32 1) | 
|  | 183 | %1 = tail call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (i1)* @required_state_store to i8*), i8* %0) | 
|  | 184 | %2 = tail call i8* @llvm.localrecover(i8* bitcast (void (i1)* @required_state_store to i8*), i8* %1, i32 0) | 
|  | 185 | %__exception_code = bitcast i8* %2 to i32* | 
|  | 186 | %3 = getelementptr inbounds i8, i8* %0, i32 -20 | 
|  | 187 | %4 = bitcast i8* %3 to { i32*, i8* }** | 
|  | 188 | %5 = load { i32*, i8* }*, { i32*, i8* }** %4, align 4 | 
|  | 189 | %6 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %5, i32 0, i32 0 | 
|  | 190 | %7 = load i32*, i32** %6, align 4 | 
|  | 191 | %8 = load i32, i32* %7, align 4 | 
|  | 192 | store i32 %8, i32* %__exception_code, align 4 | 
|  | 193 | ret i32 1 | 
|  | 194 | } | 
|  | 195 |  | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 196 | declare void @g(i32) #0 | 
|  | 197 |  | 
| David Majnemer | c640f86 | 2015-12-23 03:59:04 +0000 | [diff] [blame] | 198 | declare void @dtor() | 
|  | 199 |  | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 200 | declare x86_stdcallcc void @_CxxThrowException(i8*, %eh.ThrowInfo*) | 
|  | 201 |  | 
|  | 202 | declare i32 @__CxxFrameHandler3(...) | 
|  | 203 |  | 
| David Majnemer | 7e5937b | 2016-02-17 18:37:11 +0000 | [diff] [blame] | 204 | declare i8* @llvm.frameaddress(i32) | 
|  | 205 |  | 
|  | 206 | declare i8* @llvm.x86.seh.recoverfp(i8*, i8*) | 
|  | 207 |  | 
|  | 208 | declare i8* @llvm.localrecover(i8*, i8*, i32) | 
|  | 209 |  | 
|  | 210 | declare void @llvm.localescape(...) | 
|  | 211 |  | 
|  | 212 | declare i32 @_except_handler3(...) | 
|  | 213 |  | 
| David Majnemer | 0ad363e | 2015-08-18 19:07:12 +0000 | [diff] [blame] | 214 | attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } | 
|  | 215 | attributes #1 = { noreturn } | 
|  | 216 |  | 
|  | 217 | !llvm.ident = !{!0} | 
|  | 218 |  | 
|  | 219 | !0 = !{!"clang version 3.8.0 (trunk 245153) (llvm/trunk 245238)"} |