[opaque pointer type] Add textual IR support for explicit type parameter to the call...
[oota-llvm.git] / test / CodeGen / WinEH / seh-simple.ll
1 ; RUN: opt -S -winehprepare -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
2
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-pc-windows-msvc"
5
6 declare void @cleanup()
7 declare i32 @filt()
8 declare void @might_crash()
9 declare i32 @__C_specific_handler(...)
10 declare i32 @llvm.eh.typeid.for(i8*)
11
12 define i32 @simple_except_store() {
13 entry:
14   %retval = alloca i32
15   store i32 0, i32* %retval
16   invoke void @might_crash()
17           to label %return unwind label %lpad
18
19 lpad:
20   %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
21           catch i32 ()* @filt
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
26
27 __except:
28   store i32 1, i32* %retval
29   br label %return
30
31 return:
32   %r = load i32, i32* %retval
33   ret i32 %r
34
35 eh.resume:
36   resume { i8*, i32 } %ehvals
37 }
38
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]
44
45 define i32 @catch_all() {
46 entry:
47   %retval = alloca i32
48   store i32 0, i32* %retval
49   invoke void @might_crash()
50           to label %return unwind label %lpad
51
52 lpad:
53   %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
54           catch i8* null
55   store i32 1, i32* %retval
56   br label %return
57
58 return:
59   %r = load i32, i32* %retval
60   ret i32 %r
61 }
62
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]
68 ;
69 ; CHECK: catch.all:
70 ; CHECK: store i32 1, i32* %retval
71
72
73 define i32 @except_phi() {
74 entry:
75   invoke void @might_crash()
76           to label %return unwind label %lpad
77
78 lpad:
79   %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
80           catch i32 ()* @filt
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
85
86 return:
87   %r = phi i32 [0, %entry], [1, %lpad]
88   ret i32 %r
89
90 eh.resume:
91   resume { i8*, i32 } %ehvals
92 }
93
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]
99 ;
100 ; CHECK: return:
101 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ]
102 ; CHECK-NEXT: ret i32 %r
103
104 define i32 @cleanup_and_except() {
105 entry:
106   invoke void @might_crash()
107           to label %return unwind label %lpad
108
109 lpad:
110   %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
111           cleanup
112           catch i32 ()* @filt
113   call void @cleanup()
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
118
119 return:
120   %r = phi i32 [0, %entry], [1, %lpad]
121   ret i32 %r
122
123 eh.resume:
124   resume { i8*, i32 } %ehvals
125 }
126
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]
135 ;
136 ; CHECK: return:
137 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ]
138 ; CHECK-NEXT: ret i32 %r