1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -enable-new-pm=0 -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_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=19 -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 -enable-new-pm=0 -attributor-cgscc -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; Test for multiple potential values
8;
9; potential-test 1
10; bool iszero(int c) { return c == 0; }
11; bool potential_test1(bool c) { return iszero(c ? 1 : -1); }
12
13define internal i1 @iszero1(i32 %c) {
14; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
15; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero1
16; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
17; IS__CGSCC____-NEXT:    ret i1 undef
18;
19  %cmp = icmp eq i32 %c, 0
20  ret i1 %cmp
21}
22
23define i1 @potential_test1(i1 %c) {
24; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
25; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test1
26; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
27; IS__TUNIT____-NEXT:    ret i1 false
28;
29; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
30; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test1
31; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
32; IS__CGSCC____-NEXT:    ret i1 false
33;
34  %arg = select i1 %c, i32 -1, i32 1
35  %ret = call i1 @iszero1(i32 %arg)
36  ret i1 %ret
37}
38
39
40; potential-test 2
41;
42; potential values of argument of iszero are {1,-1}
43; potential value of returned value of iszero is 0
44;
45; int call_with_two_values(int x) { return iszero(x) + iszero(-x); }
46; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); }
47
48define internal i32 @iszero2(i32 %c) {
49; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
50; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero2
51; IS__CGSCC____-SAME: () #[[ATTR0]] {
52; IS__CGSCC____-NEXT:    ret i32 undef
53;
54  %cmp = icmp eq i32 %c, 0
55  %ret = zext i1 %cmp to i32
56  ret i32 %ret
57}
58
59define internal i32 @call_with_two_values(i32 %c) {
60; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
61; IS__CGSCC____-LABEL: define {{[^@]+}}@call_with_two_values
62; IS__CGSCC____-SAME: () #[[ATTR0]] {
63; IS__CGSCC____-NEXT:    ret i32 undef
64;
65  %csret1 = call i32 @iszero2(i32 %c)
66  %minusc = sub i32 0, %c
67  %csret2 = call i32 @iszero2(i32 %minusc)
68  %ret = add i32 %csret1, %csret2
69  ret i32 %ret
70}
71
72define i32 @potential_test2(i1 %c) {
73; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
74; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test2
75; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
76; IS__TUNIT____-NEXT:    ret i32 0
77;
78; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
79; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test2
80; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
81; IS__CGSCC____-NEXT:    ret i32 0
82;
83  %csret1 = call i32 @call_with_two_values(i32 1)
84  %csret2 = call i32 @call_with_two_values(i32 -1)
85  %ret = add i32 %csret1, %csret2
86  ret i32 %ret
87}
88
89
90; potential-test 3
91;
92; potential values of returned value of f are {0,1}
93; potential values of argument of g are {0,1}
94; potential value of returned value of g is 1
95; then returned value of g can be simplified
96;
97; int zero_or_one(int c) { return c < 2; }
98; int potential_test3() { return zero_or_one(iszero(0))+zero_or_one(iszero(1)); }
99
100define internal i32 @iszero3(i32 %c) {
101; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
102; IS__TUNIT____-LABEL: define {{[^@]+}}@iszero3
103; IS__TUNIT____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
104; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0
105; IS__TUNIT____-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i32
106; IS__TUNIT____-NEXT:    ret i32 [[RET]]
107;
108; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
109; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero3
110; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
111; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0
112; IS__CGSCC____-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i32
113; IS__CGSCC____-NEXT:    ret i32 [[RET]]
114;
115  %cmp = icmp eq i32 %c, 0
116  %ret = zext i1 %cmp to i32
117  ret i32 %ret
118}
119
120define internal i32 @less_than_two(i32 %c) {
121; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
122; IS__TUNIT____-LABEL: define {{[^@]+}}@less_than_two
123; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
124; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 2
125; IS__TUNIT____-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i32
126; IS__TUNIT____-NEXT:    ret i32 [[RET]]
127;
128; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
129; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_two
130; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
131; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 2
132; IS__CGSCC____-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i32
133; IS__CGSCC____-NEXT:    ret i32 [[RET]]
134;
135  %cmp = icmp slt i32 %c, 2
136  %ret = zext i1 %cmp to i32
137  ret i32 %ret
138}
139
140define i32 @potential_test3() {
141; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
142; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test3
143; IS__TUNIT_OPM-SAME: () #[[ATTR0]] {
144; IS__TUNIT_OPM-NEXT:    [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR0]]
145; IS__TUNIT_OPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR0]]
146; IS__TUNIT_OPM-NEXT:    [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR0]]
147; IS__TUNIT_OPM-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR0]]
148; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]]
149; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
150;
151; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
152; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test3
153; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
154; IS__TUNIT_NPM-NEXT:    [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR0]], !range [[RNG0:![0-9]+]]
155; IS__TUNIT_NPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR0]], !range [[RNG0]]
156; IS__TUNIT_NPM-NEXT:    [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR0]], !range [[RNG0]]
157; IS__TUNIT_NPM-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR0]], !range [[RNG0]]
158; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]]
159; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
160;
161; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
162; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test3
163; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
164; IS__CGSCC_OPM-NEXT:    [[CMP1:%.*]] = call noundef i32 @iszero3(i32 noundef 0) #[[ATTR2:[0-9]+]]
165; IS__CGSCC_OPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) #[[ATTR2]], !range [[RNG0:![0-9]+]]
166; IS__CGSCC_OPM-NEXT:    [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) #[[ATTR2]]
167; IS__CGSCC_OPM-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) #[[ATTR2]], !range [[RNG0]]
168; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]]
169; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
170;
171; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
172; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test3
173; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
174; IS__CGSCC_NPM-NEXT:    [[CMP1:%.*]] = call noundef i32 @iszero3(i32 noundef 0) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
175; IS__CGSCC_NPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) #[[ATTR1]], !range [[RNG0]]
176; IS__CGSCC_NPM-NEXT:    [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) #[[ATTR1]], !range [[RNG0]]
177; IS__CGSCC_NPM-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) #[[ATTR1]], !range [[RNG0]]
178; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]]
179; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
180;
181  %cmp1 = call i32 @iszero3(i32 0)
182  %true1 = call i32 @less_than_two(i32 %cmp1)
183  %cmp2 = call i32 @iszero3(i32 1)
184  %true2 = call i32 @less_than_two(i32 %cmp2)
185  %ret = add i32 %true1, %true2
186  ret i32 %ret
187}
188
189
190; potential-test 4,5
191;
192; simplified
193; int potential_test4(int c) { return return1or3(c) == 2; }
194; int potential_test5(int c) { return return1or3(c) == return2or4(c); }
195;
196; not simplified
197; int potential_test6(int c) { return return1or3(c) == 3; }
198; int potential_test7(int c) { return return1or3(c) == return3or4(c); }
199
200define i32 @potential_test4(i32 %c) {
201; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
202; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test4
203; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
204; IS__TUNIT____-NEXT:    ret i32 0
205;
206; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
207; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test4
208; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
209; IS__CGSCC____-NEXT:    ret i32 0
210;
211  %csret = call i32 @return1or3(i32 %c)
212  %false = icmp eq i32 %csret, 2
213  %ret = zext i1 %false to i32
214  ret i32 %ret
215}
216
217define i32 @potential_test5(i32 %c) {
218; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
219; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test5
220; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
221; IS__TUNIT____-NEXT:    ret i32 0
222;
223; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
224; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test5
225; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
226; IS__CGSCC____-NEXT:    ret i32 0
227;
228  %csret1 = call i32 @return1or3(i32 %c)
229  %csret2 = call i32 @return2or4(i32 %c)
230  %false = icmp eq i32 %csret1, %csret2
231  %ret = zext i1 %false to i32
232  ret i32 %ret
233}
234
235define i1 @potential_test6(i32 %c) {
236; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
237; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test6
238; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
239; IS__TUNIT_OPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG0:![0-9]+]]
240; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
241; IS__TUNIT_OPM-NEXT:    ret i1 [[RET]]
242;
243; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
244; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test6
245; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
246; IS__TUNIT_NPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG1:![0-9]+]]
247; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
248; IS__TUNIT_NPM-NEXT:    ret i1 [[RET]]
249;
250; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
251; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test6
252; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
253; IS__CGSCC_OPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]], !range [[RNG1:![0-9]+]]
254; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
255; IS__CGSCC_OPM-NEXT:    ret i1 [[RET]]
256;
257; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
258; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test6
259; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
260; IS__CGSCC_NPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
261; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
262; IS__CGSCC_NPM-NEXT:    ret i1 [[RET]]
263;
264  %csret1 = call i32 @return1or3(i32 %c)
265  %ret = icmp eq i32 %csret1, 3
266  ret i1 %ret
267}
268
269define i1 @potential_test7(i32 %c) {
270; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
271; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test7
272; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
273; IS__TUNIT_OPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG0]]
274; IS__TUNIT_OPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR0]], !range [[RNG1:![0-9]+]]
275; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
276; IS__TUNIT_OPM-NEXT:    ret i1 [[RET]]
277;
278; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
279; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test7
280; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
281; IS__TUNIT_NPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG1]]
282; IS__TUNIT_NPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
283; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
284; IS__TUNIT_NPM-NEXT:    ret i1 [[RET]]
285;
286; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
287; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test7
288; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
289; IS__CGSCC_OPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]], !range [[RNG1]]
290; IS__CGSCC_OPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR2]], !range [[RNG2:![0-9]+]]
291; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
292; IS__CGSCC_OPM-NEXT:    ret i1 [[RET]]
293;
294; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
295; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test7
296; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
297; IS__CGSCC_NPM-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]], !range [[RNG1]]
298; IS__CGSCC_NPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR1]], !range [[RNG2:![0-9]+]]
299; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
300; IS__CGSCC_NPM-NEXT:    ret i1 [[RET]]
301;
302  %csret1 = call i32 @return1or3(i32 %c)
303  %csret2 = call i32 @return3or4(i32 %c)
304  %ret = icmp eq i32 %csret1, %csret2
305  ret i1 %ret
306}
307
308define internal i32 @return1or3(i32 %c) {
309; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
310; IS__TUNIT____-LABEL: define {{[^@]+}}@return1or3
311; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
312; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0
313; IS__TUNIT____-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3
314; IS__TUNIT____-NEXT:    ret i32 [[RET]]
315;
316; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
317; IS__CGSCC____-LABEL: define {{[^@]+}}@return1or3
318; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
319; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0
320; IS__CGSCC____-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3
321; IS__CGSCC____-NEXT:    ret i32 [[RET]]
322;
323  %cmp = icmp eq i32 %c, 0
324  %ret = select i1 %cmp, i32 1, i32 3
325  ret i32 %ret
326}
327
328define internal i32 @return2or4(i32 %c) {
329; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
330; IS__CGSCC____-LABEL: define {{[^@]+}}@return2or4
331; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
332; IS__CGSCC____-NEXT:    ret i32 undef
333;
334  %cmp = icmp eq i32 %c, 0
335  %ret = select i1 %cmp, i32 2, i32 4
336  ret i32 %ret
337}
338
339define internal i32 @return3or4(i32 %c) {
340; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
341; IS__TUNIT____-LABEL: define {{[^@]+}}@return3or4
342; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
343; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0
344; IS__TUNIT____-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 3, i32 4
345; IS__TUNIT____-NEXT:    ret i32 [[RET]]
346;
347; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
348; IS__CGSCC____-LABEL: define {{[^@]+}}@return3or4
349; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
350; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0
351; IS__CGSCC____-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 3, i32 4
352; IS__CGSCC____-NEXT:    ret i32 [[RET]]
353;
354  %cmp = icmp eq i32 %c, 0
355  %ret = select i1 %cmp, i32 3, i32 4
356  ret i32 %ret
357}
358
359; potential-test 8
360;
361; propagate argument to callsite argument
362
363define internal i1 @cmp_with_four(i32 %c) {
364; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
365; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_with_four
366; IS__CGSCC____-SAME: () #[[ATTR0]] {
367; IS__CGSCC____-NEXT:    ret i1 undef
368;
369  %cmp = icmp eq i32 %c, 4
370  ret i1 %cmp
371}
372
373define internal i1 @wrapper(i32 %c) {
374; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
375; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper
376; IS__CGSCC____-SAME: () #[[ATTR0]] {
377; IS__CGSCC____-NEXT:    ret i1 undef
378;
379  %ret = call i1 @cmp_with_four(i32 %c)
380  ret i1 %ret
381}
382
383define i1 @potential_test8() {
384; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
385; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test8
386; IS__TUNIT____-SAME: () #[[ATTR0]] {
387; IS__TUNIT____-NEXT:    ret i1 false
388;
389; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
390; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test8
391; IS__CGSCC____-SAME: () #[[ATTR0]] {
392; IS__CGSCC____-NEXT:    ret i1 false
393;
394  %res1 = call i1 @wrapper(i32 1)
395  %res3 = call i1 @wrapper(i32 3)
396  %res5 = call i1 @wrapper(i32 5)
397  %res13 = or i1 %res1, %res3
398  %res135 =  or i1 %res13, %res5
399  ret i1 %res135
400}
401
402define i1 @potential_test9() {
403; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
404; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test9
405; IS__TUNIT_OPM-SAME: () #[[ATTR1:[0-9]+]] {
406; IS__TUNIT_OPM-NEXT:  entry:
407; IS__TUNIT_OPM-NEXT:    br label [[COND:%.*]]
408; IS__TUNIT_OPM:       cond:
409; IS__TUNIT_OPM-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ]
410; IS__TUNIT_OPM-NEXT:    [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ]
411; IS__TUNIT_OPM-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 10
412; IS__TUNIT_OPM-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
413; IS__TUNIT_OPM:       body:
414; IS__TUNIT_OPM-NEXT:    [[C_1]] = mul i32 [[C_0]], -1
415; IS__TUNIT_OPM-NEXT:    br label [[INC]]
416; IS__TUNIT_OPM:       inc:
417; IS__TUNIT_OPM-NEXT:    [[I_1]] = add i32 [[I_0]], 1
418; IS__TUNIT_OPM-NEXT:    br label [[COND]]
419; IS__TUNIT_OPM:       end:
420; IS__TUNIT_OPM-NEXT:    ret i1 false
421;
422; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
423; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test9
424; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
425; IS__TUNIT_NPM-NEXT:  entry:
426; IS__TUNIT_NPM-NEXT:    br label [[COND:%.*]]
427; IS__TUNIT_NPM:       cond:
428; IS__TUNIT_NPM-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ]
429; IS__TUNIT_NPM-NEXT:    [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ]
430; IS__TUNIT_NPM-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 10
431; IS__TUNIT_NPM-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
432; IS__TUNIT_NPM:       body:
433; IS__TUNIT_NPM-NEXT:    [[C_1]] = mul i32 [[C_0]], -1
434; IS__TUNIT_NPM-NEXT:    br label [[INC]]
435; IS__TUNIT_NPM:       inc:
436; IS__TUNIT_NPM-NEXT:    [[I_1]] = add i32 [[I_0]], 1
437; IS__TUNIT_NPM-NEXT:    br label [[COND]]
438; IS__TUNIT_NPM:       end:
439; IS__TUNIT_NPM-NEXT:    ret i1 false
440;
441; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
442; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test9
443; IS__CGSCC_OPM-SAME: () #[[ATTR1:[0-9]+]] {
444; IS__CGSCC_OPM-NEXT:  entry:
445; IS__CGSCC_OPM-NEXT:    br label [[COND:%.*]]
446; IS__CGSCC_OPM:       cond:
447; IS__CGSCC_OPM-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ]
448; IS__CGSCC_OPM-NEXT:    [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ]
449; IS__CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 10
450; IS__CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
451; IS__CGSCC_OPM:       body:
452; IS__CGSCC_OPM-NEXT:    [[C_1]] = mul i32 [[C_0]], -1
453; IS__CGSCC_OPM-NEXT:    br label [[INC]]
454; IS__CGSCC_OPM:       inc:
455; IS__CGSCC_OPM-NEXT:    [[I_1]] = add i32 [[I_0]], 1
456; IS__CGSCC_OPM-NEXT:    br label [[COND]]
457; IS__CGSCC_OPM:       end:
458; IS__CGSCC_OPM-NEXT:    ret i1 false
459;
460; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
461; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test9
462; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
463; IS__CGSCC_NPM-NEXT:  entry:
464; IS__CGSCC_NPM-NEXT:    br label [[COND:%.*]]
465; IS__CGSCC_NPM:       cond:
466; IS__CGSCC_NPM-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ]
467; IS__CGSCC_NPM-NEXT:    [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ]
468; IS__CGSCC_NPM-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 10
469; IS__CGSCC_NPM-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
470; IS__CGSCC_NPM:       body:
471; IS__CGSCC_NPM-NEXT:    [[C_1]] = mul i32 [[C_0]], -1
472; IS__CGSCC_NPM-NEXT:    br label [[INC]]
473; IS__CGSCC_NPM:       inc:
474; IS__CGSCC_NPM-NEXT:    [[I_1]] = add i32 [[I_0]], 1
475; IS__CGSCC_NPM-NEXT:    br label [[COND]]
476; IS__CGSCC_NPM:       end:
477; IS__CGSCC_NPM-NEXT:    ret i1 false
478;
479entry:
480  br label %cond
481cond:
482  %i.0 = phi i32 [0, %entry], [%i.1, %inc]
483  %c.0 = phi i32 [1, %entry], [%c.1, %inc]
484  %cmp = icmp slt i32 %i.0, 10
485  br i1 %cmp, label %body, label %end
486body:
487  %c.1 = mul i32 %c.0, -1
488  br label %inc
489inc:
490  %i.1 = add i32 %i.0, 1
491  br label %cond
492end:
493  %ret = icmp eq i32 %c.0, 0
494  ret i1 %ret
495}
496
497; Test 10
498; FIXME: potential returned values of @may_return_undef is {1, -1}
499;        and returned value of @potential_test10 can be simplified to 0(false)
500
501define internal i32 @may_return_undef(i32 %c) {
502; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
503; IS__CGSCC____-LABEL: define {{[^@]+}}@may_return_undef
504; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
505; IS__CGSCC____-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
506; IS__CGSCC____-NEXT:    i32 1, label [[A:%.*]]
507; IS__CGSCC____-NEXT:    i32 -1, label [[B:%.*]]
508; IS__CGSCC____-NEXT:    ]
509; IS__CGSCC____:       a:
510; IS__CGSCC____-NEXT:    ret i32 undef
511; IS__CGSCC____:       b:
512; IS__CGSCC____-NEXT:    ret i32 undef
513; IS__CGSCC____:       otherwise:
514; IS__CGSCC____-NEXT:    ret i32 undef
515;
516  switch i32 %c, label %otherwise [i32 1, label %a
517  i32 -1, label %b]
518a:
519  ret i32 1
520b:
521  ret i32 -1
522otherwise:
523  ret i32 undef
524}
525
526define i1 @potential_test10(i32 %c) {
527; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
528; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test10
529; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
530; IS__TUNIT____-NEXT:    ret i1 false
531;
532; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
533; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test10
534; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
535; IS__CGSCC____-NEXT:    ret i1 false
536;
537  %ret = call i32 @may_return_undef(i32 %c)
538  %cmp = icmp eq i32 %ret, 0
539  ret i1 %cmp
540}
541
542define i32 @optimize_undef_1(i1 %c) {
543; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
544; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_1
545; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
546; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
547; IS__TUNIT____:       t:
548; IS__TUNIT____-NEXT:    ret i32 0
549; IS__TUNIT____:       f:
550; IS__TUNIT____-NEXT:    ret i32 1
551;
552; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
553; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_1
554; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
555; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
556; IS__CGSCC____:       t:
557; IS__CGSCC____-NEXT:    ret i32 0
558; IS__CGSCC____:       f:
559; IS__CGSCC____-NEXT:    ret i32 1
560;
561  br i1 %c, label %t, label %f
562t:
563  ret i32 0
564f:
565  %undef = add i32 undef, 1
566  ret i32 %undef
567}
568
569define i32 @optimize_undef_2(i1 %c) {
570; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
571; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_2
572; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
573; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
574; IS__TUNIT____:       t:
575; IS__TUNIT____-NEXT:    ret i32 0
576; IS__TUNIT____:       f:
577; IS__TUNIT____-NEXT:    ret i32 -1
578;
579; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
580; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_2
581; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
582; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
583; IS__CGSCC____:       t:
584; IS__CGSCC____-NEXT:    ret i32 0
585; IS__CGSCC____:       f:
586; IS__CGSCC____-NEXT:    ret i32 -1
587;
588  br i1 %c, label %t, label %f
589t:
590  ret i32 0
591f:
592  %undef = sub i32 undef, 1
593  ret i32 %undef
594}
595
596define i32 @optimize_undef_3(i1 %c) {
597; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
598; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_3
599; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
600; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
601; IS__TUNIT____:       t:
602; IS__TUNIT____-NEXT:    ret i32 0
603; IS__TUNIT____:       f:
604; IS__TUNIT____-NEXT:    ret i32 1
605;
606; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
607; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_3
608; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
609; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
610; IS__CGSCC____:       t:
611; IS__CGSCC____-NEXT:    ret i32 0
612; IS__CGSCC____:       f:
613; IS__CGSCC____-NEXT:    ret i32 1
614;
615  br i1 %c, label %t, label %f
616t:
617  ret i32 0
618f:
619  %undef = icmp eq i32 undef, 0
620  %undef2 = zext i1 %undef to i32
621  ret i32 %undef2
622}
623
624
625; FIXME: returned value can be simplified to 0
626define i32 @potential_test11(i1 %c) {
627; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
628; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11
629; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
630; IS__TUNIT_OPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
631; IS__TUNIT_OPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
632; IS__TUNIT_OPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
633; IS__TUNIT_OPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], 0
634; IS__TUNIT_OPM-NEXT:    ret i32 [[ACC2]]
635;
636; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
637; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11
638; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
639; IS__TUNIT_NPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG0]]
640; IS__TUNIT_NPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
641; IS__TUNIT_NPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
642; IS__TUNIT_NPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], 0
643; IS__TUNIT_NPM-NEXT:    ret i32 [[ACC2]]
644;
645; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
646; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11
647; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
648; IS__CGSCC_OPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR2]], !range [[RNG0]]
649; IS__CGSCC_OPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR2]], !range [[RNG3:![0-9]+]]
650; IS__CGSCC_OPM-NEXT:    [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR2]], !range [[RNG0]]
651; IS__CGSCC_OPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
652; IS__CGSCC_OPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
653; IS__CGSCC_OPM-NEXT:    ret i32 [[ACC2]]
654;
655; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
656; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test11
657; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
658; IS__CGSCC_NPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR1]], !range [[RNG0]]
659; IS__CGSCC_NPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR1]], !range [[RNG3:![0-9]+]]
660; IS__CGSCC_NPM-NEXT:    [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR1]], !range [[RNG0]]
661; IS__CGSCC_NPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
662; IS__CGSCC_NPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
663; IS__CGSCC_NPM-NEXT:    ret i32 [[ACC2]]
664;
665  %zero1 = call i32 @optimize_undef_1(i1 %c)
666  %zero2 = call i32 @optimize_undef_2(i1 %c)
667  %zero3 = call i32 @optimize_undef_3(i1 %c)
668  %acc1 = add i32 %zero1, %zero2
669  %acc2 = add i32 %acc1, %zero3
670  ret i32 %acc2
671}
672
673define i32 @optimize_poison_1(i1 %c) {
674; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
675; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
676; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
677; IS__TUNIT_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
678; IS__TUNIT_OPM:       t:
679; IS__TUNIT_OPM-NEXT:    ret i32 0
680; IS__TUNIT_OPM:       f:
681; IS__TUNIT_OPM-NEXT:    ret i32 -1
682;
683; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
684; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@optimize_poison_1
685; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
686; IS__TUNIT_NPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
687; IS__TUNIT_NPM:       t:
688; IS__TUNIT_NPM-NEXT:    ret i32 0
689; IS__TUNIT_NPM:       f:
690; IS__TUNIT_NPM-NEXT:    ret i32 undef
691;
692; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
693; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
694; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
695; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
696; IS__CGSCC_OPM:       t:
697; IS__CGSCC_OPM-NEXT:    ret i32 0
698; IS__CGSCC_OPM:       f:
699; IS__CGSCC_OPM-NEXT:    ret i32 -1
700;
701; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
702; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@optimize_poison_1
703; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
704; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
705; IS__CGSCC_NPM:       t:
706; IS__CGSCC_NPM-NEXT:    ret i32 0
707; IS__CGSCC_NPM:       f:
708; IS__CGSCC_NPM-NEXT:    ret i32 undef
709;
710  br i1 %c, label %t, label %f
711t:
712  ret i32 0
713f:
714  %poison = sub nuw i32 0, 1
715  ret i32 %poison
716}
717
718; FIXME: returned value can be simplified to 0
719define i32 @potential_test12(i1 %c) {
720; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
721; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test12
722; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
723; IS__TUNIT_OPM-NEXT:    [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR0]], !range [[RNG3]]
724; IS__TUNIT_OPM-NEXT:    ret i32 [[ZERO]]
725;
726; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
727; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test12
728; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
729; IS__TUNIT_NPM-NEXT:    ret i32 0
730;
731; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
732; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12
733; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
734; IS__CGSCC_OPM-NEXT:    [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]]
735; IS__CGSCC_OPM-NEXT:    ret i32 [[ZERO]]
736;
737; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
738; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test12
739; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
740; IS__CGSCC_NPM-NEXT:    ret i32 0
741;
742  %zero = call i32 @optimize_poison_1(i1 %c)
743  ret i32 %zero
744}
745
746; Test 13
747; Do not simplify %ret in the callee to `%c`.
748; The potential value of %c is {0, 1} (undef is merged).
749; However, we should not simplify `and i32 %c, 3` to `%c`
750
751define internal i32 @potential_test13_callee(i32 %c) {
752; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
753; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_callee
754; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
755; IS__TUNIT____-NEXT:    [[RET:%.*]] = and i32 [[C]], 3
756; IS__TUNIT____-NEXT:    ret i32 [[RET]]
757;
758; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
759; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test13_callee
760; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
761; IS__CGSCC____-NEXT:    [[RET:%.*]] = and i32 [[C]], 3
762; IS__CGSCC____-NEXT:    ret i32 [[RET]]
763;
764  %ret = and i32 %c, 3
765  ret i32 %ret
766}
767
768define i32 @potential_test13_caller1() {
769; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
770; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1
771; IS__TUNIT_OPM-SAME: () #[[ATTR0]] {
772; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG2]]
773; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
774;
775; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
776; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1
777; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
778; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG0]]
779; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
780;
781; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
782; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1
783; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
784; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG0]]
785; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
786;
787; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
788; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1
789; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
790; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG0]]
791; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
792;
793  %ret = call i32 @potential_test13_callee(i32 0)
794  ret i32 %ret
795}
796
797define i32 @potential_test13_caller2() {
798; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
799; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2
800; IS__TUNIT_OPM-SAME: () #[[ATTR0]] {
801; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR0]], !range [[RNG2]]
802; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
803;
804; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
805; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2
806; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
807; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR0]], !range [[RNG0]]
808; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
809;
810; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
811; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2
812; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
813; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG0]]
814; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
815;
816; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
817; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2
818; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
819; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG0]]
820; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
821;
822  %ret = call i32 @potential_test13_callee(i32 1)
823  ret i32 %ret
824}
825
826define i32 @potential_test13_caller3() {
827; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
828; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3
829; IS__TUNIT_OPM-SAME: () #[[ATTR0]] {
830; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR0]], !range [[RNG2]]
831; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
832;
833; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
834; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3
835; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
836; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR0]], !range [[RNG0]]
837; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
838;
839; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
840; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3
841; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
842; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR2]], !range [[RNG0]]
843; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
844;
845; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
846; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3
847; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
848; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR1]], !range [[RNG0]]
849; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
850;
851  %ret = call i32 @potential_test13_callee(i32 undef)
852  ret i32 %ret
853}
854
855define i1 @potential_test14(i1 %c0, i1 %c1, i1 %c2, i1 %c3) {
856; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
857; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test14
858; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR0]] {
859; IS__TUNIT____-NEXT:    [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1
860; IS__TUNIT____-NEXT:    [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef
861; IS__TUNIT____-NEXT:    [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7
862; IS__TUNIT____-NEXT:    [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]]
863; IS__TUNIT____-NEXT:    [[RET:%.*]] = icmp slt i32 [[Z3]], 7
864; IS__TUNIT____-NEXT:    ret i1 [[RET]]
865;
866; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
867; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test14
868; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR0]] {
869; IS__CGSCC____-NEXT:    [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1
870; IS__CGSCC____-NEXT:    [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef
871; IS__CGSCC____-NEXT:    [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7
872; IS__CGSCC____-NEXT:    [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]]
873; IS__CGSCC____-NEXT:    [[RET:%.*]] = icmp slt i32 [[Z3]], 7
874; IS__CGSCC____-NEXT:    ret i1 [[RET]]
875;
876  %x0 = select i1 %c0, i32 0, i32 1
877  %x1 = select i1 %c1, i32 %x0, i32 undef
878  %y2 = select i1 %c2, i32 0, i32 7
879  %z3 = select i1 %c3, i32 %x1, i32 %y2
880  %ret = icmp slt i32 %z3, 7
881  ret i1 %ret
882}
883
884define i1 @potential_test15(i1 %c0, i1 %c1) {
885; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
886; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test15
887; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {
888; IS__TUNIT____-NEXT:    ret i1 false
889;
890; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
891; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test15
892; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {
893; IS__CGSCC____-NEXT:    ret i1 false
894;
895  %x0 = select i1 %c0, i32 0, i32 1
896  %x1 = select i1 %c1, i32 %x0, i32 undef
897  %ret = icmp eq i32 %x1, 7
898  ret i1 %ret
899}
900
901define i1 @potential_test16(i1 %c0, i1 %c1) {
902; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
903; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test16
904; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {
905; IS__TUNIT____-NEXT:    ret i1 false
906;
907; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
908; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test16
909; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {
910; IS__CGSCC____-NEXT:    ret i1 false
911;
912  %x0 = select i1 %c0, i32 0, i32 undef
913  %x1 = select i1 %c1, i32 %x0, i32 1
914  %ret = icmp eq i32 %x1, 7
915  ret i1 %ret
916}
917
918;.
919; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
920; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone }
921;.
922; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
923;.
924; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
925; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone }
926; IS__CGSCC_OPM: attributes #[[ATTR2]] = { readnone willreturn }
927;.
928; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
929; IS__CGSCC_NPM: attributes #[[ATTR1]] = { readnone willreturn }
930;.
931; IS__TUNIT_OPM: [[RNG0]] = !{i32 1, i32 4}
932; IS__TUNIT_OPM: [[RNG1]] = !{i32 3, i32 5}
933; IS__TUNIT_OPM: [[RNG2]] = !{i32 0, i32 2}
934; IS__TUNIT_OPM: [[RNG3]] = !{i32 -1, i32 1}
935;.
936; NOT_TUNIT_OPM: [[META0:![0-9]+]] = !{i32 0, i32 2}
937; NOT_TUNIT_OPM: [[META1:![0-9]+]] = !{i32 1, i32 4}
938; NOT_TUNIT_OPM: [[META2:![0-9]+]] = !{i32 3, i32 5}
939; NOT_TUNIT_OPM: [[META3:![0-9]+]] = !{i32 -1, i32 1}
940;.
941