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