xref: /llvm-project/llvm/test/Transforms/Attributor/range.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
4
5; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed.
6
7define i32 @test0(ptr %p) {
8; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
9; CHECK-LABEL: define {{[^@]+}}@test0
10; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
11; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]
12; CHECK-NEXT:    ret i32 [[A]]
13;
14  %a = load i32, ptr %p, !range !0
15  ret i32 %a
16}
17
18define i32 @test0-range-check(ptr %p) {
19; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
20; TUNIT-LABEL: define {{[^@]+}}@test0-range-check
21; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) #[[ATTR0]] {
22; TUNIT-NEXT:    [[A:%.*]] = tail call i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]]
23; TUNIT-NEXT:    ret i32 [[A]]
24;
25; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
26; CGSCC-LABEL: define {{[^@]+}}@test0-range-check
27; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
28; CGSCC-NEXT:    [[A:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5:[0-9]+]]
29; CGSCC-NEXT:    ret i32 [[A]]
30;
31  %a = tail call i32 @test0(ptr %p)
32  ret i32 %a
33}
34
35declare void @use3-dummy(i1, i1, i1)
36define void @use3(i1, i1, i1) {
37; CHECK-LABEL: define {{[^@]+}}@use3
38; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], i1 [[TMP2:%.*]]) {
39; CHECK-NEXT:    tail call void @use3-dummy(i1 [[TMP0]], i1 [[TMP1]], i1 [[TMP2]])
40; CHECK-NEXT:    ret void
41;
42  tail call void @use3-dummy(i1 %0, i1 %1, i1 %2)
43  ret void
44}
45
46; TEST0 icmp test
47define void @test0-icmp-check(ptr %p){
48  ; ret = [0, 10)
49; TUNIT-LABEL: define {{[^@]+}}@test0-icmp-check
50; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) {
51; TUNIT-NEXT:    [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]], !range [[RNG0]]
52; TUNIT-NEXT:    [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
53; TUNIT-NEXT:    [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
54; TUNIT-NEXT:    [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
55; TUNIT-NEXT:    [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
56; TUNIT-NEXT:    [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
57; TUNIT-NEXT:    [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
58; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
59; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
60; TUNIT-NEXT:    [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
61; TUNIT-NEXT:    [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
62; TUNIT-NEXT:    [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
63; TUNIT-NEXT:    [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
64; TUNIT-NEXT:    [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
65; TUNIT-NEXT:    [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
66; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
67; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])
68; TUNIT-NEXT:    [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
69; TUNIT-NEXT:    [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
70; TUNIT-NEXT:    [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
71; TUNIT-NEXT:    [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
72; TUNIT-NEXT:    [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
73; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
74; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false)
75; TUNIT-NEXT:    [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
76; TUNIT-NEXT:    [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
77; TUNIT-NEXT:    [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
78; TUNIT-NEXT:    [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
79; TUNIT-NEXT:    [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
80; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
81; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]])
82; TUNIT-NEXT:    [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
83; TUNIT-NEXT:    [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
84; TUNIT-NEXT:    [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
85; TUNIT-NEXT:    [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
86; TUNIT-NEXT:    [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
87; TUNIT-NEXT:    [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
88; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
89; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
90; TUNIT-NEXT:    [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
91; TUNIT-NEXT:    [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
92; TUNIT-NEXT:    [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
93; TUNIT-NEXT:    [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
94; TUNIT-NEXT:    [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
95; TUNIT-NEXT:    [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
96; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
97; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
98; TUNIT-NEXT:    [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
99; TUNIT-NEXT:    [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
100; TUNIT-NEXT:    [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
101; TUNIT-NEXT:    [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
102; TUNIT-NEXT:    [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
103; TUNIT-NEXT:    [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
104; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
105; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
106; TUNIT-NEXT:    [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
107; TUNIT-NEXT:    [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
108; TUNIT-NEXT:    [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
109; TUNIT-NEXT:    [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
110; TUNIT-NEXT:    [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
111; TUNIT-NEXT:    [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
112; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
113; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
114; TUNIT-NEXT:    ret void
115;
116; CGSCC-LABEL: define {{[^@]+}}@test0-icmp-check
117; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) {
118; CGSCC-NEXT:    [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]
119; CGSCC-NEXT:    [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
120; CGSCC-NEXT:    [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
121; CGSCC-NEXT:    [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
122; CGSCC-NEXT:    [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
123; CGSCC-NEXT:    [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
124; CGSCC-NEXT:    [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
125; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
126; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
127; CGSCC-NEXT:    [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
128; CGSCC-NEXT:    [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
129; CGSCC-NEXT:    [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
130; CGSCC-NEXT:    [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
131; CGSCC-NEXT:    [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
132; CGSCC-NEXT:    [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
133; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
134; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])
135; CGSCC-NEXT:    [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
136; CGSCC-NEXT:    [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
137; CGSCC-NEXT:    [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
138; CGSCC-NEXT:    [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
139; CGSCC-NEXT:    [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
140; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
141; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false)
142; CGSCC-NEXT:    [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
143; CGSCC-NEXT:    [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
144; CGSCC-NEXT:    [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
145; CGSCC-NEXT:    [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
146; CGSCC-NEXT:    [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
147; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
148; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]])
149; CGSCC-NEXT:    [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
150; CGSCC-NEXT:    [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
151; CGSCC-NEXT:    [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
152; CGSCC-NEXT:    [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
153; CGSCC-NEXT:    [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
154; CGSCC-NEXT:    [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
155; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
156; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
157; CGSCC-NEXT:    [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
158; CGSCC-NEXT:    [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
159; CGSCC-NEXT:    [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
160; CGSCC-NEXT:    [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
161; CGSCC-NEXT:    [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
162; CGSCC-NEXT:    [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
163; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
164; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
165; CGSCC-NEXT:    [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
166; CGSCC-NEXT:    [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
167; CGSCC-NEXT:    [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
168; CGSCC-NEXT:    [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
169; CGSCC-NEXT:    [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
170; CGSCC-NEXT:    [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
171; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
172; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
173; CGSCC-NEXT:    [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
174; CGSCC-NEXT:    [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
175; CGSCC-NEXT:    [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
176; CGSCC-NEXT:    [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
177; CGSCC-NEXT:    [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
178; CGSCC-NEXT:    [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
179; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
180; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
181; CGSCC-NEXT:    ret void
182;
183  %ret = tail call i32 @test0(ptr %p)
184
185  ; ret = [0, 10), eq
186  %cmp-eq-1 = icmp eq i32 %ret, 10
187  %cmp-eq-2 = icmp eq i32 %ret, 9
188  %cmp-eq-3 = icmp eq i32 %ret, 8
189  %cmp-eq-4 = icmp eq i32 %ret, 1
190  %cmp-eq-5 = icmp eq i32 %ret, 0
191  %cmp-eq-6 = icmp eq i32 %ret, -1
192  tail call void @use3(i1 %cmp-eq-1, i1 %cmp-eq-2, i1 %cmp-eq-3)
193  tail call void @use3(i1 %cmp-eq-4, i1 %cmp-eq-5, i1 %cmp-eq-6)
194
195  ; ret = [0, 10), ne
196  %cmp-ne-1 = icmp ne i32 %ret, 10
197  %cmp-ne-2 = icmp ne i32 %ret, 9
198  %cmp-ne-3 = icmp ne i32 %ret, 8
199  %cmp-ne-4 = icmp ne i32 %ret, 1
200  %cmp-ne-5 = icmp ne i32 %ret, 0
201  %cmp-ne-6 = icmp ne i32 %ret, -1
202  tail call void @use3(i1 %cmp-ne-1, i1 %cmp-ne-2, i1 %cmp-ne-3)
203  tail call void @use3(i1 %cmp-ne-4, i1 %cmp-ne-5, i1 %cmp-ne-6)
204
205  ; ret = [0, 10), ugt
206  %cmp-ugt-1 = icmp ugt i32 %ret, 10
207  %cmp-ugt-2 = icmp ugt i32 %ret, 9
208  %cmp-ugt-3 = icmp ugt i32 %ret, 8
209  %cmp-ugt-4 = icmp ugt i32 %ret, 1
210  %cmp-ugt-5 = icmp ugt i32 %ret, 0
211  %cmp-ugt-6 = icmp ugt i32 %ret, -1
212  tail call void @use3(i1 %cmp-ugt-1, i1 %cmp-ugt-2, i1 %cmp-ugt-3)
213  tail call void @use3(i1 %cmp-ugt-4, i1 %cmp-ugt-5, i1 %cmp-ugt-6)
214
215  ; ret = [0, 10), uge
216  %cmp-uge-1 = icmp uge i32 %ret, 10
217  %cmp-uge-2 = icmp uge i32 %ret, 9
218  %cmp-uge-3 = icmp uge i32 %ret, 8
219  %cmp-uge-4 = icmp uge i32 %ret, 1
220  %cmp-uge-5 = icmp uge i32 %ret, 0
221  %cmp-uge-6 = icmp uge i32 %ret, -1
222  tail call void @use3(i1 %cmp-uge-1, i1 %cmp-uge-2, i1 %cmp-uge-3)
223  tail call void @use3(i1 %cmp-uge-4, i1 %cmp-uge-5, i1 %cmp-uge-6)
224
225  ; ret = [0, 10), sgt
226  %cmp-sgt-1 = icmp sgt i32 %ret, 10
227  %cmp-sgt-2 = icmp sgt i32 %ret, 9
228  %cmp-sgt-3 = icmp sgt i32 %ret, 8
229  %cmp-sgt-4 = icmp sgt i32 %ret, 1
230  %cmp-sgt-5 = icmp sgt i32 %ret, 0
231  %cmp-sgt-6 = icmp sgt i32 %ret, -1
232  tail call void @use3(i1 %cmp-sgt-1, i1 %cmp-sgt-2, i1 %cmp-sgt-3)
233  tail call void @use3(i1 %cmp-sgt-4, i1 %cmp-sgt-5, i1 %cmp-sgt-6)
234
235  ; ret = [0, 10), sge
236  %cmp-gte-1 = icmp sge i32 %ret, 10
237  %cmp-gte-2 = icmp sge i32 %ret, 9
238  %cmp-gte-3 = icmp sge i32 %ret, 8
239  %cmp-gte-4 = icmp sge i32 %ret, 1
240  %cmp-gte-5 = icmp sge i32 %ret, 0
241  %cmp-gte-6 = icmp sge i32 %ret, -1
242  tail call void @use3(i1 %cmp-gte-1, i1 %cmp-gte-2, i1 %cmp-gte-3)
243  tail call void @use3(i1 %cmp-gte-4, i1 %cmp-gte-5, i1 %cmp-gte-6)
244
245  ; ret = [0, 10), slt
246  %cmp-slt-1 = icmp slt i32 %ret, 10
247  %cmp-slt-2 = icmp slt i32 %ret, 9
248  %cmp-slt-3 = icmp slt i32 %ret, 8
249  %cmp-slt-4 = icmp slt i32 %ret, 1
250  %cmp-slt-5 = icmp slt i32 %ret, 0
251  %cmp-slt-6 = icmp slt i32 %ret, -1
252  tail call void @use3(i1 %cmp-slt-1, i1 %cmp-slt-2, i1 %cmp-slt-3)
253  tail call void @use3(i1 %cmp-slt-4, i1 %cmp-slt-5, i1 %cmp-slt-6)
254
255  ; ret = [0, 10), sle
256  %cmp-lte-1 = icmp sle i32 %ret, 10
257  %cmp-lte-2 = icmp sle i32 %ret, 9
258  %cmp-lte-3 = icmp sle i32 %ret, 8
259  %cmp-lte-4 = icmp sle i32 %ret, 1
260  %cmp-lte-5 = icmp sle i32 %ret, 0
261  %cmp-lte-6 = icmp sle i32 %ret, -1
262  tail call void @use3(i1 %cmp-lte-1, i1 %cmp-lte-2, i1 %cmp-lte-3)
263  tail call void @use3(i1 %cmp-lte-4, i1 %cmp-lte-5, i1 %cmp-lte-6)
264
265  ret void
266}
267define i32 @test1(ptr %p) {
268; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
269; CHECK-LABEL: define {{[^@]+}}@test1
270; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR0]] {
271; CHECK-NEXT:    [[LOAD_10_100:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]]
272; CHECK-NEXT:    [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
273; CHECK-NEXT:    [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
274; CHECK-NEXT:    ret i32 [[MUL_10_THEN_200_1091]]
275;
276  %load-10-100 = load i32, ptr %p, !range !1
277  %add-10-then-20-110 = add i32 %load-10-100, 10
278  %mul-10-then-200-1091 = mul i32 %add-10-then-20-110, 10
279  ret i32 %mul-10-then-200-1091
280}
281
282define i1 @test1-check(ptr %p) {
283;
284; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
285; TUNIT-LABEL: define {{[^@]+}}@test1-check
286; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) #[[ATTR0]] {
287; TUNIT-NEXT:    [[RES:%.*]] = tail call i32 @test1(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]], !range [[RNG2:![0-9]+]]
288; TUNIT-NEXT:    [[CMP:%.*]] = icmp eq i32 [[RES]], 500
289; TUNIT-NEXT:    ret i1 [[CMP]]
290;
291; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
292; CGSCC-LABEL: define {{[^@]+}}@test1-check
293; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
294; CGSCC-NEXT:    [[RES:%.*]] = tail call i32 @test1(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]
295; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[RES]], 500
296; CGSCC-NEXT:    ret i1 [[CMP]]
297;
298  %res = tail call i32 @test1(ptr %p)
299  %cmp = icmp eq i32 %res, 500
300  ret i1 %cmp
301}
302
303;  TEST2
304;  int test2(int *p) { return *p == 0 ? 4 : 3; }
305;  int test2_check(int *p) {
306;    int call = test2(p);
307;    if (call == 5) {
308;      // dead block
309;      return 2;
310;    } else {
311;      return 3;
312;    }
313;  }
314
315define i32 @test2(ptr %p) {
316; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
317; CHECK-LABEL: define {{[^@]+}}@test2
318; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR0]] {
319; CHECK-NEXT:  entry:
320; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 4
321; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
322; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
323; CHECK-NEXT:    ret i32 [[COND]]
324;
325entry:
326  %0 = load i32, ptr %p, align 4
327  %tobool = icmp eq i32 %0, 0
328  %cond = select i1 %tobool, i32 4, i32 3
329  ret i32 %cond
330}
331
332define i32 @test2_check(ptr %p) {
333; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
334; TUNIT-LABEL: define {{[^@]+}}@test2_check
335; TUNIT-SAME: (ptr nofree readnone align 4 captures(none) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
336; TUNIT-NEXT:  entry:
337; TUNIT-NEXT:    br label [[IF_THEN:%.*]]
338; TUNIT:       if.then:
339; TUNIT-NEXT:    br label [[RETURN:%.*]]
340; TUNIT:       if.end:
341; TUNIT-NEXT:    unreachable
342; TUNIT:       return:
343; TUNIT-NEXT:    ret i32 2
344;
345; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
346; CGSCC-LABEL: define {{[^@]+}}@test2_check
347; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
348; CGSCC-NEXT:  entry:
349; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @test2(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]
350; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 5
351; CGSCC-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
352; CGSCC:       if.then:
353; CGSCC-NEXT:    br label [[RETURN:%.*]]
354; CGSCC:       if.end:
355; CGSCC-NEXT:    br label [[RETURN]]
356; CGSCC:       return:
357; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ]
358; CGSCC-NEXT:    ret i32 [[RETVAL_0]]
359;
360entry:
361  %call = tail call i32 @test2(ptr %p)
362  %cmp = icmp slt i32 %call, 5
363  br i1 %cmp, label %if.then, label %if.end
364
365if.then:                                          ; preds = %entry
366  br label %return
367
368if.end:                                           ; preds = %entry
369  br label %return
370
371return:                                           ; preds = %if.end, %if.then
372  %retval.0 = phi i32 [ 2, %if.then ], [ 3, %if.end ]
373  ret i32 %retval.0
374}
375
376; TEST 3 SECV test
377
378; void unkown();
379; int r1(unsigned int u){
380;   int sum = 0;
381;   for(int i = 0; i<100;i++){
382;     sum += i;
383;   }
384;   // sum = 50 * 49 / 2
385;   if(sum > 10000){
386;   // dead block
387;     return 20;
388;   }else {
389;     return 10;
390;   }
391; }
392; void f1(int u){
393;   if(r1(u) > 15){
394;   // deadblock
395;     unkown();
396;   }else {
397;     return;
398;   }
399; }
400
401declare dso_local void @unkown()
402
403define internal i32 @r1(i32) local_unnamed_addr {
404; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
405; TUNIT-LABEL: define {{[^@]+}}@r1
406; TUNIT-SAME: () local_unnamed_addr #[[ATTR1]] {
407; TUNIT-NEXT:    br label [[TMP4:%.*]]
408; TUNIT:       1:
409; TUNIT-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
410; TUNIT-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
411; TUNIT:       3:
412; TUNIT-NEXT:    ret i32 20
413; TUNIT:       f:
414; TUNIT-NEXT:    ret i32 10
415; TUNIT:       4:
416; TUNIT-NEXT:    [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
417; TUNIT-NEXT:    [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
418; TUNIT-NEXT:    [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
419; TUNIT-NEXT:    [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
420; TUNIT-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
421; TUNIT-NEXT:    br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
422;
423; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
424; CGSCC-LABEL: define {{[^@]+}}@r1
425; CGSCC-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] {
426; CGSCC-NEXT:    br label [[TMP4:%.*]]
427; CGSCC:       1:
428; CGSCC-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
429; CGSCC-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
430; CGSCC:       3:
431; CGSCC-NEXT:    ret i32 20
432; CGSCC:       f:
433; CGSCC-NEXT:    ret i32 10
434; CGSCC:       4:
435; CGSCC-NEXT:    [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
436; CGSCC-NEXT:    [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
437; CGSCC-NEXT:    [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
438; CGSCC-NEXT:    [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
439; CGSCC-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
440; CGSCC-NEXT:    br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
441;
442  br label %5
443
4442:                                                ; preds = %5
445  %3 = icmp sgt i32 %8, 10000
446  br i1 %3, label %4, label %f
4474:
448  ret i32 20
449f:
450  ret i32 10
4515:                                                ; preds = %5, %1
452  %6 = phi i32 [ 0, %1 ], [ %9, %5 ]
453  %7 = phi i32 [ 0, %1 ], [ %8, %5 ]
454  %8 = add nuw nsw i32 %6, %7
455  %9 = add nuw nsw i32 %6, 1
456  %10 = icmp eq i32 %9, 100
457  br i1 %10, label %2, label %5
458}
459
460define void @f1(i32){
461; TUNIT-LABEL: define {{[^@]+}}@f1
462; TUNIT-SAME: (i32 [[TMP0:%.*]]) {
463; TUNIT-NEXT:    [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]]
464; TUNIT-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
465; TUNIT-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
466; TUNIT:       4:
467; TUNIT-NEXT:    tail call void @unkown()
468; TUNIT-NEXT:    br label [[TMP5]]
469; TUNIT:       5:
470; TUNIT-NEXT:    ret void
471;
472; CGSCC-LABEL: define {{[^@]+}}@f1
473; CGSCC-SAME: (i32 [[TMP0:%.*]]) {
474; CGSCC-NEXT:    [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]]
475; CGSCC-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
476; CGSCC-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
477; CGSCC:       4:
478; CGSCC-NEXT:    tail call void @unkown()
479; CGSCC-NEXT:    br label [[TMP5]]
480; CGSCC:       5:
481; CGSCC-NEXT:    ret void
482;
483  %2 = tail call i32 @r1(i32 %0)
484  %3 = icmp sgt i32 %2, 15
485  br i1 %3, label %4, label %5
486
4874:                                                ; preds = %1
488  tail call void @unkown()
489  br label %5
490
4915:                                                ; preds = %1, %4
492  ret void
493}
494
495; TEST4 LVI test
496
497; f1
498; int test4-f1(int u){
499;   if(u>=0) {
500;     return u;
501;   }else{
502;     return 0;
503;   }
504; }
505define dso_local i32 @test4-f1(i32 %u) {
506; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
507; TUNIT-LABEL: define {{[^@]+}}@test4-f1
508; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
509; TUNIT-NEXT:  entry:
510; TUNIT-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
511; TUNIT-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
512; TUNIT:       if.then:
513; TUNIT-NEXT:    br label [[RETURN]]
514; TUNIT:       return:
515; TUNIT-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
516; TUNIT-NEXT:    ret i32 [[RETVAL_0]]
517;
518; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
519; CGSCC-LABEL: define {{[^@]+}}@test4-f1
520; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] {
521; CGSCC-NEXT:  entry:
522; CGSCC-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
523; CGSCC-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
524; CGSCC:       if.then:
525; CGSCC-NEXT:    br label [[RETURN]]
526; CGSCC:       return:
527; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
528; CGSCC-NEXT:    ret i32 [[RETVAL_0]]
529;
530; FIXME: RETVAL_0 >= 0
531entry:
532  %cmp = icmp sgt i32 %u, -1
533  br i1 %cmp, label %if.then, label %return
534
535if.then:                                          ; preds = %entry
536  br label %return
537
538return:                                           ; preds = %entry, %if.then
539  %retval.0 = phi i32 [ %u, %if.then ], [ 0, %entry ]
540  ret i32 %retval.0
541}
542
543
544define dso_local i32 @test4-g1(i32 %u) {
545; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
546; TUNIT-LABEL: define {{[^@]+}}@test4-g1
547; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
548; TUNIT-NEXT:  entry:
549; TUNIT-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4]]
550; TUNIT-NEXT:    ret i32 [[CALL]]
551;
552; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
553; CGSCC-LABEL: define {{[^@]+}}@test4-g1
554; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] {
555; CGSCC-NEXT:  entry:
556; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR7:[0-9]+]]
557; CGSCC-NEXT:    ret i32 [[CALL]]
558;
559; FIXME: %call should have range [0, inf]
560
561entry:
562  %call = tail call i32 @test4-f1(i32 %u)
563  ret i32 %call
564}
565
566; f2
567; int test4-f1(int u){
568;   if(u>-1) {
569;     return u+1;
570;   }else{
571;     return 1;
572;   }
573; }
574define dso_local i32 @test4-f2(i32 %u) {
575; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
576; TUNIT-LABEL: define {{[^@]+}}@test4-f2
577; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
578; TUNIT-NEXT:  entry:
579; TUNIT-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
580; TUNIT-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
581; TUNIT:       if.then:
582; TUNIT-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
583; TUNIT-NEXT:    br label [[RETURN:%.*]]
584; TUNIT:       if.else:
585; TUNIT-NEXT:    br label [[RETURN]]
586; TUNIT:       return:
587; TUNIT-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
588; TUNIT-NEXT:    ret i32 [[RETVAL_0]]
589;
590; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
591; CGSCC-LABEL: define {{[^@]+}}@test4-f2
592; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] {
593; CGSCC-NEXT:  entry:
594; CGSCC-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
595; CGSCC-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
596; CGSCC:       if.then:
597; CGSCC-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
598; CGSCC-NEXT:    br label [[RETURN:%.*]]
599; CGSCC:       if.else:
600; CGSCC-NEXT:    br label [[RETURN]]
601; CGSCC:       return:
602; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
603; CGSCC-NEXT:    ret i32 [[RETVAL_0]]
604;
605entry:
606  %cmp = icmp sgt i32 %u, -1
607  br i1 %cmp, label %if.then, label %if.else
608
609if.then:                                          ; preds = %entry
610  %add = add nuw nsw i32 %u, 1
611  br label %return
612
613if.else:                                          ; preds = %entry
614  br label %return
615
616return:                                           ; preds = %if.else, %if.then
617  %retval.0 = phi i32 [ %add, %if.then ], [ 1, %if.else ]
618  ret i32 %retval.0
619}
620
621
622define dso_local i32 @test4-g2(i32 %u) {
623; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
624; TUNIT-LABEL: define {{[^@]+}}@test4-g2
625; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
626; TUNIT-NEXT:  entry:
627; TUNIT-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR4]], !range [[RNG3:![0-9]+]]
628; TUNIT-NEXT:    ret i32 [[CALL]]
629;
630; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
631; CGSCC-LABEL: define {{[^@]+}}@test4-g2
632; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3]] {
633; CGSCC-NEXT:  entry:
634; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR7]]
635; CGSCC-NEXT:    ret i32 [[CALL]]
636;
637entry:
638  %call = tail call i32 @test4-f2(i32 %u)
639  ret i32 %call
640}
641
642define dso_local i32 @test-5() {
643; TUNIT-LABEL: define {{[^@]+}}@test-5() {
644; TUNIT-NEXT:  entry:
645; TUNIT-NEXT:    [[CALL:%.*]] = call i32 @rec(i32 noundef 0)
646; TUNIT-NEXT:    ret i32 [[CALL]]
647;
648; CGSCC-LABEL: define {{[^@]+}}@test-5() {
649; CGSCC-NEXT:  entry:
650; CGSCC-NEXT:    [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0)
651; CGSCC-NEXT:    ret i32 [[CALL]]
652;
653entry:
654  %call = call i32 @rec(i32 0)
655  ret i32 %call
656}
657define internal i32 @rec(i32 %depth) {
658; CHECK-LABEL: define {{[^@]+}}@rec
659; CHECK-SAME: (i32 [[DEPTH:%.*]]) {
660; CHECK-NEXT:  entry:
661; CHECK-NEXT:    [[CALL:%.*]] = call i32 @foo(i32 [[DEPTH]])
662; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[CALL]], 0
663; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
664; CHECK:       if.then:
665; CHECK-NEXT:    br label [[RETURN:%.*]]
666; CHECK:       if.end:
667; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[DEPTH]], 10
668; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END3:%.*]]
669; CHECK:       if.then1:
670; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[DEPTH]], 1
671; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @rec(i32 [[ADD]])
672; CHECK-NEXT:    br label [[IF_END3]]
673; CHECK:       if.end3:
674; CHECK-NEXT:    br label [[RETURN]]
675; CHECK:       return:
676; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ 1, [[IF_END3]] ]
677; CHECK-NEXT:    ret i32 [[RETVAL_0]]
678;
679entry:
680  %call = call i32 @foo(i32 %depth)
681  %tobool = icmp ne i32 %call, 0
682  br i1 %tobool, label %if.then, label %if.end
683
684if.then:                                          ; preds = %entry
685  br label %return
686
687if.end:                                           ; preds = %entry
688  %cmp = icmp slt i32 %depth, 10
689  br i1 %cmp, label %if.then1, label %if.end3
690
691if.then1:                                         ; preds = %if.end
692  %add = add nsw i32 %depth, 1
693  %call2 = call i32 @rec(i32 %add)
694  br label %if.end3
695
696if.end3:                                          ; preds = %if.then1, %if.end
697  br label %return
698
699return:                                           ; preds = %if.end3, %if.then
700  %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end3 ]
701  ret i32 %retval.0
702}
703declare dso_local i32 @foo(i32)
704
705
706; Examples taken from https://llvm.discourse.group/t/impossible-condition-optimization/461/1
707;
708; The important part is that we return a constant (false)
709;
710; {
711
712; FIXME: All but the return is not needed anymore
713define dso_local zeroext i1 @phi(i32 %arg) {
714; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
715; TUNIT-LABEL: define {{[^@]+}}@phi
716; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
717; TUNIT-NEXT:  bb:
718; TUNIT-NEXT:    [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
719; TUNIT-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
720; TUNIT:       bb1:
721; TUNIT-NEXT:    br label [[BB3:%.*]]
722; TUNIT:       bb2:
723; TUNIT-NEXT:    br label [[BB3]]
724; TUNIT:       bb3:
725; TUNIT-NEXT:    [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
726; TUNIT-NEXT:    br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
727; TUNIT:       bb5:
728; TUNIT-NEXT:    br label [[BB9:%.*]]
729; TUNIT:       bb7:
730; TUNIT-NEXT:    br label [[BB9]]
731; TUNIT:       bb9:
732; TUNIT-NEXT:    br label [[BB12:%.*]]
733; TUNIT:       bb11:
734; TUNIT-NEXT:    unreachable
735; TUNIT:       bb12:
736; TUNIT-NEXT:    br label [[BB13:%.*]]
737; TUNIT:       bb13:
738; TUNIT-NEXT:    ret i1 false
739;
740; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
741; CGSCC-LABEL: define {{[^@]+}}@phi
742; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {
743; CGSCC-NEXT:  bb:
744; CGSCC-NEXT:    [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
745; CGSCC-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
746; CGSCC:       bb1:
747; CGSCC-NEXT:    br label [[BB3:%.*]]
748; CGSCC:       bb2:
749; CGSCC-NEXT:    br label [[BB3]]
750; CGSCC:       bb3:
751; CGSCC-NEXT:    [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
752; CGSCC-NEXT:    br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
753; CGSCC:       bb5:
754; CGSCC-NEXT:    br label [[BB9:%.*]]
755; CGSCC:       bb7:
756; CGSCC-NEXT:    br label [[BB9]]
757; CGSCC:       bb9:
758; CGSCC-NEXT:    br label [[BB12:%.*]]
759; CGSCC:       bb11:
760; CGSCC-NEXT:    unreachable
761; CGSCC:       bb12:
762; CGSCC-NEXT:    br label [[BB13:%.*]]
763; CGSCC:       bb13:
764; CGSCC-NEXT:    ret i1 false
765;
766bb:
767  %tmp = icmp sgt i32 %arg, 5
768  br i1 %tmp, label %bb1, label %bb2
769
770bb1:                                              ; preds = %bb
771  br label %bb3
772
773bb2:                                              ; preds = %bb
774  br label %bb3
775
776bb3:                                              ; preds = %bb2, %bb1
777  %.02 = phi i32 [ 1, %bb1 ], [ 2, %bb2 ]
778  %tmp4 = icmp sgt i32 %arg, 10
779  br i1 %tmp4, label %bb5, label %bb7
780
781bb5:                                              ; preds = %bb3
782  %tmp6 = add nsw i32 %.02, 1
783  br label %bb9
784
785bb7:                                              ; preds = %bb3
786  %tmp8 = add nsw i32 %.02, 2
787  br label %bb9
788
789bb9:                                              ; preds = %bb7, %bb5
790  %.01 = phi i32 [ %tmp6, %bb5 ], [ %tmp8, %bb7 ]
791  %tmp10 = icmp eq i32 %.01, 5
792  br i1 %tmp10, label %bb11, label %bb12
793
794bb11:                                             ; preds = %bb9
795  br label %bb13
796
797bb12:                                             ; preds = %bb9
798  br label %bb13
799
800bb13:                                             ; preds = %bb12, %bb11
801  %.0 = phi i1 [ true, %bb11 ], [ false, %bb12 ]
802  ret i1 %.0
803}
804
805define dso_local i1 @select(i32 %a) local_unnamed_addr #0 {
806; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
807; TUNIT-LABEL: define {{[^@]+}}@select
808; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
809; TUNIT-NEXT:  entry:
810; TUNIT-NEXT:    ret i1 false
811;
812; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
813; CGSCC-LABEL: define {{[^@]+}}@select
814; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
815; CGSCC-NEXT:  entry:
816; CGSCC-NEXT:    ret i1 false
817;
818entry:
819  %cmp = icmp sgt i32 %a, 5
820  %. = select i1 %cmp, i32 1, i32 2
821  %cmp1 = icmp sgt i32 %a, 10
822  %y.0.v = select i1 %cmp1, i32 1, i32 2
823  %y.0 = add nuw nsw i32 %., %y.0.v
824  %cmp6 = icmp eq i32 %y.0, 5
825  ret i1 %cmp6
826}
827
828define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {
829; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
830; TUNIT-LABEL: define {{[^@]+}}@select_zext
831; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
832; TUNIT-NEXT:  entry:
833; TUNIT-NEXT:    ret i32 0
834;
835; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
836; CGSCC-LABEL: define {{[^@]+}}@select_zext
837; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
838; CGSCC-NEXT:  entry:
839; CGSCC-NEXT:    ret i32 0
840;
841entry:
842  %cmp = icmp sgt i32 %a, 5
843  %. = select i1 %cmp, i32 1, i32 2
844  %cmp1 = icmp sgt i32 %a, 10
845  %y.0.v = select i1 %cmp1, i32 1, i32 2
846  %y.0 = add nuw nsw i32 %., %y.0.v
847  %cmp6 = icmp eq i32 %y.0, 5
848  %.13 = zext i1 %cmp6 to i32
849  ret i32 %.13
850}
851
852define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 {
853; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
854; TUNIT-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
855; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
856; TUNIT-NEXT:  entry:
857; TUNIT-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
858; TUNIT-NEXT:    [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2
859; TUNIT-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], 10
860; TUNIT-NEXT:    [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2
861; TUNIT-NEXT:    [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]
862; TUNIT-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5
863; TUNIT-NEXT:    [[I2P:%.*]] = inttoptr i1 [[CMP6]] to ptr
864; TUNIT-NEXT:    [[P2I:%.*]] = ptrtoint ptr [[I2P]] to i64
865; TUNIT-NEXT:    ret i64 [[P2I]]
866;
867; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
868; CGSCC-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
869; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
870; CGSCC-NEXT:  entry:
871; CGSCC-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
872; CGSCC-NEXT:    [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2
873; CGSCC-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], 10
874; CGSCC-NEXT:    [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2
875; CGSCC-NEXT:    [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]
876; CGSCC-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5
877; CGSCC-NEXT:    [[I2P:%.*]] = inttoptr i1 [[CMP6]] to ptr
878; CGSCC-NEXT:    [[P2I:%.*]] = ptrtoint ptr [[I2P]] to i64
879; CGSCC-NEXT:    ret i64 [[P2I]]
880;
881entry:
882  %cmp = icmp sgt i32 %a, 5
883  %. = select i1 %cmp, i32 1, i32 2
884  %cmp1 = icmp sgt i32 %a, 10
885  %y.0.v = select i1 %cmp1, i32 1, i32 2
886  %y.0 = add nuw nsw i32 %., %y.0.v
887  %cmp6 = icmp eq i32 %y.0, 5
888  %i2p = inttoptr i1 %cmp6 to ptr
889  %p2i = ptrtoint ptr %i2p to i64
890  ret i64 %p2i
891}
892
893; }
894
895define i1 @f_fcmp(float %a, float %b) {
896; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
897; TUNIT-LABEL: define {{[^@]+}}@f_fcmp
898; TUNIT-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] {
899; TUNIT-NEXT:    [[R:%.*]] = fcmp uge float [[A]], [[B]]
900; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
901; TUNIT-NEXT:    ret i1 [[S]]
902;
903; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
904; CGSCC-LABEL: define {{[^@]+}}@f_fcmp
905; CGSCC-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR2]] {
906; CGSCC-NEXT:    [[R:%.*]] = fcmp uge float [[A]], [[B]]
907; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
908; CGSCC-NEXT:    ret i1 [[S]]
909;
910  %r = fcmp uge float %a, %b
911  %s = select i1 %r, i1 %r, i1 0
912  ret i1 %s
913}
914define i1 @d_fcmp(double %a, double %b) {
915; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
916; TUNIT-LABEL: define {{[^@]+}}@d_fcmp
917; TUNIT-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] {
918; TUNIT-NEXT:    [[R:%.*]] = fcmp oeq double [[A]], [[B]]
919; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
920; TUNIT-NEXT:    ret i1 [[S]]
921;
922; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
923; CGSCC-LABEL: define {{[^@]+}}@d_fcmp
924; CGSCC-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR2]] {
925; CGSCC-NEXT:    [[R:%.*]] = fcmp oeq double [[A]], [[B]]
926; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
927; CGSCC-NEXT:    ret i1 [[S]]
928;
929  %r = fcmp oeq double %a, %b
930  %s = select i1 %r, i1 %r, i1 0
931  ret i1 %s
932}
933define i1 @dp_icmp(ptr %a, ptr %b) {
934; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
935; TUNIT-LABEL: define {{[^@]+}}@dp_icmp
936; TUNIT-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR1]] {
937; TUNIT-NEXT:    [[R:%.*]] = icmp sge ptr [[A]], [[B]]
938; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
939; TUNIT-NEXT:    ret i1 [[S]]
940;
941; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
942; CGSCC-LABEL: define {{[^@]+}}@dp_icmp
943; CGSCC-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR2]] {
944; CGSCC-NEXT:    [[R:%.*]] = icmp sge ptr [[A]], [[B]]
945; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
946; CGSCC-NEXT:    ret i1 [[S]]
947;
948  %r = icmp sge ptr %a, %b
949  %s = select i1 %r, i1 %r, i1 0
950  ret i1 %s
951}
952define i1 @ip_icmp(ptr %a, ptr %b) {
953; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
954; TUNIT-LABEL: define {{[^@]+}}@ip_icmp
955; TUNIT-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR1]] {
956; TUNIT-NEXT:    [[R:%.*]] = icmp ult ptr [[A]], [[B]]
957; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
958; TUNIT-NEXT:    ret i1 [[S]]
959;
960; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
961; CGSCC-LABEL: define {{[^@]+}}@ip_icmp
962; CGSCC-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR2]] {
963; CGSCC-NEXT:    [[R:%.*]] = icmp ult ptr [[A]], [[B]]
964; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
965; CGSCC-NEXT:    ret i1 [[S]]
966;
967  %r = icmp ult ptr %a, %b
968  %s = select i1 %r, i1 %r, i1 0
969  ret i1 %s
970}
971define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, ptr %dpb, ptr %ipa, ptr %ipb) {
972; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
973; TUNIT-LABEL: define {{[^@]+}}@fcmp_caller
974; TUNIT-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR1]] {
975; TUNIT-NEXT:    [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]]
976; TUNIT-NEXT:    [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]]
977; TUNIT-NEXT:    [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR4]]
978; TUNIT-NEXT:    [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR4]]
979; TUNIT-NEXT:    [[O1:%.*]] = or i1 [[R1]], [[R2]]
980; TUNIT-NEXT:    [[O2:%.*]] = or i1 [[R3]], [[R4]]
981; TUNIT-NEXT:    [[O3:%.*]] = or i1 [[O1]], [[O2]]
982; TUNIT-NEXT:    ret i1 [[O3]]
983;
984; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
985; CGSCC-LABEL: define {{[^@]+}}@fcmp_caller
986; CGSCC-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR3]] {
987; CGSCC-NEXT:    [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR7]]
988; CGSCC-NEXT:    [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR7]]
989; CGSCC-NEXT:    [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR7]]
990; CGSCC-NEXT:    [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR7]]
991; CGSCC-NEXT:    [[O1:%.*]] = or i1 [[R1]], [[R2]]
992; CGSCC-NEXT:    [[O2:%.*]] = or i1 [[R3]], [[R4]]
993; CGSCC-NEXT:    [[O3:%.*]] = or i1 [[O1]], [[O2]]
994; CGSCC-NEXT:    ret i1 [[O3]]
995;
996  %r1 = call i1 @f_fcmp(float %fa, float %fb)
997  %r2 = call i1 @d_fcmp(double %da, double %db)
998  %r3 = call i1 @dp_icmp(ptr %dpa, ptr %dpb)
999  %r4 = call i1 @ip_icmp(ptr %ipa, ptr %ipb)
1000  %o1 = or i1 %r1, %r2
1001  %o2 = or i1 %r3, %r4
1002  %o3 = or i1 %o1, %o2
1003  ret i1 %o3
1004}
1005
1006define i8 @ret_two() {
1007; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1008; TUNIT-LABEL: define {{[^@]+}}@ret_two
1009; TUNIT-SAME: () #[[ATTR1]] {
1010; TUNIT-NEXT:    ret i8 2
1011;
1012; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1013; CGSCC-LABEL: define {{[^@]+}}@ret_two
1014; CGSCC-SAME: () #[[ATTR2]] {
1015; CGSCC-NEXT:    ret i8 2
1016;
1017  ret i8 2
1018}
1019define i8 @ret_undef() {
1020; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1021; TUNIT-LABEL: define {{[^@]+}}@ret_undef
1022; TUNIT-SAME: () #[[ATTR1]] {
1023; TUNIT-NEXT:    ret i8 undef
1024;
1025; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1026; CGSCC-LABEL: define {{[^@]+}}@ret_undef
1027; CGSCC-SAME: () #[[ATTR2]] {
1028; CGSCC-NEXT:    ret i8 undef
1029;
1030  ret i8 undef
1031}
1032
1033; Verify we collapse undef to a value and return something non-undef here.
1034define i8 @undef_collapse_1() {
1035; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1036; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_1
1037; TUNIT-SAME: () #[[ATTR1]] {
1038; TUNIT-NEXT:    ret i8 0
1039;
1040; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1041; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_1
1042; CGSCC-SAME: () #[[ATTR3]] {
1043; CGSCC-NEXT:    [[C:%.*]] = call i8 @ret_undef() #[[ATTR7]]
1044; CGSCC-NEXT:    [[S:%.*]] = shl i8 [[C]], 2
1045; CGSCC-NEXT:    ret i8 [[S]]
1046;
1047  %c = call i8 @ret_undef()
1048  %s = shl i8 %c, 2
1049  ret i8 %s
1050}
1051
1052; Verify we collapse undef to a value and return something non-undef here.
1053define i8 @undef_collapse_2() {
1054; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1055; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_2
1056; TUNIT-SAME: () #[[ATTR1]] {
1057; TUNIT-NEXT:    ret i8 0
1058;
1059; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1060; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_2
1061; CGSCC-SAME: () #[[ATTR3]] {
1062; CGSCC-NEXT:    [[C:%.*]] = call i8 @ret_two() #[[ATTR7]]
1063; CGSCC-NEXT:    [[S:%.*]] = shl i8 undef, [[C]]
1064; CGSCC-NEXT:    ret i8 [[S]]
1065;
1066  %c = call i8 @ret_two()
1067  %s = shl i8 undef, %c
1068  ret i8 %s
1069}
1070
1071define i8 @undef_collapse_caller() {
1072;
1073; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1074; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_caller
1075; TUNIT-SAME: () #[[ATTR1]] {
1076; TUNIT-NEXT:    ret i8 0
1077;
1078; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1079; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_caller
1080; CGSCC-SAME: () #[[ATTR3]] {
1081; CGSCC-NEXT:    [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR7]]
1082; CGSCC-NEXT:    [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR7]]
1083; CGSCC-NEXT:    [[A:%.*]] = add i8 [[C1]], [[C2]]
1084; CGSCC-NEXT:    ret i8 [[A]]
1085;
1086  %c1 = call i8 @undef_collapse_1()
1087  %c2 = call i8 @undef_collapse_2()
1088  %a = add i8 %c1, %c2
1089  ret i8 %a
1090}
1091
1092define i32 @ret1or2(i1 %c) {
1093; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1094; TUNIT-LABEL: define {{[^@]+}}@ret1or2
1095; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
1096; TUNIT-NEXT:    [[S:%.*]] = select i1 [[C]], i32 1, i32 2
1097; TUNIT-NEXT:    ret i32 [[S]]
1098;
1099; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1100; CGSCC-LABEL: define {{[^@]+}}@ret1or2
1101; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
1102; CGSCC-NEXT:    [[S:%.*]] = select i1 [[C]], i32 1, i32 2
1103; CGSCC-NEXT:    ret i32 [[S]]
1104;
1105  %s = select i1 %c, i32 1, i32 2
1106  ret i32 %s
1107}
1108define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
1109;
1110; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1111; TUNIT-LABEL: define {{[^@]+}}@callee_range_1
1112; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] {
1113; TUNIT-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
1114; TUNIT-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
1115; TUNIT-NEXT:    [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
1116; TUNIT-NEXT:    [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
1117; TUNIT-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 4
1118; TUNIT-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1119; TUNIT-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1120; TUNIT-NEXT:    ret i1 [[F]]
1121;
1122; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1123; CGSCC-LABEL: define {{[^@]+}}@callee_range_1
1124; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] {
1125; CGSCC-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
1126; CGSCC-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
1127; CGSCC-NEXT:    [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
1128; CGSCC-NEXT:    [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
1129; CGSCC-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 4
1130; CGSCC-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1131; CGSCC-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1132; CGSCC-NEXT:    ret i1 [[F]]
1133;
1134  %r1 = call i32 @ret1or2(i1 %c1)
1135  %r2 = call i32 @ret1or2(i1 %c2)
1136  %indirection = select i1 %c3, i32 %r1, i32 %r2
1137  %a = add i32 %r1, %indirection
1138  %i1 = icmp sle i32 %a, 4
1139  %i2 = icmp sge i32 %a, 2
1140  %f = and i1 %i1, %i2
1141  ret i1 %f
1142}
1143
1144define i1 @callee_range_2(i1 %c1, i1 %c2) {
1145;
1146; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1147; TUNIT-LABEL: define {{[^@]+}}@callee_range_2
1148; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {
1149; TUNIT-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
1150; TUNIT-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
1151; TUNIT-NEXT:    [[A:%.*]] = add i32 [[R1]], [[R2]]
1152; TUNIT-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 3
1153; TUNIT-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1154; TUNIT-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1155; TUNIT-NEXT:    ret i1 [[F]]
1156;
1157; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1158; CGSCC-LABEL: define {{[^@]+}}@callee_range_2
1159; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] {
1160; CGSCC-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
1161; CGSCC-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
1162; CGSCC-NEXT:    [[A:%.*]] = add i32 [[R1]], [[R2]]
1163; CGSCC-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 3
1164; CGSCC-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1165; CGSCC-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1166; CGSCC-NEXT:    ret i1 [[F]]
1167;
1168  %r1 = call i32 @ret1or2(i1 %c1)
1169  %r2 = call i32 @ret1or2(i1 %c2)
1170  %a = add i32 %r1, %r2
1171  %i1 = icmp sle i32 %a, 3
1172  %i2 = icmp sge i32 %a, 2
1173  %f = and i1 %i1, %i2
1174  ret i1 %f
1175}
1176
1177
1178define i32 @ret100() {
1179; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1180; TUNIT-LABEL: define {{[^@]+}}@ret100
1181; TUNIT-SAME: () #[[ATTR1]] {
1182; TUNIT-NEXT:    ret i32 100
1183;
1184; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1185; CGSCC-LABEL: define {{[^@]+}}@ret100
1186; CGSCC-SAME: () #[[ATTR2]] {
1187; CGSCC-NEXT:    ret i32 100
1188;
1189  ret i32 100
1190}
1191
1192define i1 @ctx_adjustment(i32 %V) {
1193;
1194; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1195; TUNIT-LABEL: define {{[^@]+}}@ctx_adjustment
1196; TUNIT-SAME: (i32 [[V:%.*]]) #[[ATTR1]] {
1197; TUNIT-NEXT:    [[C1:%.*]] = icmp sge i32 [[V]], 100
1198; TUNIT-NEXT:    br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1199; TUNIT:       if.true:
1200; TUNIT-NEXT:    br label [[END:%.*]]
1201; TUNIT:       if.false:
1202; TUNIT-NEXT:    br label [[END]]
1203; TUNIT:       end:
1204; TUNIT-NEXT:    [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
1205; TUNIT-NEXT:    [[C2:%.*]] = icmp sge i32 [[PHI]], 100
1206; TUNIT-NEXT:    ret i1 [[C2]]
1207;
1208; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1209; CGSCC-LABEL: define {{[^@]+}}@ctx_adjustment
1210; CGSCC-SAME: (i32 [[V:%.*]]) #[[ATTR3]] {
1211; CGSCC-NEXT:    [[C1:%.*]] = icmp sge i32 [[V]], 100
1212; CGSCC-NEXT:    br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1213; CGSCC:       if.true:
1214; CGSCC-NEXT:    br label [[END:%.*]]
1215; CGSCC:       if.false:
1216; CGSCC-NEXT:    [[CALL:%.*]] = call i32 @ret100() #[[ATTR7]]
1217; CGSCC-NEXT:    br label [[END]]
1218; CGSCC:       end:
1219; CGSCC-NEXT:    [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ]
1220; CGSCC-NEXT:    [[C2:%.*]] = icmp sge i32 [[PHI]], 100
1221; CGSCC-NEXT:    ret i1 [[C2]]
1222;
1223  %c1 = icmp sge i32 %V, 100
1224  br i1 %c1, label %if.true, label %if.false
1225if.true:
1226  br label %end
1227if.false:
1228  %call = call i32 @ret100()
1229  br label %end
1230end:
1231  %phi = phi i32 [ %V, %if.true ], [ %call, %if.false ]
1232  %c2 = icmp sge i32 %phi, 100
1233  ret i1 %c2
1234}
1235
1236
1237define i32 @func(i1 %c) {
1238; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1239; TUNIT-LABEL: define {{[^@]+}}@func
1240; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
1241; TUNIT-NEXT:    [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
1242; TUNIT-NEXT:    ret i32 [[RET]]
1243;
1244; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1245; CGSCC-LABEL: define {{[^@]+}}@func
1246; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
1247; CGSCC-NEXT:    [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
1248; CGSCC-NEXT:    ret i32 [[RET]]
1249;
1250  %ret = select i1 %c, i32 0, i32 1
1251  ret i32 %ret
1252}
1253
1254define i32 @simplify_callsite_argument(i1 %d) {
1255; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1256; TUNIT-LABEL: define {{[^@]+}}@simplify_callsite_argument
1257; TUNIT-SAME: (i1 [[D:%.*]]) #[[ATTR1]] {
1258; TUNIT-NEXT:    [[C:%.*]] = select i1 [[D]], i1 true, i1 false
1259; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1260; TUNIT:       t:
1261; TUNIT-NEXT:    [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR4]]
1262; TUNIT-NEXT:    ret i32 [[RET1]]
1263; TUNIT:       f:
1264; TUNIT-NEXT:    [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR4]]
1265; TUNIT-NEXT:    ret i32 [[RET2]]
1266;
1267; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1268; CGSCC-LABEL: define {{[^@]+}}@simplify_callsite_argument
1269; CGSCC-SAME: (i1 [[D:%.*]]) #[[ATTR3]] {
1270; CGSCC-NEXT:    [[C:%.*]] = select i1 [[D]], i1 true, i1 false
1271; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1272; CGSCC:       t:
1273; CGSCC-NEXT:    [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR7]]
1274; CGSCC-NEXT:    ret i32 [[RET1]]
1275; CGSCC:       f:
1276; CGSCC-NEXT:    [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR7]]
1277; CGSCC-NEXT:    ret i32 [[RET2]]
1278;
1279  %c = select i1 %d, i1 true, i1 false
1280  br i1 %c, label %t, label %f
1281t:
1282  %ret1 = call i32 @func(i1 %c)
1283  ret i32 %ret1
1284f:
1285  %ret2 = call i32 @func(i1 false)
1286  ret i32 %ret2
1287}
1288
1289define internal i32 @less_than_65536(i32 %arg) {
1290;
1291; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1292; CGSCC-LABEL: define {{[^@]+}}@less_than_65536
1293; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {
1294; CGSCC-NEXT:    [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536
1295; CGSCC-NEXT:    ret i32 [[SHRINKED]]
1296;
1297  %shrinked = udiv i32 %arg, 65536
1298  ret i32 %shrinked
1299}
1300
1301define internal i1 @is_less_than_65536(i32 %arg) {
1302; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1303; CGSCC-LABEL: define {{[^@]+}}@is_less_than_65536
1304; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {
1305; CGSCC-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536
1306; CGSCC-NEXT:    ret i1 [[CMP]]
1307;
1308  %cmp = icmp ult i32 %arg, 65536
1309  ret i1 %cmp
1310}
1311
1312define i1 @check_divided_range(i32 %arg) {
1313; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1314; TUNIT-LABEL: define {{[^@]+}}@check_divided_range
1315; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
1316; TUNIT-NEXT:    ret i1 true
1317;
1318; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1319; CGSCC-LABEL: define {{[^@]+}}@check_divided_range
1320; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
1321; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR7]]
1322; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR7]]
1323; CGSCC-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR7]]
1324; CGSCC-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR7]]
1325; CGSCC-NEXT:    [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
1326; CGSCC-NEXT:    ret i1 [[RET]]
1327;
1328  %csret1 = call i32 @less_than_65536(i32 0)
1329  %csret2 = call i32 @less_than_65536(i32 %arg)
1330  %true1 = call i1 @is_less_than_65536(i32 %csret1)
1331  %true2 = call i1 @is_less_than_65536(i32 %csret2)
1332  %ret = and i1 %true1, %true2
1333  ret i1 %ret
1334}
1335
1336define internal i32 @cast_and_return(i1 %c) {
1337;
1338; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1339; CGSCC-LABEL: define {{[^@]+}}@cast_and_return
1340; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
1341; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[C]] to i32
1342; CGSCC-NEXT:    ret i32 [[RET]]
1343;
1344  %ret = zext i1 %c to i32
1345  ret i32 %ret
1346}
1347
1348define internal i1 @is_less_than_3(i32 %c) {
1349; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1350; CGSCC-LABEL: define {{[^@]+}}@is_less_than_3
1351; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] {
1352; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 3
1353; CGSCC-NEXT:    ret i1 [[CMP]]
1354;
1355  %cmp = icmp slt i32 %c, 3
1356  ret i1 %cmp
1357}
1358
1359define i1 @check_casted_range(i1 %c) {
1360; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1361; TUNIT-LABEL: define {{[^@]+}}@check_casted_range
1362; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
1363; TUNIT-NEXT:    ret i1 true
1364;
1365; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1366; CGSCC-LABEL: define {{[^@]+}}@check_casted_range
1367; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
1368; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR7]]
1369; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR7]]
1370; CGSCC-NEXT:    [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
1371; CGSCC-NEXT:    [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR7]]
1372; CGSCC-NEXT:    ret i1 [[RET]]
1373;
1374  %csret1 = call i32 @cast_and_return(i1 true)
1375  %csret2 = call i32 @cast_and_return(i1 %c)
1376  %add = add i32 %csret1, %csret2
1377  %ret = call i1 @is_less_than_3(i32 %add)
1378  ret i1 %ret
1379}
1380
1381define internal i32 @less_than_100_1(i32 %c) {
1382; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1383; CGSCC-LABEL: define {{[^@]+}}@less_than_100_1
1384; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1385; CGSCC-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
1386; CGSCC-NEXT:      i32 0, label [[ONZERO:%.*]]
1387; CGSCC-NEXT:      i32 1, label [[ONONE:%.*]]
1388; CGSCC-NEXT:      i32 2, label [[ONTWO:%.*]]
1389; CGSCC-NEXT:      i32 3, label [[ONTHREE:%.*]]
1390; CGSCC-NEXT:      i32 4, label [[ONFOUR:%.*]]
1391; CGSCC-NEXT:      i32 5, label [[ONFIVE:%.*]]
1392; CGSCC-NEXT:      i32 6, label [[ONSIX:%.*]]
1393; CGSCC-NEXT:    ]
1394; CGSCC:       onzero:
1395; CGSCC-NEXT:    ret i32 0
1396; CGSCC:       onone:
1397; CGSCC-NEXT:    ret i32 1
1398; CGSCC:       ontwo:
1399; CGSCC-NEXT:    ret i32 2
1400; CGSCC:       onthree:
1401; CGSCC-NEXT:    ret i32 3
1402; CGSCC:       onfour:
1403; CGSCC-NEXT:    ret i32 4
1404; CGSCC:       onfive:
1405; CGSCC-NEXT:    ret i32 5
1406; CGSCC:       onsix:
1407; CGSCC-NEXT:    ret i32 6
1408; CGSCC:       otherwise:
1409; CGSCC-NEXT:    ret i32 99
1410;
1411  switch i32 %c, label %otherwise [ i32 0, label %onzero
1412  i32 1, label %onone
1413  i32 2, label %ontwo
1414  i32 3, label %onthree
1415  i32 4, label %onfour
1416  i32 5, label %onfive
1417  i32 6, label %onsix]
1418onzero:
1419  ret i32 0
1420onone:
1421  ret i32 1
1422ontwo:
1423  ret i32 2
1424onthree:
1425  ret i32 3
1426onfour:
1427  ret i32 4
1428onfive:
1429  ret i32 5
1430onsix:
1431  ret i32 6
1432otherwise:
1433  ret i32 99
1434}
1435
1436define internal i1 @is_less_than_100_1(i32 %c) {
1437; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1438; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_1
1439; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1440; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 100
1441; CGSCC-NEXT:    ret i1 [[CMP]]
1442;
1443  %cmp = icmp slt i32 %c, 100
1444  ret i1 %cmp
1445}
1446
1447define i1 @propagate_range1(i32 %c){
1448; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1449; TUNIT-LABEL: define {{[^@]+}}@propagate_range1
1450; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
1451; TUNIT-NEXT:    ret i1 true
1452;
1453; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1454; CGSCC-LABEL: define {{[^@]+}}@propagate_range1
1455; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
1456; CGSCC-NEXT:    [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR7]]
1457; CGSCC-NEXT:    [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR7]]
1458; CGSCC-NEXT:    ret i1 [[TRUE]]
1459;
1460  %csret = call i32 @less_than_100_1(i32 %c)
1461  %true = call i1 @is_less_than_100_1(i32 %csret)
1462  ret i1 %true
1463}
1464
1465define internal i32 @less_than_100_2(i32 %c) {
1466;
1467; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1468; TUNIT-LABEL: define {{[^@]+}}@less_than_100_2
1469; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {
1470; TUNIT-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
1471; TUNIT-NEXT:      i32 0, label [[ONZERO:%.*]]
1472; TUNIT-NEXT:      i32 1, label [[ONONE:%.*]]
1473; TUNIT-NEXT:      i32 2, label [[ONTWO:%.*]]
1474; TUNIT-NEXT:      i32 3, label [[ONTHREE:%.*]]
1475; TUNIT-NEXT:      i32 4, label [[ONFOUR:%.*]]
1476; TUNIT-NEXT:      i32 5, label [[ONFIVE:%.*]]
1477; TUNIT-NEXT:      i32 6, label [[ONSIX:%.*]]
1478; TUNIT-NEXT:    ]
1479; TUNIT:       onzero:
1480; TUNIT-NEXT:    ret i32 0
1481; TUNIT:       onone:
1482; TUNIT-NEXT:    ret i32 1
1483; TUNIT:       ontwo:
1484; TUNIT-NEXT:    ret i32 2
1485; TUNIT:       onthree:
1486; TUNIT-NEXT:    ret i32 3
1487; TUNIT:       onfour:
1488; TUNIT-NEXT:    ret i32 4
1489; TUNIT:       onfive:
1490; TUNIT-NEXT:    ret i32 5
1491; TUNIT:       onsix:
1492; TUNIT-NEXT:    ret i32 6
1493; TUNIT:       otherwise:
1494; TUNIT-NEXT:    ret i32 99
1495;
1496; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1497; CGSCC-LABEL: define {{[^@]+}}@less_than_100_2
1498; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1499; CGSCC-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
1500; CGSCC-NEXT:      i32 0, label [[ONZERO:%.*]]
1501; CGSCC-NEXT:      i32 1, label [[ONONE:%.*]]
1502; CGSCC-NEXT:      i32 2, label [[ONTWO:%.*]]
1503; CGSCC-NEXT:      i32 3, label [[ONTHREE:%.*]]
1504; CGSCC-NEXT:      i32 4, label [[ONFOUR:%.*]]
1505; CGSCC-NEXT:      i32 5, label [[ONFIVE:%.*]]
1506; CGSCC-NEXT:      i32 6, label [[ONSIX:%.*]]
1507; CGSCC-NEXT:    ]
1508; CGSCC:       onzero:
1509; CGSCC-NEXT:    ret i32 0
1510; CGSCC:       onone:
1511; CGSCC-NEXT:    ret i32 1
1512; CGSCC:       ontwo:
1513; CGSCC-NEXT:    ret i32 2
1514; CGSCC:       onthree:
1515; CGSCC-NEXT:    ret i32 3
1516; CGSCC:       onfour:
1517; CGSCC-NEXT:    ret i32 4
1518; CGSCC:       onfive:
1519; CGSCC-NEXT:    ret i32 5
1520; CGSCC:       onsix:
1521; CGSCC-NEXT:    ret i32 6
1522; CGSCC:       otherwise:
1523; CGSCC-NEXT:    ret i32 99
1524;
1525  switch i32 %c, label %otherwise [ i32 0, label %onzero
1526  i32 1, label %onone
1527  i32 2, label %ontwo
1528  i32 3, label %onthree
1529  i32 4, label %onfour
1530  i32 5, label %onfive
1531  i32 6, label %onsix]
1532onzero:
1533  ret i32 0
1534onone:
1535  ret i32 1
1536ontwo:
1537  ret i32 2
1538onthree:
1539  ret i32 3
1540onfour:
1541  ret i32 4
1542onfive:
1543  ret i32 5
1544onsix:
1545  ret i32 6
1546otherwise:
1547  ret i32 99
1548}
1549
1550define internal i1 @is_less_than_100_2(i32 %c) {
1551;
1552; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1553; TUNIT-LABEL: define {{[^@]+}}@is_less_than_100_2
1554; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {
1555; TUNIT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 100
1556; TUNIT-NEXT:    ret i1 [[CMP]]
1557;
1558; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1559; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_2
1560; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1561; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 100
1562; CGSCC-NEXT:    ret i1 [[CMP]]
1563;
1564  %cmp = icmp slt i32 %c, 100
1565  ret i1 %cmp
1566}
1567
1568define i1 @propagate_range2(i32 %c) {
1569; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1570; TUNIT-LABEL: define {{[^@]+}}@propagate_range2
1571; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
1572; TUNIT-NEXT:    [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR4]]
1573; TUNIT-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR4]]
1574; TUNIT-NEXT:    [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR4]]
1575; TUNIT-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR4]]
1576; TUNIT-NEXT:    [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
1577; TUNIT-NEXT:    ret i1 [[TRUE]]
1578;
1579; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1580; CGSCC-LABEL: define {{[^@]+}}@propagate_range2
1581; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
1582; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR7]]
1583; CGSCC-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR7]]
1584; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR7]]
1585; CGSCC-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR7]]
1586; CGSCC-NEXT:    [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
1587; CGSCC-NEXT:    ret i1 [[TRUE]]
1588;
1589  %csret1 = call i32 @less_than_100_2(i32 0)
1590  %true1 = call i1 @is_less_than_100_2(i32 %csret1)
1591  %csret2 = call i32 @less_than_100_2(i32 %c)
1592  %true2 = call i1 @is_less_than_100_2(i32 %csret2)
1593  %true = and i1 %true1, %true2
1594  ret i1 %true
1595}
1596
1597define internal i1 @non_zero(i8 %v) {
1598; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1599; TUNIT-LABEL: define {{[^@]+}}@non_zero
1600; TUNIT-SAME: (i8 [[V:%.*]]) #[[ATTR1]] {
1601; TUNIT-NEXT:    [[R:%.*]] = icmp ne i8 [[V]], 0
1602; TUNIT-NEXT:    ret i1 [[R]]
1603;
1604; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1605; CGSCC-LABEL: define {{[^@]+}}@non_zero
1606; CGSCC-SAME: (i8 [[V:%.*]]) #[[ATTR2]] {
1607; CGSCC-NEXT:    ret i1 true
1608;
1609  %r = icmp ne i8 %v, 0
1610  ret i1 %r
1611}
1612
1613; Avoid range metadata for %l below
1614define i1 @context(ptr %p) {
1615; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
1616; TUNIT-LABEL: define {{[^@]+}}@context
1617; TUNIT-SAME: (ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR0]] {
1618; TUNIT-NEXT:    [[L:%.*]] = load i8, ptr [[P]], align 1
1619; TUNIT-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
1620; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1621; TUNIT:       t:
1622; TUNIT-NEXT:    [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR4]]
1623; TUNIT-NEXT:    ret i1 [[R]]
1624; TUNIT:       f:
1625; TUNIT-NEXT:    ret i1 false
1626;
1627; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
1628; CGSCC-LABEL: define {{[^@]+}}@context
1629; CGSCC-SAME: (ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR1]] {
1630; CGSCC-NEXT:    [[L:%.*]] = load i8, ptr [[P]], align 1
1631; CGSCC-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
1632; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1633; CGSCC:       t:
1634; CGSCC-NEXT:    [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR7]]
1635; CGSCC-NEXT:    ret i1 [[R]]
1636; CGSCC:       f:
1637; CGSCC-NEXT:    ret i1 false
1638;
1639  %l = load i8, ptr %p
1640  %c = icmp slt i8 0, %l
1641  br i1 %c, label %t, label %f
1642t:
1643  %r = call i1 @non_zero(i8 %l)
1644  ret i1 %r
1645f:
1646  ret i1 false
1647}
1648
1649
1650define void @spam(ptr %arg, ptr %arg1) {
1651; CHECK-LABEL: define {{[^@]+}}@spam
1652; CHECK-SAME: (ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[ARG:%.*]], ptr nofree readnone captures(none) [[ARG1:%.*]]) {
1653; CHECK-NEXT:  bb:
1654; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[ARG]], align 8
1655; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP]], 4
1656; CHECK-NEXT:    br i1 [[TMP2]], label [[BB3:%.*]], label [[BB4:%.*]]
1657; CHECK:       bb3:
1658; CHECK-NEXT:    call fastcc void @wobble(i32 signext [[TMP]])
1659; CHECK-NEXT:    br label [[BB5:%.*]]
1660; CHECK:       bb4:
1661; CHECK-NEXT:    call void @ham(i32 [[TMP]])
1662; CHECK-NEXT:    br label [[BB5]]
1663; CHECK:       bb5:
1664; CHECK-NEXT:    ret void
1665;
1666bb:
1667  %tmp = load i32, ptr %arg, align 8
1668  %tmp2 = icmp ult i32 %tmp, 4
1669  br i1 %tmp2, label %bb3, label %bb4
1670
1671bb3:                                              ; preds = %bb
1672  call fastcc void @wobble(i32 signext %tmp)
1673  br label %bb5
1674
1675bb4:                                              ; preds = %bb
1676  call void @ham(i32 %tmp)
1677  br label %bb5
1678
1679bb5:                                              ; preds = %bb4, %bb3
1680  ret void
1681}
1682
1683define internal fastcc void @wobble(i32 signext %arg) {
1684; CHECK-LABEL: define {{[^@]+}}@wobble
1685; CHECK-SAME: (i32 signext [[ARG:%.*]]) {
1686; CHECK-NEXT:  bb:
1687; CHECK-NEXT:    [[TMP:%.*]] = icmp ult i32 [[ARG]], 2
1688; CHECK-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
1689; CHECK:       bb1:
1690; CHECK-NEXT:    call void @barney(i32 noundef signext 32, i32 noundef signext 0)
1691; CHECK-NEXT:    br label [[BB3:%.*]]
1692; CHECK:       bb2:
1693; CHECK-NEXT:    br label [[BB3]]
1694; CHECK:       bb3:
1695; CHECK-NEXT:    ret void
1696;
1697bb:
1698  %tmp = icmp ult i32 %arg, 2
1699  br i1 %tmp, label %bb1, label %bb2
1700
1701bb1:                                              ; preds = %bb
1702  call void @barney(i32 signext 32, i32 signext 0)
1703  br label %bb3
1704
1705bb2:                                              ; preds = %bb
1706  br label %bb3
1707
1708bb3:                                              ; preds = %bb2, %bb1
1709  ret void
1710}
1711
1712define i1 @loop_1(i32 %N) {
1713; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
1714; TUNIT-LABEL: define {{[^@]+}}@loop_1
1715; TUNIT-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {
1716; TUNIT-NEXT:  entry:
1717; TUNIT-NEXT:    br label [[HEADER:%.*]]
1718; TUNIT:       header:
1719; TUNIT-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ]
1720; TUNIT-NEXT:    [[INC:%.*]] = add i32 [[I]], 1
1721; TUNIT-NEXT:    [[AND]] = and i32 [[INC]], 9999
1722; TUNIT-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]]
1723; TUNIT-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
1724; TUNIT:       exit:
1725; TUNIT-NEXT:    [[R:%.*]] = icmp sle i32 [[I]], 5
1726; TUNIT-NEXT:    ret i1 [[R]]
1727;
1728; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(none)
1729; CGSCC-LABEL: define {{[^@]+}}@loop_1
1730; CGSCC-SAME: (i32 [[N:%.*]]) #[[ATTR4:[0-9]+]] {
1731; CGSCC-NEXT:  entry:
1732; CGSCC-NEXT:    br label [[HEADER:%.*]]
1733; CGSCC:       header:
1734; CGSCC-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ]
1735; CGSCC-NEXT:    [[INC:%.*]] = add i32 [[I]], 1
1736; CGSCC-NEXT:    [[AND]] = and i32 [[INC]], 9999
1737; CGSCC-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]]
1738; CGSCC-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
1739; CGSCC:       exit:
1740; CGSCC-NEXT:    [[R:%.*]] = icmp sle i32 [[I]], 5
1741; CGSCC-NEXT:    ret i1 [[R]]
1742;
1743entry:
1744  br label %header
1745header:
1746  %i = phi i32 [0, %entry], [%and, %header]
1747  %inc = add i32 %i, 1
1748  %and = and i32 %inc, 9999
1749  %cmp = icmp ne i32 %N, %and
1750  br i1 %cmp, label %header, label %exit
1751exit:
1752  %r = icmp sle i32 %i, 5
1753  ret i1 %r
1754}
1755
1756declare void @ham(i32)
1757
1758declare void @barney(i32 signext, i32 signext)
1759
1760
1761!0 = !{i32 0, i32 10}
1762!1 = !{i32 10, i32 100}
1763;.
1764; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
1765; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1766; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) }
1767; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(read) }
1768; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(none) }
1769;.
1770; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
1771; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }
1772; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1773; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
1774; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(none) }
1775; CGSCC: attributes #[[ATTR5]] = { nofree willreturn memory(read) }
1776; CGSCC: attributes #[[ATTR6]] = { nofree willreturn }
1777; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }
1778;.
1779; TUNIT: [[RNG0]] = !{i32 0, i32 10}
1780; TUNIT: [[RNG1]] = !{i32 10, i32 100}
1781; TUNIT: [[RNG2]] = !{i32 200, i32 1091}
1782; TUNIT: [[RNG3]] = !{i32 1, i32 -2147483648}
1783;.
1784; CGSCC: [[RNG0]] = !{i32 0, i32 10}
1785; CGSCC: [[RNG1]] = !{i32 10, i32 100}
1786;.
1787