1 ; RUN: opt -S -winehprepare -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-pc-windows-msvc"
6 declare void @cleanup()
8 declare void @might_crash()
9 declare i32 @__C_specific_handler(...)
10 declare i32 @llvm.eh.typeid.for(i8*)
12 define i32 @simple_except_store() {
15 store i32 0, i32* %retval
16 invoke void @might_crash()
17 to label %return unwind label %lpad
20 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
22 %sel = extractvalue { i8*, i32 } %ehvals, 1
23 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
24 %matches = icmp eq i32 %sel, %filt_sel
25 br i1 %matches, label %__except, label %eh.resume
28 store i32 1, i32* %retval
32 %r = load i32, i32* %retval
36 resume { i8*, i32 } %ehvals
39 ; CHECK-LABEL: define i32 @simple_except_store()
40 ; CHECK: landingpad { i8*, i32 }
41 ; CHECK-NEXT: catch i32 ()* @filt
42 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@simple_except_store, %__except))
43 ; CHECK-NEXT: indirectbr {{.*}} [label %__except]
45 define i32 @catch_all() {
48 store i32 0, i32* %retval
49 invoke void @might_crash()
50 to label %return unwind label %lpad
53 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
55 store i32 1, i32* %retval
59 %r = load i32, i32* %retval
63 ; CHECK-LABEL: define i32 @catch_all()
64 ; CHECK: landingpad { i8*, i32 }
65 ; CHECK-NEXT: catch i8* null
66 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* null, i32 -1, i8* blockaddress(@catch_all, %catch.all))
67 ; CHECK-NEXT: indirectbr {{.*}} [label %catch.all]
70 ; CHECK: store i32 1, i32* %retval
73 define i32 @except_phi() {
75 invoke void @might_crash()
76 to label %return unwind label %lpad
79 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
81 %sel = extractvalue { i8*, i32 } %ehvals, 1
82 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
83 %matches = icmp eq i32 %sel, %filt_sel
84 br i1 %matches, label %return, label %eh.resume
87 %r = phi i32 [0, %entry], [1, %lpad]
91 resume { i8*, i32 } %ehvals
94 ; CHECK-LABEL: define i32 @except_phi()
95 ; CHECK: landingpad { i8*, i32 }
96 ; CHECK-NEXT: catch i32 ()* @filt
97 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@except_phi, %return))
98 ; CHECK-NEXT: indirectbr {{.*}} [label %return]
101 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ]
102 ; CHECK-NEXT: ret i32 %r
104 define i32 @cleanup_and_except() {
106 invoke void @might_crash()
107 to label %return unwind label %lpad
110 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
114 %sel = extractvalue { i8*, i32 } %ehvals, 1
115 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
116 %matches = icmp eq i32 %sel, %filt_sel
117 br i1 %matches, label %return, label %eh.resume
120 %r = phi i32 [0, %entry], [1, %lpad]
124 resume { i8*, i32 } %ehvals
127 ; CHECK-LABEL: define i32 @cleanup_and_except()
128 ; CHECK: landingpad { i8*, i32 }
129 ; CHECK-NEXT: cleanup
130 ; CHECK-NEXT: catch i32 ()* @filt
131 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(
132 ; CHECK: i32 0, void (i8*, i8*)* @cleanup_and_except.cleanup,
133 ; CHECK: i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@cleanup_and_except, %return))
134 ; CHECK-NEXT: indirectbr {{.*}} [label %return]
137 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ]
138 ; CHECK-NEXT: ret i32 %r