Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / Attributor / value-simplify-instances.ll
blobb1b907cd6250f3904181f25f283f6f18b20e7177
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
7 declare ptr @geti1Ptr()
9 ; Make sure we do *not* return true.
11 ; CHECK: @[[G1:[a-zA-Z0-9_$"\\.-]+]] = private global ptr undef
12 ; CHECK: @[[G2:[a-zA-Z0-9_$"\\.-]+]] = private global ptr undef
13 ; CHECK: @[[G3:[a-zA-Z0-9_$"\\.-]+]] = private global i1 undef
15 define internal i1 @recursive_inst_comparator(ptr %a, ptr %b) {
16 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
17 ; CHECK-LABEL: define {{[^@]+}}@recursive_inst_comparator
18 ; CHECK-SAME: (ptr noalias nofree readnone [[A:%.*]], ptr noalias nofree readnone [[B:%.*]]) #[[ATTR0:[0-9]+]] {
19 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[B]]
20 ; CHECK-NEXT:    ret i1 [[CMP]]
22   %cmp = icmp eq ptr %a, %b
23   ret i1 %cmp
26 define internal i1 @recursive_inst_generator(i1 %c, ptr %p) {
27 ; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_generator
28 ; TUNIT-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) {
29 ; TUNIT-NEXT:    [[A:%.*]] = call ptr @geti1Ptr()
30 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
31 ; TUNIT:       t:
32 ; TUNIT-NEXT:    [[R1:%.*]] = call i1 @recursive_inst_comparator(ptr noalias nofree readnone [[A]], ptr noalias nofree readnone [[P]]) #[[ATTR7:[0-9]+]]
33 ; TUNIT-NEXT:    ret i1 [[R1]]
34 ; TUNIT:       f:
35 ; TUNIT-NEXT:    [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, ptr nofree [[A]])
36 ; TUNIT-NEXT:    ret i1 [[R2]]
38 ; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_generator
39 ; CGSCC-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) {
40 ; CGSCC-NEXT:    [[A:%.*]] = call ptr @geti1Ptr()
41 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
42 ; CGSCC:       t:
43 ; CGSCC-NEXT:    [[R1:%.*]] = call i1 @recursive_inst_comparator(ptr noalias nofree readnone [[A]], ptr noalias nofree readnone [[P]])
44 ; CGSCC-NEXT:    ret i1 [[R1]]
45 ; CGSCC:       f:
46 ; CGSCC-NEXT:    [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, ptr nofree [[A]])
47 ; CGSCC-NEXT:    ret i1 [[R2]]
49   %a = call ptr @geti1Ptr()
50   br i1 %c, label %t, label %f
52   %r1 = call i1 @recursive_inst_comparator(ptr %a, ptr %p)
53   ret i1 %r1
55   %r2 = call i1 @recursive_inst_generator(i1 true, ptr %a)
56   ret i1 %r2
59 ; FIXME: This should *not* return true.
60 define i1 @recursive_inst_generator_caller(i1 %c) {
61 ; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_generator_caller
62 ; TUNIT-SAME: (i1 [[C:%.*]]) {
63 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_generator(i1 [[C]], ptr undef)
64 ; TUNIT-NEXT:    ret i1 [[CALL]]
66 ; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_generator_caller
67 ; CGSCC-SAME: (i1 [[C:%.*]]) {
68 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_generator(i1 [[C]], ptr nofree undef)
69 ; CGSCC-NEXT:    ret i1 [[CALL]]
71   %call = call i1 @recursive_inst_generator(i1 %c, ptr undef)
72   ret i1 %call
75 ; Make sure we do *not* return true.
76 define internal i1 @recursive_inst_compare(i1 %c, ptr %p) {
77 ; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare
78 ; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
79 ; CHECK-NEXT:    [[A:%.*]] = call ptr @geti1Ptr()
80 ; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
81 ; CHECK:       t:
82 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
83 ; CHECK-NEXT:    ret i1 [[CMP]]
84 ; CHECK:       f:
85 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 noundef true, ptr [[A]])
86 ; CHECK-NEXT:    ret i1 [[CALL]]
88   %a = call ptr @geti1Ptr()
89   br i1 %c, label %t, label %f
91   %cmp = icmp eq ptr %a, %p
92   ret i1 %cmp
94   %call = call i1 @recursive_inst_compare(i1 true, ptr %a)
95   ret i1 %call
98 ; FIXME: This should *not* return true.
99 define i1 @recursive_inst_compare_caller(i1 %c) {
100 ; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare_caller
101 ; CHECK-SAME: (i1 [[C:%.*]]) {
102 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 [[C]], ptr undef)
103 ; CHECK-NEXT:    ret i1 [[CALL]]
105   %call = call i1 @recursive_inst_compare(i1 %c, ptr undef)
106   ret i1 %call
109 ; Make sure we do *not* return true.
110 define internal i1 @recursive_alloca_compare(i1 %c, ptr %p) {
111 ; CHECK: Function Attrs: nofree nosync nounwind memory(none)
112 ; CHECK-LABEL: define {{[^@]+}}@recursive_alloca_compare
113 ; CHECK-SAME: (i1 noundef [[C:%.*]], ptr noalias nofree readnone [[P:%.*]]) #[[ATTR1:[0-9]+]] {
114 ; CHECK-NEXT:    [[A:%.*]] = alloca i1, align 1
115 ; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
116 ; CHECK:       t:
117 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
118 ; CHECK-NEXT:    ret i1 [[CMP]]
119 ; CHECK:       f:
120 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef true, ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A]]) #[[ATTR1]]
121 ; CHECK-NEXT:    ret i1 [[CALL]]
123   %a = alloca i1
124   br i1 %c, label %t, label %f
126   %cmp = icmp eq ptr %a, %p
127   ret i1 %cmp
129   %call = call i1 @recursive_alloca_compare(i1 true, ptr %a)
130   ret i1 %call
133 ; FIXME: This should *not* return true.
134 define i1 @recursive_alloca_compare_caller(i1 %c) {
135 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
136 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller
137 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
138 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef [[C]], ptr undef) #[[ATTR1]]
139 ; TUNIT-NEXT:    ret i1 [[CALL]]
141 ; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
142 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller
143 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {
144 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef [[C]], ptr nofree undef) #[[ATTR1]]
145 ; CGSCC-NEXT:    ret i1 [[CALL]]
147   %call = call i1 @recursive_alloca_compare(i1 %c, ptr undef)
148   ret i1 %call
151 ; Make sure we do *not* simplify this to return 0 or 1, return 42 is ok though.
152 define internal i8 @recursive_alloca_load_return(i1 %c, ptr %p, i8 %v) {
153 ; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
154 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_load_return
155 ; TUNIT-SAME: (i1 noundef [[C:%.*]], ptr noalias nocapture nofree readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR3:[0-9]+]] {
156 ; TUNIT-NEXT:    [[A:%.*]] = alloca i8, align 1
157 ; TUNIT-NEXT:    store i8 [[V]], ptr [[A]], align 1
158 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
159 ; TUNIT:       t:
160 ; TUNIT-NEXT:    store i8 0, ptr [[A]], align 1
161 ; TUNIT-NEXT:    [[L:%.*]] = load i8, ptr [[P]], align 1
162 ; TUNIT-NEXT:    ret i8 [[L]]
163 ; TUNIT:       f:
164 ; TUNIT-NEXT:    [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4:[0-9]+]]
165 ; TUNIT-NEXT:    ret i8 [[CALL]]
167 ; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
168 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_load_return
169 ; CGSCC-SAME: (i1 noundef [[C:%.*]], ptr noalias nocapture nofree readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR2:[0-9]+]] {
170 ; CGSCC-NEXT:    [[A:%.*]] = alloca i8, align 1
171 ; CGSCC-NEXT:    store i8 [[V]], ptr [[A]], align 1
172 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
173 ; CGSCC:       t:
174 ; CGSCC-NEXT:    store i8 0, ptr [[A]], align 1
175 ; CGSCC-NEXT:    [[L:%.*]] = load i8, ptr [[P]], align 1
176 ; CGSCC-NEXT:    ret i8 [[L]]
177 ; CGSCC:       f:
178 ; CGSCC-NEXT:    [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR3:[0-9]+]]
179 ; CGSCC-NEXT:    ret i8 [[CALL]]
181   %a = alloca i8
182   store i8 %v, ptr %a
183   br i1 %c, label %t, label %f
185   store i8 0, ptr %a
186   %l = load i8, ptr %p
187   ret i8 %l
189   %call = call i8 @recursive_alloca_load_return(i1 true, ptr %a, i8 1)
190   ret i8 %call
193 define i8 @recursive_alloca_load_return_caller(i1 %c) {
194 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
195 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller
196 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
197 ; TUNIT-NEXT:    [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef [[C]], ptr undef, i8 noundef 42) #[[ATTR4]]
198 ; TUNIT-NEXT:    ret i8 [[CALL]]
200 ; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
201 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller
202 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {
203 ; CGSCC-NEXT:    [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef [[C]], ptr nofree undef, i8 noundef 42) #[[ATTR5:[0-9]+]]
204 ; CGSCC-NEXT:    ret i8 [[CALL]]
206   %call = call i8 @recursive_alloca_load_return(i1 %c, ptr undef, i8 42)
207   ret i8 %call
210 @G1 = private global ptr undef
211 @G2 = private global ptr undef
212 @G3 = private global i1 undef
214 ; Make sure we do *not* return true.
215 define internal i1 @recursive_alloca_compare_global1(i1 %c) {
216 ; TUNIT: Function Attrs: nofree nosync nounwind
217 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1
218 ; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR4]] {
219 ; TUNIT-NEXT:    [[A:%.*]] = alloca i1, align 1
220 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
221 ; TUNIT:       t:
222 ; TUNIT-NEXT:    [[P:%.*]] = load ptr, ptr @G1, align 8
223 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
224 ; TUNIT-NEXT:    ret i1 [[CMP]]
225 ; TUNIT:       f:
226 ; TUNIT-NEXT:    store ptr [[A]], ptr @G1, align 8
227 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR4]]
228 ; TUNIT-NEXT:    ret i1 [[CALL]]
230 ; CGSCC: Function Attrs: nofree nosync nounwind
231 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1
232 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
233 ; CGSCC-NEXT:    [[A:%.*]] = alloca i1, align 1
234 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
235 ; CGSCC:       t:
236 ; CGSCC-NEXT:    [[P:%.*]] = load ptr, ptr @G1, align 8
237 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
238 ; CGSCC-NEXT:    ret i1 [[CMP]]
239 ; CGSCC:       f:
240 ; CGSCC-NEXT:    store ptr [[A]], ptr @G1, align 8
241 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR3]]
242 ; CGSCC-NEXT:    ret i1 [[CALL]]
244   %a = alloca i1
245   br i1 %c, label %t, label %f
247   %p = load ptr, ptr @G1
248   %cmp = icmp eq ptr %a, %p
249   ret i1 %cmp
251   store ptr %a, ptr @G1
252   %call = call i1 @recursive_alloca_compare_global1(i1 true)
253   ret i1 %call
256 ; FIXME: This should *not* return true.
257 define i1 @recursive_alloca_compare_caller_global1(i1 %c) {
258 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind
259 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global1
260 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR5:[0-9]+]] {
261 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef [[C]]) #[[ATTR4]]
262 ; TUNIT-NEXT:    ret i1 [[CALL]]
264 ; CGSCC: Function Attrs: nofree nosync nounwind
265 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global1
266 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
267 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef [[C]]) #[[ATTR5]]
268 ; CGSCC-NEXT:    ret i1 [[CALL]]
270   %call = call i1 @recursive_alloca_compare_global1(i1 %c)
271   ret i1 %call
274 define internal i1 @recursive_alloca_compare_global2(i1 %c) {
275 ; TUNIT: Function Attrs: nofree nosync nounwind
276 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2
277 ; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR4]] {
278 ; TUNIT-NEXT:    [[A:%.*]] = alloca i1, align 1
279 ; TUNIT-NEXT:    [[P:%.*]] = load ptr, ptr @G2, align 8
280 ; TUNIT-NEXT:    store ptr [[A]], ptr @G2, align 8
281 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
282 ; TUNIT:       t:
283 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
284 ; TUNIT-NEXT:    ret i1 [[CMP]]
285 ; TUNIT:       f:
286 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR4]]
287 ; TUNIT-NEXT:    ret i1 [[CALL]]
289 ; CGSCC: Function Attrs: nofree nosync nounwind
290 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2
291 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
292 ; CGSCC-NEXT:    [[A:%.*]] = alloca i1, align 1
293 ; CGSCC-NEXT:    [[P:%.*]] = load ptr, ptr @G2, align 8
294 ; CGSCC-NEXT:    store ptr [[A]], ptr @G2, align 8
295 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
296 ; CGSCC:       t:
297 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
298 ; CGSCC-NEXT:    ret i1 [[CMP]]
299 ; CGSCC:       f:
300 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR3]]
301 ; CGSCC-NEXT:    ret i1 [[CALL]]
303   %a = alloca i1
304   %p = load ptr, ptr @G2
305   store ptr %a, ptr @G2
306   br i1 %c, label %t, label %f
308   %cmp = icmp eq ptr %a, %p
309   ret i1 %cmp
311   %call = call i1 @recursive_alloca_compare_global2(i1 true)
312   ret i1 %call
315 ; FIXME: This should *not* return true.
316 define i1 @recursive_alloca_compare_caller_global2(i1 %c) {
317 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind
318 ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global2
319 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR5]] {
320 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef [[C]]) #[[ATTR4]]
321 ; TUNIT-NEXT:    ret i1 [[CALL]]
323 ; CGSCC: Function Attrs: nofree nosync nounwind
324 ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global2
325 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
326 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef [[C]]) #[[ATTR5]]
327 ; CGSCC-NEXT:    ret i1 [[CALL]]
329   %call = call i1 @recursive_alloca_compare_global2(i1 %c)
330   ret i1 %call
332 define internal i1 @recursive_inst_compare_global3(i1 %c) {
334 ; TUNIT: Function Attrs: nofree nosync nounwind
335 ; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_compare_global3
336 ; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR4]] {
337 ; TUNIT-NEXT:    [[P:%.*]] = load i1, ptr @G3, align 1
338 ; TUNIT-NEXT:    store i1 [[C]], ptr @G3, align 1
339 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
340 ; TUNIT:       t:
341 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp eq i1 [[C]], [[P]]
342 ; TUNIT-NEXT:    ret i1 [[CMP]]
343 ; TUNIT:       f:
344 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR4]]
345 ; TUNIT-NEXT:    ret i1 [[CALL]]
347 ; CGSCC: Function Attrs: nofree nosync nounwind
348 ; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_compare_global3
349 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
350 ; CGSCC-NEXT:    [[P:%.*]] = load i1, ptr @G3, align 1
351 ; CGSCC-NEXT:    store i1 [[C]], ptr @G3, align 1
352 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
353 ; CGSCC:       t:
354 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i1 [[C]], [[P]]
355 ; CGSCC-NEXT:    ret i1 [[CMP]]
356 ; CGSCC:       f:
357 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR3]]
358 ; CGSCC-NEXT:    ret i1 [[CALL]]
360   %p = load i1, ptr @G3
361   store i1 %c, ptr @G3
362   br i1 %c, label %t, label %f
364   %cmp = icmp eq i1 %c, %p
365   ret i1 %cmp
367   %call = call i1 @recursive_inst_compare_global3(i1 true)
368   ret i1 %call
371 ; FIXME: This should *not* return true.
372 define i1 @recursive_inst_compare_caller_global3(i1 %c) {
373 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind
374 ; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_compare_caller_global3
375 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR5]] {
376 ; TUNIT-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef [[C]]) #[[ATTR4]]
377 ; TUNIT-NEXT:    ret i1 [[CALL]]
379 ; CGSCC: Function Attrs: nofree nosync nounwind
380 ; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_compare_caller_global3
381 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
382 ; CGSCC-NEXT:    [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef [[C]]) #[[ATTR5]]
383 ; CGSCC-NEXT:    ret i1 [[CALL]]
385   %call = call i1 @recursive_inst_compare_global3(i1 %c)
386   ret i1 %call
389 define i32 @non_unique_phi_ops(ptr %ptr) {
390 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
391 ; TUNIT-LABEL: define {{[^@]+}}@non_unique_phi_ops
392 ; TUNIT-SAME: (ptr nocapture nofree readonly [[PTR:%.*]]) #[[ATTR6:[0-9]+]] {
393 ; TUNIT-NEXT:  entry:
394 ; TUNIT-NEXT:    br label [[HEADER:%.*]]
395 ; TUNIT:       header:
396 ; TUNIT-NEXT:    [[I:%.*]] = phi i32 [ [[ADD:%.*]], [[F:%.*]] ], [ 0, [[ENTRY:%.*]] ]
397 ; TUNIT-NEXT:    [[P:%.*]] = phi i32 [ [[NON_UNIQUE:%.*]], [[F]] ], [ poison, [[ENTRY]] ]
398 ; TUNIT-NEXT:    [[ADD]] = add i32 [[I]], 1
399 ; TUNIT-NEXT:    [[G:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[I]]
400 ; TUNIT-NEXT:    [[NON_UNIQUE_INPUT:%.*]] = load i32, ptr [[G]], align 4
401 ; TUNIT-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I]], [[NON_UNIQUE_INPUT]]
402 ; TUNIT-NEXT:    br i1 [[CMP1]], label [[T:%.*]], label [[F]]
403 ; TUNIT:       t:
404 ; TUNIT-NEXT:    br label [[F]]
405 ; TUNIT:       f:
406 ; TUNIT-NEXT:    [[NON_UNIQUE]] = phi i32 [ [[NON_UNIQUE_INPUT]], [[T]] ], [ [[P]], [[HEADER]] ]
407 ; TUNIT-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 42
408 ; TUNIT-NEXT:    br i1 [[CMP2]], label [[HEADER]], label [[END:%.*]]
409 ; TUNIT:       end:
410 ; TUNIT-NEXT:    ret i32 [[P]]
412 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
413 ; CGSCC-LABEL: define {{[^@]+}}@non_unique_phi_ops
414 ; CGSCC-SAME: (ptr nocapture nofree readonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] {
415 ; CGSCC-NEXT:  entry:
416 ; CGSCC-NEXT:    br label [[HEADER:%.*]]
417 ; CGSCC:       header:
418 ; CGSCC-NEXT:    [[I:%.*]] = phi i32 [ [[ADD:%.*]], [[F:%.*]] ], [ 0, [[ENTRY:%.*]] ]
419 ; CGSCC-NEXT:    [[P:%.*]] = phi i32 [ [[NON_UNIQUE:%.*]], [[F]] ], [ poison, [[ENTRY]] ]
420 ; CGSCC-NEXT:    [[ADD]] = add i32 [[I]], 1
421 ; CGSCC-NEXT:    [[G:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[I]]
422 ; CGSCC-NEXT:    [[NON_UNIQUE_INPUT:%.*]] = load i32, ptr [[G]], align 4
423 ; CGSCC-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I]], [[NON_UNIQUE_INPUT]]
424 ; CGSCC-NEXT:    br i1 [[CMP1]], label [[T:%.*]], label [[F]]
425 ; CGSCC:       t:
426 ; CGSCC-NEXT:    br label [[F]]
427 ; CGSCC:       f:
428 ; CGSCC-NEXT:    [[NON_UNIQUE]] = phi i32 [ [[NON_UNIQUE_INPUT]], [[T]] ], [ [[P]], [[HEADER]] ]
429 ; CGSCC-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[I]], 42
430 ; CGSCC-NEXT:    br i1 [[CMP2]], label [[HEADER]], label [[END:%.*]]
431 ; CGSCC:       end:
432 ; CGSCC-NEXT:    ret i32 [[P]]
434 entry:
435   br label %header
437 header:
438   %i = phi i32 [ %add, %f ], [ 0, %entry ]
439   %p = phi i32 [ %non_unique, %f ], [ poison, %entry ]
440   %add = add i32 %i, 1
441   %g = getelementptr i32, ptr %ptr, i32 %i
442   %non_unique_input = load i32, ptr %g, align 4
443   %cmp1 = icmp eq i32 %i, %non_unique_input
444   br i1 %cmp1, label %t, label %f
446   br label %f
448   %non_unique = phi i32 [ %non_unique_input, %t ], [ %p, %header ]
449   %cmp2 = icmp slt i32 %i, 42
450   br i1 %cmp2, label %header, label %end
452 end:
453   ret i32 %p
457 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
458 ; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind memory(none) }
459 ; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) }
460 ; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind memory(argmem: readwrite) }
461 ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind }
462 ; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind }
463 ; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
464 ; TUNIT: attributes #[[ATTR7]] = { nounwind memory(none) }
466 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
467 ; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind memory(none) }
468 ; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind memory(argmem: readwrite) }
469 ; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind }
470 ; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
471 ; CGSCC: attributes #[[ATTR5]] = { nofree nounwind }