1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
4
5declare i32 @__gxx_personality_v0(...)
6declare void @__cxa_call_unexpected(i8*)
7declare void @purefn() nounwind readnone
8declare i32 @read_only() nounwind readonly
9declare i32 @nounwind_fn() nounwind
10declare i32 @fn()
11
12
13define i8* @f1() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
14; CHECK-LABEL: @f1(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    call void @llvm.trap()
17; CHECK-NEXT:    unreachable
18;
19entry:
20  %call = invoke noalias i8* undef()
21  to label %invoke.cont unwind label %lpad
22
23invoke.cont:
24  ret i8* %call
25
26lpad:
27  %0 = landingpad { i8*, i32 }
28  filter [0 x i8*] zeroinitializer
29  %1 = extractvalue { i8*, i32 } %0, 0
30  tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind
31  unreachable
32}
33
34define i8* @f2() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
35; CHECK-LABEL: @f2(
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    call void @llvm.trap()
38; CHECK-NEXT:    unreachable
39;
40entry:
41  %call = invoke noalias i8* null()
42  to label %invoke.cont unwind label %lpad
43
44invoke.cont:
45  ret i8* %call
46
47lpad:
48  %0 = landingpad { i8*, i32 }
49  filter [0 x i8*] zeroinitializer
50  %1 = extractvalue { i8*, i32 } %0, 0
51  tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind
52  unreachable
53}
54
55define i8* @f2_no_null_opt() nounwind uwtable ssp #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
56; CHECK-LABEL: @f2_no_null_opt(
57; CHECK-NEXT:  entry:
58; CHECK-NEXT:    [[CALL:%.*]] = invoke noalias i8* null()
59; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
60; CHECK:       invoke.cont:
61; CHECK-NEXT:    ret i8* [[CALL]]
62; CHECK:       lpad:
63; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
64; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
65; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0
66; CHECK-NEXT:    tail call void @__cxa_call_unexpected(i8* [[TMP1]]) #[[ATTR6:[0-9]+]]
67; CHECK-NEXT:    unreachable
68;
69entry:
70  %call = invoke noalias i8* null()
71  to label %invoke.cont unwind label %lpad
72
73invoke.cont:
74  ret i8* %call
75
76lpad:
77  %0 = landingpad { i8*, i32 }
78  filter [0 x i8*] zeroinitializer
79  %1 = extractvalue { i8*, i32 } %0, 0
80  tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind
81  unreachable
82}
83
84define i32 @f3() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
85; CHECK-LABEL: @f3(
86; CHECK-NEXT:  entry:
87; CHECK-NEXT:    ret i32 3
88;
89entry:
90  %call = invoke i32 @read_only()
91  to label %invoke.cont unwind label %lpad
92
93invoke.cont:
94  ret i32 3
95
96lpad:
97  %0 = landingpad { i8*, i32 }
98  filter [0 x i8*] zeroinitializer
99  %1 = extractvalue { i8*, i32 } %0, 0
100  tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind
101  unreachable
102}
103
104define i32 @f4() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
105; CHECK-LABEL: @f4(
106; CHECK-NEXT:  entry:
107; CHECK-NEXT:    [[CALL:%.*]] = call i32 @read_only()
108; CHECK-NEXT:    ret i32 [[CALL]]
109;
110entry:
111  %call = invoke i32 @read_only()
112  to label %invoke.cont unwind label %lpad
113
114invoke.cont:
115  ret i32 %call
116
117lpad:
118  %0 = landingpad { i8*, i32 }
119  filter [0 x i8*] zeroinitializer
120  %1 = extractvalue { i8*, i32 } %0, 0
121  tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind
122  unreachable
123}
124
125define i32 @f5(i1 %cond, i8* %a, i8* %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
126; CHECK-LABEL: @f5(
127; CHECK-NEXT:  entry:
128; CHECK-NEXT:    br i1 [[COND:%.*]], label [[X:%.*]], label [[Y:%.*]]
129; CHECK:       x:
130; CHECK-NEXT:    [[CALL:%.*]] = invoke i32 @fn()
131; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[LPAD:%.*]]
132; CHECK:       y:
133; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @nounwind_fn()
134; CHECK-NEXT:    br label [[CONT]]
135; CHECK:       cont:
136; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[CALL]], [[X]] ], [ [[CALL2]], [[Y]] ]
137; CHECK-NEXT:    ret i32 [[PHI]]
138; CHECK:       lpad:
139; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
140; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
141; CHECK-NEXT:    tail call void @__cxa_call_unexpected(i8* [[A:%.*]]) #[[ATTR6]]
142; CHECK-NEXT:    unreachable
143;
144entry:
145  br i1 %cond, label %x, label %y
146
147x:
148  %call = invoke i32 @fn()
149  to label %cont unwind label %lpad
150
151y:
152  %call2 = invoke i32 @nounwind_fn()
153  to label %cont unwind label %lpad
154
155cont:
156  %phi = phi i32 [%call, %x], [%call2, %y]
157  ret i32 %phi
158
159lpad:
160  %phi2 = phi i8* [%a, %x], [%b, %y]
161  %0 = landingpad { i8*, i32 }
162  filter [0 x i8*] zeroinitializer
163  tail call void @__cxa_call_unexpected(i8* %phi2) noreturn nounwind
164  unreachable
165}
166
167define void @f6() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
168; CHECK-LABEL: @f6(
169; CHECK-NEXT:  entry:
170; CHECK-NEXT:    [[FOO:%.*]] = invoke i32 @fn()
171; CHECK-NEXT:    to label [[COMMON_RET:%.*]] unwind label [[LPAD:%.*]]
172; CHECK:       common.ret:
173; CHECK-NEXT:    ret void
174; CHECK:       lpad:
175; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
176; CHECK-NEXT:    cleanup
177; CHECK-NEXT:    br label [[COMMON_RET]]
178;
179entry:
180  invoke void @purefn()
181  to label %invoke.cont1 unwind label %lpad
182
183invoke.cont1:
184  %foo = invoke i32 @fn()
185  to label %invoke.cont2 unwind label %lpad
186
187invoke.cont2:
188  ret void
189
190lpad:
191  %tmp = phi i8* [ null, %invoke.cont1 ], [ null, %entry ]
192  landingpad { i8*, i32 }
193  cleanup
194  ret void
195}
196
197attributes #0 = { null_pointer_is_valid }
198