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