• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
2; RUN: opt -enable-new-pm=0 -attributor -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 -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:#.*]] {
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:#.*]] {
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]], [[RNG0:!range !.*]]
155; IS__TUNIT_NPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR0]], [[RNG0]]
156; IS__TUNIT_NPM-NEXT:    [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) [[ATTR0]], [[RNG0]]
157; IS__TUNIT_NPM-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) [[ATTR0]], [[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:#.*]]
165; IS__CGSCC_OPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) [[ATTR2]], [[RNG0:!range !.*]]
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]], [[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:#.*]], [[RNG0:!range !.*]]
175; IS__CGSCC_NPM-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) [[ATTR1]], [[RNG0]]
176; IS__CGSCC_NPM-NEXT:    [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) [[ATTR1]], [[RNG0]]
177; IS__CGSCC_NPM-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) [[ATTR1]], [[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]], [[RNG0:!range !.*]]
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]], [[RNG1:!range !.*]]
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]], [[RNG1:!range !.*]]
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]], [[RNG1:!range !.*]]
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]], [[RNG0]]
274; IS__TUNIT_OPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG1:!range !.*]]
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]], [[RNG1]]
282; IS__TUNIT_NPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG2:!range !.*]]
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]], [[RNG1]]
290; IS__CGSCC_OPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR2]], [[RNG2:!range !.*]]
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]], [[RNG1]]
298; IS__CGSCC_NPM-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR1]], [[RNG2:!range !.*]]
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:#.*]] {
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:#.*]] {
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  switch i32 %c, label %otherwise [i32 1, label %a
503  i32 -1, label %b]
504a:
505  ret i32 1
506b:
507  ret i32 -1
508otherwise:
509  ret i32 undef
510}
511
512define i1 @potential_test10(i32 %c) {
513; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
514; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test10
515; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] {
516; IS__TUNIT____-NEXT:    ret i1 false
517;
518; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
519; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test10
520; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] {
521; IS__CGSCC____-NEXT:    ret i1 false
522;
523  %ret = call i32 @may_return_undef(i32 %c)
524  %cmp = icmp eq i32 %ret, 0
525  ret i1 %cmp
526}
527
528define i32 @optimize_undef_1(i1 %c) {
529; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
530; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_1
531; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
532; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
533; IS__TUNIT____:       t:
534; IS__TUNIT____-NEXT:    ret i32 0
535; IS__TUNIT____:       f:
536; IS__TUNIT____-NEXT:    ret i32 1
537;
538; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
539; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_1
540; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
541; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
542; IS__CGSCC____:       t:
543; IS__CGSCC____-NEXT:    ret i32 0
544; IS__CGSCC____:       f:
545; IS__CGSCC____-NEXT:    ret i32 1
546;
547  br i1 %c, label %t, label %f
548t:
549  ret i32 0
550f:
551  %undef = add i32 undef, 1
552  ret i32 %undef
553}
554
555define i32 @optimize_undef_2(i1 %c) {
556; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
557; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_2
558; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
559; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
560; IS__TUNIT____:       t:
561; IS__TUNIT____-NEXT:    ret i32 0
562; IS__TUNIT____:       f:
563; IS__TUNIT____-NEXT:    ret i32 -1
564;
565; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
566; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_2
567; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
568; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
569; IS__CGSCC____:       t:
570; IS__CGSCC____-NEXT:    ret i32 0
571; IS__CGSCC____:       f:
572; IS__CGSCC____-NEXT:    ret i32 -1
573;
574  br i1 %c, label %t, label %f
575t:
576  ret i32 0
577f:
578  %undef = sub i32 undef, 1
579  ret i32 %undef
580}
581
582define i32 @optimize_undef_3(i1 %c) {
583; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
584; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_3
585; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
586; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
587; IS__TUNIT____:       t:
588; IS__TUNIT____-NEXT:    ret i32 0
589; IS__TUNIT____:       f:
590; IS__TUNIT____-NEXT:    ret i32 1
591;
592; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
593; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_3
594; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
595; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
596; IS__CGSCC____:       t:
597; IS__CGSCC____-NEXT:    ret i32 0
598; IS__CGSCC____:       f:
599; IS__CGSCC____-NEXT:    ret i32 1
600;
601  br i1 %c, label %t, label %f
602t:
603  ret i32 0
604f:
605  %undef = icmp eq i32 undef, 0
606  %undef2 = zext i1 %undef to i32
607  ret i32 %undef2
608}
609
610
611; FIXME: returned value can be simplified to 0
612define i32 @potential_test11(i1 %c) {
613; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
614; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11
615; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
616; IS__TUNIT_OPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR0]], [[RNG2:!range !.*]]
617; IS__TUNIT_OPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR0]], [[RNG3:!range !.*]]
618; IS__TUNIT_OPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
619; IS__TUNIT_OPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], 0
620; IS__TUNIT_OPM-NEXT:    ret i32 [[ACC2]]
621;
622; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
623; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11
624; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
625; IS__TUNIT_NPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR0]], [[RNG0]]
626; IS__TUNIT_NPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR0]], [[RNG3:!range !.*]]
627; IS__TUNIT_NPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
628; IS__TUNIT_NPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], 0
629; IS__TUNIT_NPM-NEXT:    ret i32 [[ACC2]]
630;
631; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
632; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11
633; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
634; IS__CGSCC_OPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR2]], [[RNG0]]
635; IS__CGSCC_OPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR2]], [[RNG3:!range !.*]]
636; IS__CGSCC_OPM-NEXT:    [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR2]], [[RNG0]]
637; IS__CGSCC_OPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
638; IS__CGSCC_OPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
639; IS__CGSCC_OPM-NEXT:    ret i32 [[ACC2]]
640;
641; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
642; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test11
643; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
644; IS__CGSCC_NPM-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR1]], [[RNG0]]
645; IS__CGSCC_NPM-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR1]], [[RNG3:!range !.*]]
646; IS__CGSCC_NPM-NEXT:    [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR1]], [[RNG0]]
647; IS__CGSCC_NPM-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
648; IS__CGSCC_NPM-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
649; IS__CGSCC_NPM-NEXT:    ret i32 [[ACC2]]
650;
651  %zero1 = call i32 @optimize_undef_1(i1 %c)
652  %zero2 = call i32 @optimize_undef_2(i1 %c)
653  %zero3 = call i32 @optimize_undef_3(i1 %c)
654  %acc1 = add i32 %zero1, %zero2
655  %acc2 = add i32 %acc1, %zero3
656  ret i32 %acc2
657}
658
659define i32 @optimize_poison_1(i1 %c) {
660; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
661; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
662; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
663; IS__TUNIT_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
664; IS__TUNIT_OPM:       t:
665; IS__TUNIT_OPM-NEXT:    ret i32 0
666; IS__TUNIT_OPM:       f:
667; IS__TUNIT_OPM-NEXT:    ret i32 -1
668;
669; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
670; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@optimize_poison_1
671; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
672; IS__TUNIT_NPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
673; IS__TUNIT_NPM:       t:
674; IS__TUNIT_NPM-NEXT:    ret i32 0
675; IS__TUNIT_NPM:       f:
676; IS__TUNIT_NPM-NEXT:    ret i32 undef
677;
678; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
679; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
680; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
681; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
682; IS__CGSCC_OPM:       t:
683; IS__CGSCC_OPM-NEXT:    ret i32 0
684; IS__CGSCC_OPM:       f:
685; IS__CGSCC_OPM-NEXT:    ret i32 -1
686;
687; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
688; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@optimize_poison_1
689; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
690; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
691; IS__CGSCC_NPM:       t:
692; IS__CGSCC_NPM-NEXT:    ret i32 0
693; IS__CGSCC_NPM:       f:
694; IS__CGSCC_NPM-NEXT:    ret i32 undef
695;
696  br i1 %c, label %t, label %f
697t:
698  ret i32 0
699f:
700  %poison = sub nuw i32 0, 1
701  ret i32 %poison
702}
703
704; FIXME: returned value can be simplified to 0
705define i32 @potential_test12(i1 %c) {
706; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
707; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test12
708; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
709; IS__TUNIT_OPM-NEXT:    [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) [[ATTR0]], [[RNG3]]
710; IS__TUNIT_OPM-NEXT:    ret i32 [[ZERO]]
711;
712; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
713; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test12
714; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
715; IS__TUNIT_NPM-NEXT:    ret i32 0
716;
717; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
718; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12
719; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
720; IS__CGSCC_OPM-NEXT:    [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) [[ATTR2]], [[RNG3]]
721; IS__CGSCC_OPM-NEXT:    ret i32 [[ZERO]]
722;
723; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
724; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test12
725; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] {
726; IS__CGSCC_NPM-NEXT:    ret i32 0
727;
728  %zero = call i32 @optimize_poison_1(i1 %c)
729  ret i32 %zero
730}
731
732; Test 13
733; Do not simplify %ret in the callee to `%c`.
734; The potential value of %c is {0, 1} (undef is merged).
735; However, we should not simplify `and i32 %c, 3` to `%c`
736
737define internal i32 @potential_test13_callee(i32 %c) {
738; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
739; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_callee
740; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] {
741; IS__TUNIT____-NEXT:    [[RET:%.*]] = and i32 [[C]], 3
742; IS__TUNIT____-NEXT:    ret i32 [[RET]]
743;
744; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
745; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test13_callee
746; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] {
747; IS__CGSCC____-NEXT:    [[RET:%.*]] = and i32 [[C]], 3
748; IS__CGSCC____-NEXT:    ret i32 [[RET]]
749;
750  %ret = and i32 %c, 3
751  ret i32 %ret
752}
753
754define i32 @potential_test13_caller1() {
755; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
756; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1
757; IS__TUNIT_OPM-SAME: () [[ATTR0]] {
758; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR0]], [[RNG2]]
759; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
760;
761; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
762; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1
763; IS__TUNIT_NPM-SAME: () [[ATTR0]] {
764; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR0]], [[RNG0]]
765; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
766;
767; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
768; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1
769; IS__CGSCC_OPM-SAME: () [[ATTR0]] {
770; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR2]], [[RNG0]]
771; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
772;
773; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
774; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1
775; IS__CGSCC_NPM-SAME: () [[ATTR0]] {
776; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR1]], [[RNG0]]
777; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
778;
779  %ret = call i32 @potential_test13_callee(i32 0)
780  ret i32 %ret
781}
782
783define i32 @potential_test13_caller2() {
784; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
785; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2
786; IS__TUNIT_OPM-SAME: () [[ATTR0]] {
787; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR0]], [[RNG2]]
788; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
789;
790; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
791; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2
792; IS__TUNIT_NPM-SAME: () [[ATTR0]] {
793; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR0]], [[RNG0]]
794; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
795;
796; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
797; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2
798; IS__CGSCC_OPM-SAME: () [[ATTR0]] {
799; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR2]], [[RNG0]]
800; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
801;
802; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
803; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2
804; IS__CGSCC_NPM-SAME: () [[ATTR0]] {
805; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR1]], [[RNG0]]
806; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
807;
808  %ret = call i32 @potential_test13_callee(i32 1)
809  ret i32 %ret
810}
811
812define i32 @potential_test13_caller3() {
813; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
814; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3
815; IS__TUNIT_OPM-SAME: () [[ATTR0]] {
816; IS__TUNIT_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR0]], [[RNG2]]
817; IS__TUNIT_OPM-NEXT:    ret i32 [[RET]]
818;
819; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
820; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3
821; IS__TUNIT_NPM-SAME: () [[ATTR0]] {
822; IS__TUNIT_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR0]], [[RNG0]]
823; IS__TUNIT_NPM-NEXT:    ret i32 [[RET]]
824;
825; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
826; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3
827; IS__CGSCC_OPM-SAME: () [[ATTR0]] {
828; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR2]], [[RNG0]]
829; IS__CGSCC_OPM-NEXT:    ret i32 [[RET]]
830;
831; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
832; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3
833; IS__CGSCC_NPM-SAME: () [[ATTR0]] {
834; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR1]], [[RNG0]]
835; IS__CGSCC_NPM-NEXT:    ret i32 [[RET]]
836;
837  %ret = call i32 @potential_test13_callee(i32 undef)
838  ret i32 %ret
839}
840
841define i1 @potential_test14(i1 %c0, i1 %c1, i1 %c2, i1 %c3) {
842; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
843; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test14
844; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR0]] {
845; IS__TUNIT____-NEXT:    [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1
846; IS__TUNIT____-NEXT:    [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef
847; IS__TUNIT____-NEXT:    [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7
848; IS__TUNIT____-NEXT:    [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]]
849; IS__TUNIT____-NEXT:    [[RET:%.*]] = icmp slt i32 [[Z3]], 7
850; IS__TUNIT____-NEXT:    ret i1 [[RET]]
851;
852; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
853; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test14
854; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR0]] {
855; IS__CGSCC____-NEXT:    [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1
856; IS__CGSCC____-NEXT:    [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef
857; IS__CGSCC____-NEXT:    [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7
858; IS__CGSCC____-NEXT:    [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]]
859; IS__CGSCC____-NEXT:    [[RET:%.*]] = icmp slt i32 [[Z3]], 7
860; IS__CGSCC____-NEXT:    ret i1 [[RET]]
861;
862  %x0 = select i1 %c0, i32 0, i32 1
863  %x1 = select i1 %c1, i32 %x0, i32 undef
864  %y2 = select i1 %c2, i32 0, i32 7
865  %z3 = select i1 %c3, i32 %x1, i32 %y2
866  %ret = icmp slt i32 %z3, 7
867  ret i1 %ret
868}
869
870define i1 @potential_test15(i1 %c0, i1 %c1) {
871; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
872; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test15
873; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] {
874; IS__TUNIT____-NEXT:    ret i1 false
875;
876; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
877; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test15
878; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] {
879; IS__CGSCC____-NEXT:    ret i1 false
880;
881  %x0 = select i1 %c0, i32 0, i32 1
882  %x1 = select i1 %c1, i32 %x0, i32 undef
883  %ret = icmp eq i32 %x1, 7
884  ret i1 %ret
885}
886
887define i1 @potential_test16(i1 %c0, i1 %c1) {
888; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
889; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test16
890; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] {
891; IS__TUNIT____-NEXT:    ret i1 false
892;
893; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
894; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test16
895; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] {
896; IS__CGSCC____-NEXT:    ret i1 false
897;
898  %x0 = select i1 %c0, i32 0, i32 undef
899  %x1 = select i1 %c1, i32 %x0, i32 1
900  %ret = icmp eq i32 %x1, 7
901  ret i1 %ret
902}
903
904; IS__TUNIT_NPM: !0 = !{i32 0, i32 2}
905; IS__TUNIT_NPM: !1 = !{i32 1, i32 4}
906; IS__TUNIT_NPM: !2 = !{i32 3, i32 5}
907; IS__TUNIT_NPM: !3 = !{i32 -1, i32 1}
908; IS__TUNIT_NPM-NOT: !4
909
910; IS__TUNIT_OPM: !0 = !{i32 1, i32 4}
911; IS__TUNIT_OPM: !1 = !{i32 3, i32 5}
912; IS__TUNIT_OPM: !2 = !{i32 0, i32 2}
913; IS__TUNIT_OPM: !3 = !{i32 -1, i32 1}
914; IS__TUNIT_OPM-NOT: !4
915