blob: 53f532c8eb161473d6f0475f7e97425c992903d5 [file] [log] [blame]
Andrew Kaylorcc14f382015-05-11 23:06:02 +00001; RUN: opt -mtriple=x86_64-pc-windows-msvc -winehprepare -S -o - < %s | FileCheck %s
2
3; This test was generated from the following code.
4;
5; void test1() {
6; try {
7; try {
8; throw 1;
9; } catch(...) { throw; }
10; } catch (...) { }
11; }
12; void test2() {
13; try {
14; throw 1;
15; } catch(...) {
16; try {
17; throw;
18; } catch (...) {}
19; }
20; }
21;
22; These two functions result in functionally equivalent code, but the last
23; catch block contains a call to llvm.eh.endcatch that tripped up processing
24; during development.
25;
26; The main purpose of this test is to verify that we can correctly
27; handle the case of nested landing pads that return directly to a block in
28; the parent function.
29
30; ModuleID = 'cppeh-nested-rethrow.cpp'
31target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
32target triple = "x86_64-pc-windows-msvc"
33
34%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
35%eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 }
36%eh.CatchableTypeArray.1 = type { i32, [1 x i32] }
37%eh.ThrowInfo = type { i32, i32, i32, i32 }
38
39$"\01??_R0H@8" = comdat any
40
41$"_CT??_R0H@84" = comdat any
42
43$_CTA1H = comdat any
44
45$_TI1H = comdat any
46
47@"\01??_7type_info@@6B@" = external constant i8*
48@"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
49@__ImageBase = external constant i8
50@"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 4, i32 0 }, section ".xdata", comdat
51@_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0H@84" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
52@_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.1* @_CTA1H to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat
53
54; CHECK-LABEL: define void @"\01?test1@@YAXXZ"()
55; CHECK: entry:
Reid Kleckner60381792015-07-07 22:25:32 +000056; CHECK: call void (...) @llvm.localescape
Andrew Kaylorcc14f382015-05-11 23:06:02 +000057
58; Function Attrs: nounwind uwtable
David Majnemer7fddecc2015-06-17 20:52:32 +000059define void @"\01?test1@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
Andrew Kaylorcc14f382015-05-11 23:06:02 +000060entry:
61 %tmp = alloca i32, align 4
62 %exn.slot = alloca i8*
63 %ehselector.slot = alloca i32
64 store i32 1, i32* %tmp
65 %0 = bitcast i32* %tmp to i8*
66 invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #2
67 to label %unreachable unwind label %lpad
68
69lpad: ; preds = %entry
David Majnemer7fddecc2015-06-17 20:52:32 +000070 %1 = landingpad { i8*, i32 }
Andrew Kaylorcc14f382015-05-11 23:06:02 +000071 catch i8* null
72 %2 = extractvalue { i8*, i32 } %1, 0
73 store i8* %2, i8** %exn.slot
74 %3 = extractvalue { i8*, i32 } %1, 1
75 store i32 %3, i32* %ehselector.slot
76 br label %catch
77
78catch: ; preds = %lpad
79 %exn = load i8*, i8** %exn.slot
80 call void @llvm.eh.begincatch(i8* %exn, i8* null) #1
81 invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #2
82 to label %unreachable unwind label %lpad1
83
84lpad1: ; preds = %catch
David Majnemer7fddecc2015-06-17 20:52:32 +000085 %4 = landingpad { i8*, i32 }
Andrew Kaylorcc14f382015-05-11 23:06:02 +000086 catch i8* null
87 %5 = extractvalue { i8*, i32 } %4, 0
88 store i8* %5, i8** %exn.slot
89 %6 = extractvalue { i8*, i32 } %4, 1
90 store i32 %6, i32* %ehselector.slot
91 br label %catch2
92
93catch2: ; preds = %lpad1
94 %exn3 = load i8*, i8** %exn.slot
95 call void @llvm.eh.begincatch(i8* %exn3, i8* null) #1
96 call void @llvm.eh.endcatch() #1
Sunil Srivastavad79dfcb2015-05-12 16:47:30 +000097 br label %try.cont.4
Andrew Kaylorcc14f382015-05-11 23:06:02 +000098
99; This block should not be eliminated.
Sunil Srivastavad79dfcb2015-05-12 16:47:30 +0000100; CHECK: try.cont.4:
101try.cont.4: ; preds = %catch2, %try.cont
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000102 ret void
103
104try.cont: ; No predecessors!
Sunil Srivastavad79dfcb2015-05-12 16:47:30 +0000105 br label %try.cont.4
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000106
107unreachable: ; preds = %catch, %entry
108 unreachable
109; CHECK: }
110}
111
112declare void @_CxxThrowException(i8*, %eh.ThrowInfo*)
113
114declare i32 @__CxxFrameHandler3(...)
115
116; Function Attrs: nounwind
117declare void @llvm.eh.begincatch(i8* nocapture, i8* nocapture) #1
118
119; Function Attrs: nounwind
120declare void @llvm.eh.endcatch() #1
121
122; CHECK-LABEL: define void @"\01?test2@@YAXXZ"()
123; CHECK: entry:
Reid Kleckner60381792015-07-07 22:25:32 +0000124; CHECK: call void (...) @llvm.localescape
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000125
126; Function Attrs: nounwind uwtable
David Majnemer7fddecc2015-06-17 20:52:32 +0000127define void @"\01?test2@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000128entry:
129 %tmp = alloca i32, align 4
130 %exn.slot = alloca i8*
131 %ehselector.slot = alloca i32
132 store i32 1, i32* %tmp
133 %0 = bitcast i32* %tmp to i8*
134 invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #2
135 to label %unreachable unwind label %lpad
136
137lpad: ; preds = %entry
David Majnemer7fddecc2015-06-17 20:52:32 +0000138 %1 = landingpad { i8*, i32 }
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000139 catch i8* null
140 %2 = extractvalue { i8*, i32 } %1, 0
141 store i8* %2, i8** %exn.slot
142 %3 = extractvalue { i8*, i32 } %1, 1
143 store i32 %3, i32* %ehselector.slot
144 br label %catch
145
146catch: ; preds = %lpad
147 %exn = load i8*, i8** %exn.slot
148 call void @llvm.eh.begincatch(i8* %exn, i8* null) #1
149 invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #2
150 to label %unreachable unwind label %lpad1
151
152lpad1: ; preds = %catch
David Majnemer7fddecc2015-06-17 20:52:32 +0000153 %4 = landingpad { i8*, i32 }
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000154 catch i8* null
155 %5 = extractvalue { i8*, i32 } %4, 0
156 store i8* %5, i8** %exn.slot
157 %6 = extractvalue { i8*, i32 } %4, 1
158 store i32 %6, i32* %ehselector.slot
159 br label %catch2
160
161catch2: ; preds = %lpad1
162 %exn3 = load i8*, i8** %exn.slot
163 call void @llvm.eh.begincatch(i8* %exn3, i8* null) #1
164 call void @llvm.eh.endcatch() #1
165 br label %try.cont
166
167; This block should not be eliminated.
168; CHECK: try.cont:
169; The endcatch call should be eliminated.
170; CHECK-NOT: call void @llvm.eh.endcatch()
171try.cont: ; preds = %catch2
172 call void @llvm.eh.endcatch() #1
Sunil Srivastavad79dfcb2015-05-12 16:47:30 +0000173 br label %try.cont.4
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000174
Sunil Srivastavad79dfcb2015-05-12 16:47:30 +0000175try.cont.4: ; preds = %try.cont
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000176 ret void
177
178unreachable: ; preds = %catch, %entry
179 unreachable
180; CHECK: }
181}
182
Andrew Kaylora6c5b962015-05-20 23:22:24 +0000183; The outlined test1.catch handler should return to a valid block address.
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000184; CHECK-LABEL: define internal i8* @"\01?test1@@YAXXZ.catch"(i8*, i8*)
Andrew Kaylora6c5b962015-05-20 23:22:24 +0000185; CHECK-NOT: ret i8* inttoptr (i32 1 to i8*)
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000186; CHECK: }
187
Andrew Kaylora6c5b962015-05-20 23:22:24 +0000188; The outlined test1.catch1 handler should not contain a return instruction.
Sunil Srivastavad79dfcb2015-05-12 16:47:30 +0000189; CHECK-LABEL: define internal i8* @"\01?test1@@YAXXZ.catch.1"(i8*, i8*)
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000190; CHECK-NOT: ret
191; CHECK: }
192
Andrew Kaylora6c5b962015-05-20 23:22:24 +0000193; The outlined test2.catch handler should return to a valid block address.
194; CHECK-LABEL: define internal i8* @"\01?test2@@YAXXZ.catch"(i8*, i8*)
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000195; CHECK-NOT: ret i8* inttoptr (i32 1 to i8*)
196; CHECK: }
197
Andrew Kaylora6c5b962015-05-20 23:22:24 +0000198; The outlined test2.catch2 handler should not contain a return instruction.
199; CHECK-LABEL: define internal i8* @"\01?test2@@YAXXZ.catch.2"(i8*, i8*)
200; CHECK-NOT: ret
201; CHECK: }
202
Andrew Kaylorcc14f382015-05-11 23:06:02 +0000203
204attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
205attributes #1 = { nounwind }
206attributes #2 = { noreturn }
207
208!llvm.module.flags = !{!0}
209!llvm.ident = !{!1}
210
211!0 = !{i32 1, !"PIC Level", i32 2}
212!1 = !{!"clang version 3.7.0 (trunk 236059)"}