xref: /llvm-project/llvm/test/Transforms/Attributor/value-simplify.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
4
5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6declare void @f(i32)
7declare token @llvm.call.preallocated.setup(i32)
8declare ptr @llvm.call.preallocated.arg(token, i32)
9
10@str = private unnamed_addr addrspace(4) constant [1 x i8] c"\00", align 1
11@ConstAS3Ptr = addrspace(3) global i32 0, align 4
12@ConstPtr = constant i32 0, align 4
13@ConstWeakPtr = weak constant i32 0, align 4
14@ConstWeakODRPtr = weak_odr constant i32 0, align 4
15
16;.
17; CHECK: @str = private unnamed_addr addrspace(4) constant [1 x i8] zeroinitializer, align 1
18; CHECK: @ConstAS3Ptr = addrspace(3) global i32 0, align 4
19; CHECK: @ConstPtr = constant i32 0, align 4
20; CHECK: @ConstWeakPtr = weak constant i32 0, align 4
21; CHECK: @ConstWeakODRPtr = weak_odr constant i32 0, align 4
22; CHECK: @S = external global %struct.X
23; CHECK: @g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] }
24; CHECK: @x = external global i32
25;.
26define internal ptr addrspace(3) @const_ptr_return_as3() {
27; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
28; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return_as3
29; CGSCC-SAME: () #[[ATTR1:[0-9]+]] {
30; CGSCC-NEXT:    ret ptr addrspace(3) @ConstAS3Ptr
31;
32  ret ptr addrspace(3) @ConstAS3Ptr
33}
34define internal ptr @const_ptr_return() {
35; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
36; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return
37; CGSCC-SAME: () #[[ATTR1]] {
38; CGSCC-NEXT:    ret ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr)
39;
40  ret ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr)
41}
42
43; Test1: Replace argument with constant
44define internal void @test1(i32 %a) {
45; TUNIT: Function Attrs: memory(readwrite, argmem: none)
46; TUNIT-LABEL: define {{[^@]+}}@test1
47; TUNIT-SAME: () #[[ATTR1:[0-9]+]] {
48; TUNIT-NEXT:    tail call void @f(i32 noundef 1)
49; TUNIT-NEXT:    ret void
50;
51; CGSCC: Function Attrs: memory(readwrite, argmem: none)
52; CGSCC-LABEL: define {{[^@]+}}@test1
53; CGSCC-SAME: () #[[ATTR2:[0-9]+]] {
54; CGSCC-NEXT:    tail call void @f(i32 noundef 1)
55; CGSCC-NEXT:    ret void
56;
57  tail call void @f(i32 %a)
58  ret void
59}
60
61define void @test1_helper() {
62; CHECK-LABEL: define {{[^@]+}}@test1_helper() {
63; CHECK-NEXT:    tail call void @test1()
64; CHECK-NEXT:    ret void
65;
66  tail call void @test1(i32 1)
67  ret void
68}
69
70; TEST 2 : Simplify return value
71define i32 @return0() {
72; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
73; TUNIT-LABEL: define {{[^@]+}}@return0
74; TUNIT-SAME: () #[[ATTR2:[0-9]+]] {
75; TUNIT-NEXT:    ret i32 0
76;
77; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
78; CGSCC-LABEL: define {{[^@]+}}@return0
79; CGSCC-SAME: () #[[ATTR1]] {
80; CGSCC-NEXT:    ret i32 0
81;
82  ret i32 0
83}
84
85define i32 @return1() {
86; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
87; TUNIT-LABEL: define {{[^@]+}}@return1
88; TUNIT-SAME: () #[[ATTR2]] {
89; TUNIT-NEXT:    ret i32 1
90;
91; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
92; CGSCC-LABEL: define {{[^@]+}}@return1
93; CGSCC-SAME: () #[[ATTR1]] {
94; CGSCC-NEXT:    ret i32 1
95;
96  ret i32 1
97}
98
99define i32 @test2_1(i1 %c) {
100; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
101; TUNIT-LABEL: define {{[^@]+}}@test2_1
102; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
103; TUNIT-NEXT:    br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
104; TUNIT:       if.true:
105; TUNIT-NEXT:    [[RET0:%.*]] = add i32 0, 1
106; TUNIT-NEXT:    br label [[END:%.*]]
107; TUNIT:       if.false:
108; TUNIT-NEXT:    br label [[END]]
109; TUNIT:       end:
110; TUNIT-NEXT:    [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
111; TUNIT-NEXT:    ret i32 1
112;
113; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
114; CGSCC-LABEL: define {{[^@]+}}@test2_1
115; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3:[0-9]+]] {
116; CGSCC-NEXT:    br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
117; CGSCC:       if.true:
118; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @return0() #[[ATTR12:[0-9]+]]
119; CGSCC-NEXT:    [[RET0:%.*]] = add i32 [[CALL]], 1
120; CGSCC-NEXT:    br label [[END:%.*]]
121; CGSCC:       if.false:
122; CGSCC-NEXT:    [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]]
123; CGSCC-NEXT:    br label [[END]]
124; CGSCC:       end:
125; CGSCC-NEXT:    [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ]
126; CGSCC-NEXT:    ret i32 1
127;
128  br i1 %c, label %if.true, label %if.false
129if.true:
130  %call = tail call i32 @return0()
131  %ret0 = add i32 %call, 1
132  br label %end
133if.false:
134  %ret1 = tail call i32 @return1()
135  br label %end
136end:
137
138  %ret = phi i32 [ %ret0, %if.true ], [ %ret1, %if.false ]
139
140  ret i32 1
141}
142
143
144
145define i32 @test2_2(i1 %c) {
146; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
147; TUNIT-LABEL: define {{[^@]+}}@test2_2
148; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
149; TUNIT-NEXT:    ret i32 1
150;
151; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
152; CGSCC-LABEL: define {{[^@]+}}@test2_2
153; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
154; CGSCC-NEXT:    [[RET:%.*]] = tail call noundef i32 @test2_1(i1 noundef [[C]]) #[[ATTR12]]
155; CGSCC-NEXT:    ret i32 [[RET]]
156;
157  %ret = tail call i32 @test2_1(i1 %c)
158  ret i32 %ret
159}
160
161declare void @use(i32)
162define void @test3(i1 %c) {
163; TUNIT-LABEL: define {{[^@]+}}@test3
164; TUNIT-SAME: (i1 noundef [[C:%.*]]) {
165; TUNIT-NEXT:    br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
166; TUNIT:       if.true:
167; TUNIT-NEXT:    br label [[END:%.*]]
168; TUNIT:       if.false:
169; TUNIT-NEXT:    br label [[END]]
170; TUNIT:       end:
171; TUNIT-NEXT:    [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
172; TUNIT-NEXT:    tail call void @use(i32 noundef 1)
173; TUNIT-NEXT:    ret void
174;
175; CGSCC-LABEL: define {{[^@]+}}@test3
176; CGSCC-SAME: (i1 noundef [[C:%.*]]) {
177; CGSCC-NEXT:    br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
178; CGSCC:       if.true:
179; CGSCC-NEXT:    br label [[END:%.*]]
180; CGSCC:       if.false:
181; CGSCC-NEXT:    [[RET1:%.*]] = tail call i32 @return1() #[[ATTR13:[0-9]+]]
182; CGSCC-NEXT:    br label [[END]]
183; CGSCC:       end:
184; CGSCC-NEXT:    [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ]
185; CGSCC-NEXT:    tail call void @use(i32 noundef [[R]])
186; CGSCC-NEXT:    ret void
187;
188  br i1 %c, label %if.true, label %if.false
189if.true:
190  br label %end
191if.false:
192  %ret1 = tail call i32 @return1()
193  br label %end
194end:
195
196  %r = phi i32 [ 1, %if.true ], [ %ret1, %if.false ]
197
198  tail call void @use(i32 %r)
199  ret void
200}
201
202define void @test-select-phi(i1 %c) {
203; CHECK-LABEL: define {{[^@]+}}@test-select-phi
204; CHECK-SAME: (i1 [[C:%.*]]) {
205; CHECK-NEXT:    tail call void @use(i32 noundef 1)
206; CHECK-NEXT:    [[SELECT_NOT_SAME:%.*]] = select i1 [[C]], i32 1, i32 0
207; CHECK-NEXT:    tail call void @use(i32 noundef [[SELECT_NOT_SAME]])
208; CHECK-NEXT:    br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
209; CHECK:       if-true:
210; CHECK-NEXT:    br label [[END:%.*]]
211; CHECK:       if-false:
212; CHECK-NEXT:    br label [[END]]
213; CHECK:       end:
214; CHECK-NEXT:    [[PHI_SAME:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
215; CHECK-NEXT:    [[PHI_NOT_SAME:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
216; CHECK-NEXT:    [[PHI_SAME_PROP:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
217; CHECK-NEXT:    [[PHI_SAME_UNDEF:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ undef, [[IF_FALSE]] ]
218; CHECK-NEXT:    [[SELECT_NOT_SAME_UNDEF:%.*]] = select i1 [[C]], i32 [[PHI_NOT_SAME]], i32 undef
219; CHECK-NEXT:    tail call void @use(i32 noundef 1)
220; CHECK-NEXT:    tail call void @use(i32 noundef [[PHI_NOT_SAME]])
221; CHECK-NEXT:    tail call void @use(i32 noundef 1)
222; CHECK-NEXT:    tail call void @use(i32 1)
223; CHECK-NEXT:    tail call void @use(i32 [[SELECT_NOT_SAME_UNDEF]])
224; CHECK-NEXT:    ret void
225;
226  %select-same = select i1 %c, i32 1, i32 1
227  tail call void @use(i32 %select-same)
228
229  %select-not-same = select i1 %c, i32 1, i32 0
230  tail call void @use(i32 %select-not-same)
231  br i1 %c, label %if-true, label %if-false
232if-true:
233  br label %end
234if-false:
235  br label %end
236end:
237  %phi-same = phi i32 [ 1, %if-true ], [ 1, %if-false ]
238  %phi-not-same = phi i32 [ 0, %if-true ], [ 1, %if-false ]
239  %phi-same-prop = phi i32 [ 1, %if-true ], [ %select-same, %if-false ]
240  %phi-same-undef = phi i32 [ 1, %if-true ], [ undef, %if-false ]
241  %select-not-same-undef = select i1 %c, i32 %phi-not-same, i32 undef
242
243
244  tail call void @use(i32 %phi-same)
245
246  tail call void @use(i32 %phi-not-same)
247
248  tail call void @use(i32 %phi-same-prop)
249
250  tail call void @use(i32 %phi-same-undef)
251
252  tail call void @use(i32 %select-not-same-undef)
253
254  ret void
255
256}
257
258define i32 @ipccp1(i32 %a) {
259; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
260; TUNIT-LABEL: define {{[^@]+}}@ipccp1
261; TUNIT-SAME: (i32 returned [[A:%.*]]) #[[ATTR2]] {
262; TUNIT-NEXT:    br i1 true, label [[T:%.*]], label [[F:%.*]]
263; TUNIT:       t:
264; TUNIT-NEXT:    ret i32 [[A]]
265; TUNIT:       f:
266; TUNIT-NEXT:    unreachable
267;
268; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
269; CGSCC-LABEL: define {{[^@]+}}@ipccp1
270; CGSCC-SAME: (i32 returned [[A:%.*]]) #[[ATTR1]] {
271; CGSCC-NEXT:    br i1 true, label [[T:%.*]], label [[F:%.*]]
272; CGSCC:       t:
273; CGSCC-NEXT:    ret i32 [[A]]
274; CGSCC:       f:
275; CGSCC-NEXT:    unreachable
276;
277  br i1 true, label %t, label %f
278t:
279  ret i32 %a
280f:
281  %r = call i32 @ipccp1(i32 5)
282  ret i32 %r
283}
284
285define internal i1 @ipccp2i(i1 %a) {
286; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
287; CGSCC-LABEL: define {{[^@]+}}@ipccp2i
288; CGSCC-SAME: () #[[ATTR1]] {
289; CGSCC-NEXT:    br label [[T:%.*]]
290; CGSCC:       t:
291; CGSCC-NEXT:    ret i1 true
292; CGSCC:       f:
293; CGSCC-NEXT:    unreachable
294;
295  br i1 %a, label %t, label %f
296t:
297  ret i1 %a
298f:
299  %r = call i1 @ipccp2i(i1 false)
300  ret i1 %r
301}
302
303define i1 @ipccp2() {
304; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
305; TUNIT-LABEL: define {{[^@]+}}@ipccp2
306; TUNIT-SAME: () #[[ATTR2]] {
307; TUNIT-NEXT:    ret i1 true
308;
309; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
310; CGSCC-LABEL: define {{[^@]+}}@ipccp2
311; CGSCC-SAME: () #[[ATTR3]] {
312; CGSCC-NEXT:    [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR12]]
313; CGSCC-NEXT:    ret i1 [[R]]
314;
315  %r = call i1 @ipccp2i(i1 true)
316  ret i1 %r
317}
318
319define internal i1 @ipccp2ib(i1 %a) {
320; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
321; CGSCC-LABEL: define {{[^@]+}}@ipccp2ib
322; CGSCC-SAME: () #[[ATTR1]] {
323; CGSCC-NEXT:    br label [[T:%.*]]
324; CGSCC:       t:
325; CGSCC-NEXT:    ret i1 true
326; CGSCC:       f:
327; CGSCC-NEXT:    unreachable
328;
329  br i1 %a, label %t, label %f
330t:
331  ret i1 true
332f:
333  %r = call i1 @ipccp2ib(i1 false)
334  ret i1 %r
335}
336
337define i1 @ipccp2b() {
338; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
339; TUNIT-LABEL: define {{[^@]+}}@ipccp2b
340; TUNIT-SAME: () #[[ATTR2]] {
341; TUNIT-NEXT:    ret i1 true
342;
343; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
344; CGSCC-LABEL: define {{[^@]+}}@ipccp2b
345; CGSCC-SAME: () #[[ATTR3]] {
346; CGSCC-NEXT:    [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR12]]
347; CGSCC-NEXT:    ret i1 [[R]]
348;
349  %r = call i1 @ipccp2ib(i1 true)
350  ret i1 %r
351}
352
353define internal i32 @ipccp3i(i32 %a) {
354; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
355; CGSCC-LABEL: define {{[^@]+}}@ipccp3i
356; CGSCC-SAME: () #[[ATTR1]] {
357; CGSCC-NEXT:    br label [[T:%.*]]
358; CGSCC:       t:
359; CGSCC-NEXT:    ret i32 7
360; CGSCC:       f:
361; CGSCC-NEXT:    unreachable
362;
363  %c = icmp eq i32 %a, 7
364  br i1 %c, label %t, label %f
365t:
366  ret i32 %a
367f:
368  %r = call i32 @ipccp3i(i32 5)
369  ret i32 %r
370}
371
372define i32 @ipccp3() {
373; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
374; TUNIT-LABEL: define {{[^@]+}}@ipccp3
375; TUNIT-SAME: () #[[ATTR2]] {
376; TUNIT-NEXT:    ret i32 7
377;
378; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
379; CGSCC-LABEL: define {{[^@]+}}@ipccp3
380; CGSCC-SAME: () #[[ATTR3]] {
381; CGSCC-NEXT:    [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR12]]
382; CGSCC-NEXT:    ret i32 [[R]]
383;
384  %r = call i32 @ipccp3i(i32 7)
385  ret i32 %r
386}
387
388define internal i32 @ipccp4ia(i1 %c) {
389; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
390; CGSCC-LABEL: define {{[^@]+}}@ipccp4ia
391; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {
392; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
393; CGSCC:       t:
394; CGSCC-NEXT:    ret i32 0
395; CGSCC:       f:
396; CGSCC-NEXT:    ret i32 1
397;
398  br i1 %c, label %t, label %f
399t:
400  ret i32 0
401f:
402  ret i32 1
403}
404define internal i32 @ipccp4ib(i32 %a) {
405; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
406; CGSCC-LABEL: define {{[^@]+}}@ipccp4ib
407; CGSCC-SAME: () #[[ATTR3]] {
408; CGSCC-NEXT:    br label [[T:%.*]]
409; CGSCC:       t:
410; CGSCC-NEXT:    [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR12]]
411; CGSCC-NEXT:    ret i32 [[R]]
412; CGSCC:       f:
413; CGSCC-NEXT:    unreachable
414;
415  %c = icmp eq i32 %a, 7
416  br i1 %c, label %t, label %f
417t:
418  %r = call i32 @ipccp4ia(i1 %c)
419  ret i32 %r
420f:
421  ret i32 1
422}
423
424define i32 @ipccp4(i1 %c) {
425; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
426; TUNIT-LABEL: define {{[^@]+}}@ipccp4
427; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
428; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
429; TUNIT:       t:
430; TUNIT-NEXT:    br label [[F]]
431; TUNIT:       f:
432; TUNIT-NEXT:    ret i32 0
433;
434; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
435; CGSCC-LABEL: define {{[^@]+}}@ipccp4
436; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
437; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
438; CGSCC:       t:
439; CGSCC-NEXT:    br label [[F]]
440; CGSCC:       f:
441; CGSCC-NEXT:    [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR12]]
442; CGSCC-NEXT:    ret i32 [[R]]
443;
444  br i1 %c, label %t, label %f
445t:
446  %q = call i32 @ipccp4ia(i1 undef)
447  br label %f
448f:
449  %r = call i32 @ipccp4ib(i32 7)
450  ret i32 %r
451}
452
453; Do not touch complicated arguments (for now)
454%struct.X = type { ptr }
455define internal ptr @test_inalloca(ptr inalloca(i32) %a) {
456; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
457; TUNIT-LABEL: define {{[^@]+}}@test_inalloca
458; TUNIT-SAME: (ptr noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] {
459; TUNIT-NEXT:    ret ptr [[A]]
460;
461; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
462; CGSCC-LABEL: define {{[^@]+}}@test_inalloca
463; CGSCC-SAME: (ptr noalias nofree noundef nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
464; CGSCC-NEXT:    ret ptr [[A]]
465;
466  ret ptr %a
467}
468define ptr @complicated_args_inalloca(ptr %arg) {
469; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
470; TUNIT-LABEL: define {{[^@]+}}@complicated_args_inalloca
471; TUNIT-SAME: (ptr nofree nonnull readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR2]] {
472; TUNIT-NEXT:    [[CALL:%.*]] = call nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree nonnull writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]]
473; TUNIT-NEXT:    ret ptr [[CALL]]
474;
475; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
476; CGSCC-LABEL: define {{[^@]+}}@complicated_args_inalloca
477; CGSCC-SAME: (ptr nofree noundef nonnull readnone dereferenceable(4) [[ARG:%.*]]) #[[ATTR3]] {
478; CGSCC-NEXT:    [[CALL:%.*]] = call noalias noundef nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[ARG]]) #[[ATTR12]]
479; CGSCC-NEXT:    ret ptr [[CALL]]
480;
481  %call = call ptr @test_inalloca(ptr inalloca(i32) %arg)
482  ret ptr %call
483}
484
485define internal ptr @test_preallocated(ptr preallocated(i32) %a) {
486; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
487; TUNIT-LABEL: define {{[^@]+}}@test_preallocated
488; TUNIT-SAME: (ptr noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] {
489; TUNIT-NEXT:    ret ptr [[A]]
490;
491; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
492; CGSCC-LABEL: define {{[^@]+}}@test_preallocated
493; CGSCC-SAME: (ptr noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
494; CGSCC-NEXT:    ret ptr [[A]]
495;
496  ret ptr %a
497}
498define ptr @complicated_args_preallocated() {
499; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
500; TUNIT-LABEL: define {{[^@]+}}@complicated_args_preallocated
501; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
502; TUNIT-NEXT:    [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR10:[0-9]+]]
503; TUNIT-NEXT:    [[CALL:%.*]] = call noundef nonnull align 4294967296 dereferenceable(4) ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR9]] [ "preallocated"(token [[C]]) ]
504; TUNIT-NEXT:    ret ptr [[CALL]]
505;
506; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
507; CGSCC-LABEL: define {{[^@]+}}@complicated_args_preallocated
508; CGSCC-SAME: () #[[ATTR4:[0-9]+]] {
509; CGSCC-NEXT:    [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13]]
510; CGSCC-NEXT:    [[CALL:%.*]] = call ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR14:[0-9]+]] [ "preallocated"(token [[C]]) ]
511; CGSCC-NEXT:    unreachable
512;
513  %c = call token @llvm.call.preallocated.setup(i32 1)
514  %call = call ptr @test_preallocated(ptr preallocated(i32) null) ["preallocated"(token %c)]
515  ret ptr %call
516}
517
518define internal void @test_sret(ptr sret(%struct.X) %a, ptr %b) {
519;
520; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
521; TUNIT-LABEL: define {{[^@]+}}@test_sret
522; TUNIT-SAME: (ptr noalias nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) [[A:%.*]], ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR4:[0-9]+]] {
523; TUNIT-NEXT:    store ptr [[A]], ptr [[B]], align 8
524; TUNIT-NEXT:    ret void
525;
526; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
527; CGSCC-LABEL: define {{[^@]+}}@test_sret
528; CGSCC-SAME: (ptr noalias nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) [[A:%.*]], ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR5:[0-9]+]] {
529; CGSCC-NEXT:    store ptr [[A]], ptr [[B]], align 8
530; CGSCC-NEXT:    ret void
531;
532  store ptr %a, ptr %b
533  ret void
534}
535; FIXME: Alignment and dereferenceability are not propagated to the argument
536define void @complicated_args_sret(ptr %b) {
537;
538;
539; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
540; TUNIT-LABEL: define {{[^@]+}}@complicated_args_sret
541; TUNIT-SAME: (ptr nofree writeonly captures(none) [[B:%.*]]) #[[ATTR4]] {
542; TUNIT-NEXT:    call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, ptr nofree noundef writeonly align 8 captures(none) [[B]]) #[[ATTR11:[0-9]+]]
543; TUNIT-NEXT:    ret void
544;
545; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)
546; CGSCC-LABEL: define {{[^@]+}}@complicated_args_sret
547; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR6:[0-9]+]] {
548; CGSCC-NEXT:    call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) null, ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B]]) #[[ATTR15:[0-9]+]]
549; CGSCC-NEXT:    ret void
550;
551  call void @test_sret(ptr sret(%struct.X) null, ptr %b)
552  ret void
553}
554
555define internal ptr @test_nest(ptr nest %a) {
556; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
557; CGSCC-LABEL: define {{[^@]+}}@test_nest
558; CGSCC-SAME: (ptr nest noalias nofree readnone align 4294967296 captures(none) [[A:%.*]]) #[[ATTR1]] {
559; CGSCC-NEXT:    ret ptr null
560;
561  ret ptr %a
562}
563define ptr @complicated_args_nest() {
564; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
565; TUNIT-LABEL: define {{[^@]+}}@complicated_args_nest
566; TUNIT-SAME: () #[[ATTR2]] {
567; TUNIT-NEXT:    ret ptr null
568;
569; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
570; CGSCC-LABEL: define {{[^@]+}}@complicated_args_nest
571; CGSCC-SAME: () #[[ATTR3]] {
572; CGSCC-NEXT:    [[CALL:%.*]] = call noalias noundef align 4294967296 ptr @test_nest(ptr nofree noundef readnone align 4294967296 null) #[[ATTR12]]
573; CGSCC-NEXT:    ret ptr [[CALL]]
574;
575  %call = call ptr @test_nest(ptr null)
576  ret ptr %call
577}
578
579@S = external global %struct.X
580define internal void @test_byval(ptr byval(%struct.X) %a) {
581; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
582; TUNIT-LABEL: define {{[^@]+}}@test_byval
583; TUNIT-SAME: (ptr [[TMP0:%.*]]) #[[ATTR4]] {
584; TUNIT-NEXT:    [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8
585; TUNIT-NEXT:    store ptr [[TMP0]], ptr [[A_PRIV]], align 8
586; TUNIT-NEXT:    store ptr null, ptr [[A_PRIV]], align 8
587; TUNIT-NEXT:    ret void
588;
589; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
590; CGSCC-LABEL: define {{[^@]+}}@test_byval
591; CGSCC-SAME: (ptr nofree [[TMP0:%.*]]) #[[ATTR5]] {
592; CGSCC-NEXT:    [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8
593; CGSCC-NEXT:    store ptr [[TMP0]], ptr [[A_PRIV]], align 8
594; CGSCC-NEXT:    store ptr null, ptr [[A_PRIV]], align 8
595; CGSCC-NEXT:    ret void
596;
597  store ptr null, ptr %a
598  ret void
599}
600define void @complicated_args_byval() {
601; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
602; TUNIT-LABEL: define {{[^@]+}}@complicated_args_byval
603; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {
604; TUNIT-NEXT:    [[TMP1:%.*]] = load ptr, ptr @S, align 8
605; TUNIT-NEXT:    call void @test_byval(ptr [[TMP1]]) #[[ATTR11]]
606; TUNIT-NEXT:    ret void
607;
608; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
609; CGSCC-LABEL: define {{[^@]+}}@complicated_args_byval
610; CGSCC-SAME: () #[[ATTR4]] {
611; CGSCC-NEXT:    [[TMP1:%.*]] = load ptr, ptr @S, align 8
612; CGSCC-NEXT:    call void @test_byval(ptr nofree writeonly [[TMP1]]) #[[ATTR15]]
613; CGSCC-NEXT:    ret void
614;
615  call void @test_byval(ptr byval(%struct.X) @S)
616  ret void
617}
618
619declare void @sync()
620; Make sure we *do not* load @S here!
621define internal ptr @test_byval2(ptr byval(%struct.X) %a) {
622; CHECK-LABEL: define {{[^@]+}}@test_byval2
623; CHECK-SAME: (ptr [[TMP0:%.*]]) {
624; CHECK-NEXT:    [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8
625; CHECK-NEXT:    store ptr [[TMP0]], ptr [[A_PRIV]], align 8
626; CHECK-NEXT:    call void @sync()
627; CHECK-NEXT:    [[L:%.*]] = load ptr, ptr [[A_PRIV]], align 8
628; CHECK-NEXT:    ret ptr [[L]]
629;
630  call void @sync()
631  %l = load ptr, ptr %a
632  ret ptr %l
633}
634define ptr @complicated_args_byval2() {
635;
636; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval2() {
637; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr @S, align 8
638; CHECK-NEXT:    [[C:%.*]] = call ptr @test_byval2(ptr [[TMP1]])
639; CHECK-NEXT:    ret ptr [[C]]
640;
641  %c = call ptr @test_byval2(ptr byval(%struct.X) @S)
642  ret ptr %c
643}
644
645define void @fixpoint_changed(ptr %p) {
646; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
647; TUNIT-LABEL: define {{[^@]+}}@fixpoint_changed
648; TUNIT-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR4]] {
649; TUNIT-NEXT:  entry:
650; TUNIT-NEXT:    br label [[FOR_COND:%.*]]
651; TUNIT:       for.cond:
652; TUNIT-NEXT:    [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
653; TUNIT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
654; TUNIT-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
655; TUNIT:       for.body:
656; TUNIT-NEXT:    switch i32 [[J_0]], label [[SW_EPILOG]] [
657; TUNIT-NEXT:      i32 1, label [[SW_BB:%.*]]
658; TUNIT-NEXT:    ]
659; TUNIT:       sw.bb:
660; TUNIT-NEXT:    br label [[SW_EPILOG]]
661; TUNIT:       sw.epilog:
662; TUNIT-NEXT:    [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
663; TUNIT-NEXT:    store i32 [[X_0]], ptr [[P]], align 4
664; TUNIT-NEXT:    [[INC]] = add nsw i32 [[J_0]], 1
665; TUNIT-NEXT:    br label [[FOR_COND]]
666; TUNIT:       for.end:
667; TUNIT-NEXT:    ret void
668;
669; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
670; CGSCC-LABEL: define {{[^@]+}}@fixpoint_changed
671; CGSCC-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR5]] {
672; CGSCC-NEXT:  entry:
673; CGSCC-NEXT:    br label [[FOR_COND:%.*]]
674; CGSCC:       for.cond:
675; CGSCC-NEXT:    [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
676; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
677; CGSCC-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
678; CGSCC:       for.body:
679; CGSCC-NEXT:    switch i32 [[J_0]], label [[SW_EPILOG]] [
680; CGSCC-NEXT:      i32 1, label [[SW_BB:%.*]]
681; CGSCC-NEXT:    ]
682; CGSCC:       sw.bb:
683; CGSCC-NEXT:    br label [[SW_EPILOG]]
684; CGSCC:       sw.epilog:
685; CGSCC-NEXT:    [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
686; CGSCC-NEXT:    store i32 [[X_0]], ptr [[P]], align 4
687; CGSCC-NEXT:    [[INC]] = add nsw i32 [[J_0]], 1
688; CGSCC-NEXT:    br label [[FOR_COND]]
689; CGSCC:       for.end:
690; CGSCC-NEXT:    ret void
691;
692entry:
693  br label %for.cond
694
695for.cond:
696  %j.0 = phi i32 [ 0, %entry ], [ %inc, %sw.epilog ]
697  %cmp = icmp slt i32 %j.0, 30
698  br i1 %cmp, label %for.body, label %for.end
699
700for.body:
701  switch i32 %j.0, label %sw.epilog [
702  i32 1, label %sw.bb
703  ]
704
705sw.bb:
706  br label %sw.epilog
707
708sw.epilog:
709  %x.0 = phi i32 [ 255, %for.body ], [ 253, %sw.bb ]
710  store i32 %x.0, ptr %p
711  %inc = add nsw i32 %j.0, 1
712  br label %for.cond
713
714for.end:
715  ret void
716}
717
718; Check we merge undef and a constant properly.
719define i8 @caller0() {
720; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
721; TUNIT-LABEL: define {{[^@]+}}@caller0
722; TUNIT-SAME: () #[[ATTR2]] {
723; TUNIT-NEXT:    ret i8 49
724;
725; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
726; CGSCC-LABEL: define {{[^@]+}}@caller0
727; CGSCC-SAME: () #[[ATTR3]] {
728; CGSCC-NEXT:    [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]
729; CGSCC-NEXT:    ret i8 [[C]]
730;
731  %c = call i8 @callee(i8 undef)
732  ret i8 %c
733}
734define i8 @caller1() {
735; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
736; TUNIT-LABEL: define {{[^@]+}}@caller1
737; TUNIT-SAME: () #[[ATTR2]] {
738; TUNIT-NEXT:    ret i8 49
739;
740; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
741; CGSCC-LABEL: define {{[^@]+}}@caller1
742; CGSCC-SAME: () #[[ATTR3]] {
743; CGSCC-NEXT:    [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]
744; CGSCC-NEXT:    ret i8 [[C]]
745;
746  %c = call i8 @callee(i8 undef)
747  ret i8 %c
748}
749define i8 @caller2() {
750; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
751; TUNIT-LABEL: define {{[^@]+}}@caller2
752; TUNIT-SAME: () #[[ATTR2]] {
753; TUNIT-NEXT:    ret i8 49
754;
755; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
756; CGSCC-LABEL: define {{[^@]+}}@caller2
757; CGSCC-SAME: () #[[ATTR3]] {
758; CGSCC-NEXT:    [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]
759; CGSCC-NEXT:    ret i8 [[C]]
760;
761  %c = call i8 @callee(i8 undef)
762  ret i8 %c
763}
764define i8 @caller_middle() {
765; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
766; TUNIT-LABEL: define {{[^@]+}}@caller_middle
767; TUNIT-SAME: () #[[ATTR2]] {
768; TUNIT-NEXT:    ret i8 49
769;
770; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
771; CGSCC-LABEL: define {{[^@]+}}@caller_middle
772; CGSCC-SAME: () #[[ATTR3]] {
773; CGSCC-NEXT:    [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]
774; CGSCC-NEXT:    ret i8 [[C]]
775;
776  %c = call i8 @callee(i8 42)
777  ret i8 %c
778}
779define i8 @caller3() {
780; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
781; TUNIT-LABEL: define {{[^@]+}}@caller3
782; TUNIT-SAME: () #[[ATTR2]] {
783; TUNIT-NEXT:    ret i8 49
784;
785; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
786; CGSCC-LABEL: define {{[^@]+}}@caller3
787; CGSCC-SAME: () #[[ATTR3]] {
788; CGSCC-NEXT:    [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]
789; CGSCC-NEXT:    ret i8 [[C]]
790;
791  %c = call i8 @callee(i8 undef)
792  ret i8 %c
793}
794define i8 @caller4() {
795; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
796; TUNIT-LABEL: define {{[^@]+}}@caller4
797; TUNIT-SAME: () #[[ATTR2]] {
798; TUNIT-NEXT:    ret i8 49
799;
800; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
801; CGSCC-LABEL: define {{[^@]+}}@caller4
802; CGSCC-SAME: () #[[ATTR3]] {
803; CGSCC-NEXT:    [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]
804; CGSCC-NEXT:    ret i8 [[C]]
805;
806  %c = call i8 @callee(i8 undef)
807  ret i8 %c
808}
809define internal i8 @callee(i8 %a) {
810; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
811; CGSCC-LABEL: define {{[^@]+}}@callee
812; CGSCC-SAME: () #[[ATTR1]] {
813; CGSCC-NEXT:    ret i8 49
814;
815  %c = add i8 %a, 7
816  ret i8 %c
817}
818
819define void @user_as3() {
820; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
821; TUNIT-LABEL: define {{[^@]+}}@user_as3
822; TUNIT-SAME: () #[[ATTR5]] {
823; TUNIT-NEXT:    store i32 0, ptr addrspace(3) @ConstAS3Ptr, align 4
824; TUNIT-NEXT:    ret void
825;
826; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
827; CGSCC-LABEL: define {{[^@]+}}@user_as3
828; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {
829; CGSCC-NEXT:    [[CALL:%.*]] = call fastcc align 4 ptr addrspace(3) @const_ptr_return_as3() #[[ATTR12]]
830; CGSCC-NEXT:    store i32 0, ptr addrspace(3) [[CALL]], align 4
831; CGSCC-NEXT:    ret void
832;
833  %call = call fastcc ptr addrspace(3) @const_ptr_return_as3()
834  store i32 0, ptr addrspace(3) %call
835  ret void
836}
837define void @user() {
838; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
839; TUNIT-LABEL: define {{[^@]+}}@user
840; TUNIT-SAME: () #[[ATTR5]] {
841; TUNIT-NEXT:    store i32 0, ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr), align 4
842; TUNIT-NEXT:    ret void
843;
844; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
845; CGSCC-LABEL: define {{[^@]+}}@user
846; CGSCC-SAME: () #[[ATTR7]] {
847; CGSCC-NEXT:    [[CALL:%.*]] = call fastcc align 4 ptr @const_ptr_return() #[[ATTR12]]
848; CGSCC-NEXT:    store i32 0, ptr [[CALL]], align 4
849; CGSCC-NEXT:    ret void
850;
851  %call = call fastcc ptr @const_ptr_return()
852  store i32 0, ptr %call
853  ret void
854}
855
856
857define i1 @test_merge_with_undef_values_ptr(i1 %c) {
858; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
859; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
860; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
861; TUNIT-NEXT:    ret i1 false
862;
863; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
864; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
865; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
866; CGSCC-NEXT:    [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR12]]
867; CGSCC-NEXT:    ret i1 [[R1]]
868;
869  %r1 = call i1 @undef_then_null(i1 %c, ptr undef, ptr undef)
870  ret i1 %r1
871}
872define internal i1 @undef_then_null(i1 %c, ptr %i32Aptr, ptr %i32Bptr) {
873; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
874; CGSCC-LABEL: define {{[^@]+}}@undef_then_null
875; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
876; CGSCC-NEXT:    [[OR:%.*]] = or i1 false, [[C]]
877; CGSCC-NEXT:    br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
878; CGSCC:       a:
879; CGSCC-NEXT:    ret i1 false
880; CGSCC:       b:
881; CGSCC-NEXT:    ret i1 false
882;
883  %cmp1 = icmp eq ptr %i32Aptr, %i32Bptr
884  %cmp2 = icmp eq i1 %cmp1, false
885  %or = or i1 %cmp2, %c
886  br i1 %or, label %a, label %b
887a:
888  %r2 = call i1 @undef_then_null(i1 false, ptr null, ptr null)
889  ret i1 %r2
890b:
891  ret i1 %cmp2
892}
893
894define i1 @test_merge_with_undef_values(i1 %c) {
895; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
896; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values
897; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
898; TUNIT-NEXT:    ret i1 false
899;
900; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
901; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values
902; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
903; CGSCC-NEXT:    [[R1:%.*]] = call i1 @undef_then_1(i1 [[C]]) #[[ATTR12]]
904; CGSCC-NEXT:    ret i1 [[R1]]
905;
906  %r1 = call i1 @undef_then_1(i1 %c, i32 undef, i32 undef)
907  ret i1 %r1
908}
909define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) {
910;
911; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
912; CGSCC-LABEL: define {{[^@]+}}@undef_then_1
913; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
914; CGSCC-NEXT:    [[OR:%.*]] = or i1 false, [[C]]
915; CGSCC-NEXT:    br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
916; CGSCC:       a:
917; CGSCC-NEXT:    ret i1 false
918; CGSCC:       b:
919; CGSCC-NEXT:    ret i1 false
920;
921  %cmp1 = icmp eq i32 %i32A, %i32B
922  %cmp2 = icmp eq i1 %cmp1, false
923  %or = or i1 %cmp2, %c
924  br i1 %or, label %a, label %b
925a:
926  %r2 = call i1 @undef_then_1(i1 false, i32 1, i32 1)
927  ret i1 %r2
928b:
929  ret i1 %cmp2
930}
931
932define i32 @test_select(i32 %c) {
933; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
934; TUNIT-LABEL: define {{[^@]+}}@test_select
935; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR2]] {
936; TUNIT-NEXT:    ret i32 42
937;
938; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
939; CGSCC-LABEL: define {{[^@]+}}@test_select
940; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR3]] {
941; CGSCC-NEXT:    [[CALL:%.*]] = call noundef i32 @select() #[[ATTR12]]
942; CGSCC-NEXT:    ret i32 [[CALL]]
943;
944  %call = call i32 @select(i1 1, i32 42, i32 %c)
945  ret i32 %call
946}
947
948define internal i32 @select(i1 %a, i32 %b, i32 %c) {
949; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
950; CGSCC-LABEL: define {{[^@]+}}@select
951; CGSCC-SAME: () #[[ATTR1]] {
952; CGSCC-NEXT:    ret i32 42
953;
954  %s = select i1 %a, i32 %b, i32 %c
955  ret i32 %s
956}
957
958define i1 @icmp() {
959; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
960; TUNIT-LABEL: define {{[^@]+}}@icmp
961; TUNIT-SAME: () #[[ATTR2]] {
962; TUNIT-NEXT:    ret i1 true
963;
964; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
965; CGSCC-LABEL: define {{[^@]+}}@icmp
966; CGSCC-SAME: () #[[ATTR1]] {
967; CGSCC-NEXT:    ret i1 true
968;
969  %c = icmp eq ptr null, null
970  ret i1 %c
971}
972
973define void @test_callee_is_undef(ptr %fn) {
974; TUNIT-LABEL: define {{[^@]+}}@test_callee_is_undef
975; TUNIT-SAME: (ptr nofree captures(none) [[FN:%.*]]) {
976; TUNIT-NEXT:    call void @unknown_calle_arg_is_undef(ptr nofree noundef captures(none) [[FN]])
977; TUNIT-NEXT:    ret void
978;
979; CGSCC-LABEL: define {{[^@]+}}@test_callee_is_undef
980; CGSCC-SAME: (ptr nofree noundef nonnull captures(none) [[FN:%.*]]) {
981; CGSCC-NEXT:    call void @unknown_calle_arg_is_undef(ptr nofree noundef nonnull captures(none) [[FN]])
982; CGSCC-NEXT:    ret void
983;
984  call void @callee_is_undef(ptr undef)
985  call void @unknown_calle_arg_is_undef(ptr %fn, i32 undef)
986  ret void
987}
988define internal void @callee_is_undef(ptr %fn) {
989;
990; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
991; CGSCC-LABEL: define {{[^@]+}}@callee_is_undef
992; CGSCC-SAME: () #[[ATTR1]] {
993; CGSCC-NEXT:    unreachable
994;
995  call void %fn()
996  ret void
997}
998define internal void @unknown_calle_arg_is_undef(ptr %fn, i32 %arg) {
999;
1000; CHECK-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef
1001; CHECK-SAME: (ptr nofree noundef nonnull captures(none) [[FN:%.*]]) {
1002; CHECK-NEXT:    call void [[FN]](i32 undef)
1003; CHECK-NEXT:    ret void
1004;
1005  call void %fn(i32 %arg)
1006  ret void
1007}
1008
1009; Taken from 50683
1010; {{{
1011
1012@g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] }
1013
1014define internal void @f1(ptr %a) {
1015; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
1016; TUNIT-LABEL: define {{[^@]+}}@f1
1017; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
1018; TUNIT-NEXT:  entry:
1019; TUNIT-NEXT:    store ptr @g, ptr [[A]], align 8
1020; TUNIT-NEXT:    ret void
1021;
1022; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
1023; CGSCC-LABEL: define {{[^@]+}}@f1
1024; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR5]] {
1025; CGSCC-NEXT:  entry:
1026; CGSCC-NEXT:    store ptr @g, ptr [[A]], align 8
1027; CGSCC-NEXT:    ret void
1028;
1029entry:
1030  store ptr @g , ptr %a, align 8
1031  ret void
1032}
1033
1034define internal void @f2(ptr %a) {
1035; CHECK-LABEL: define {{[^@]+}}@f2
1036; CHECK-SAME: (ptr [[A:%.*]]) {
1037; CHECK-NEXT:  cont461:
1038; CHECK-NEXT:    call void @f3(ptr [[A]], ptr nofree captures(none) [[A]])
1039; CHECK-NEXT:    ret void
1040;
1041cont461:
1042  call void @f3(ptr %a, ptr %a)
1043  ret void
1044}
1045
1046define internal void @f3(ptr %a1, ptr %a) {
1047; CHECK-LABEL: define {{[^@]+}}@f3
1048; CHECK-SAME: (ptr [[A1:%.*]], ptr nofree captures(none) [[A:%.*]]) {
1049; CHECK-NEXT:  entry:
1050; CHECK-NEXT:    [[CALL20:%.*]] = call i1 @f9()
1051; CHECK-NEXT:    br i1 [[CALL20]], label [[LAND_LHS_TRUE:%.*]], label [[IF_END40:%.*]]
1052; CHECK:       land.lhs.true:
1053; CHECK-NEXT:    [[TMP0:%.*]] = call i1 [[A]](ptr [[A1]])
1054; CHECK-NEXT:    br label [[IF_END40]]
1055; CHECK:       if.end40:
1056; CHECK-NEXT:    ret void
1057;
1058entry:
1059  %call20 = call i1 @f9()
1060  br i1 %call20, label %land.lhs.true, label %if.end40
1061
1062land.lhs.true:
1063  call i1 %a(ptr %a1)
1064  br label %if.end40
1065
1066if.end40:
1067  ret void
1068}
1069
1070define linkonce_odr i1 @f9() {
1071; CHECK-LABEL: define {{[^@]+}}@f9() {
1072; CHECK-NEXT:  entry:
1073; CHECK-NEXT:    ret i1 false
1074;
1075entry:
1076  ret i1 false
1077}
1078
1079; }}}
1080
1081
1082define i1 @test_cmp_null_after_cast() {
1083; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1084; TUNIT-LABEL: define {{[^@]+}}@test_cmp_null_after_cast
1085; TUNIT-SAME: () #[[ATTR2]] {
1086; TUNIT-NEXT:    ret i1 true
1087;
1088; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1089; CGSCC-LABEL: define {{[^@]+}}@test_cmp_null_after_cast
1090; CGSCC-SAME: () #[[ATTR3]] {
1091; CGSCC-NEXT:    [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR12]]
1092; CGSCC-NEXT:    ret i1 [[C]]
1093;
1094  %c = call i1 @cmp_null_after_cast(i32 0, i8 0)
1095  ret i1 %c
1096}
1097define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) {
1098; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1099; CGSCC-LABEL: define {{[^@]+}}@cmp_null_after_cast
1100; CGSCC-SAME: () #[[ATTR1]] {
1101; CGSCC-NEXT:    ret i1 true
1102;
1103  %t = trunc i32 %a to i8
1104  %c = icmp eq i8 %t, %b
1105  ret i1 %c
1106}
1107
1108
1109declare ptr @m()
1110
1111define i32 @test(i1 %c) {
1112; TUNIT-LABEL: define {{[^@]+}}@test
1113; TUNIT-SAME: (i1 [[C:%.*]]) {
1114; TUNIT-NEXT:    [[R1:%.*]] = call i32 @ctx_test1(i1 noundef [[C]])
1115; TUNIT-NEXT:    [[R2:%.*]] = call i32 @ctx_test2(i1 noundef [[C]]), !range [[RNG0:![0-9]+]]
1116; TUNIT-NEXT:    [[ADD:%.*]] = add i32 [[R1]], [[R2]]
1117; TUNIT-NEXT:    ret i32 [[ADD]]
1118;
1119; CGSCC-LABEL: define {{[^@]+}}@test
1120; CGSCC-SAME: (i1 noundef [[C:%.*]]) {
1121; CGSCC-NEXT:    [[R1:%.*]] = call i32 @ctx_test1(i1 noundef [[C]])
1122; CGSCC-NEXT:    [[R2:%.*]] = call i32 @ctx_test2(i1 noundef [[C]])
1123; CGSCC-NEXT:    [[ADD:%.*]] = add i32 [[R1]], [[R2]]
1124; CGSCC-NEXT:    ret i32 [[ADD]]
1125;
1126  %r1 = call i32 @ctx_test1(i1 %c)
1127  %r2 = call i32 @ctx_test2(i1 %c)
1128  %add = add i32 %r1, %r2
1129  ret i32 %add
1130}
1131
1132define internal i32 @ctx_test1(i1 %c) {
1133; CHECK-LABEL: define {{[^@]+}}@ctx_test1
1134; CHECK-SAME: (i1 noundef [[C:%.*]]) {
1135; CHECK-NEXT:  entry:
1136; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]]
1137; CHECK:       then:
1138; CHECK-NEXT:    [[M:%.*]] = tail call ptr @m()
1139; CHECK-NEXT:    [[I:%.*]] = ptrtoint ptr [[M]] to i64
1140; CHECK-NEXT:    br label [[JOIN]]
1141; CHECK:       join:
1142; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]
1143; CHECK-NEXT:    [[RET:%.*]] = trunc i64 [[PHI]] to i32
1144; CHECK-NEXT:    ret i32 [[RET]]
1145;
1146entry:
1147  br i1 %c, label %then, label %join
1148
1149then:
1150  %m = tail call ptr @m()
1151  %i = ptrtoint ptr %m to i64
1152  br label %join
1153
1154join:
1155  %phi = phi i64 [ %i, %then ], [ undef, %entry ]
1156  %ret = trunc i64 %phi to i32
1157  ret i32 %ret
1158}
1159
1160define internal i32 @ctx_test2(i1 %c) {
1161; CHECK-LABEL: define {{[^@]+}}@ctx_test2
1162; CHECK-SAME: (i1 noundef [[C:%.*]]) {
1163; CHECK-NEXT:  entry:
1164; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]]
1165; CHECK:       then:
1166; CHECK-NEXT:    [[M:%.*]] = tail call ptr @m()
1167; CHECK-NEXT:    [[I:%.*]] = ptrtoint ptr [[M]] to i32
1168; CHECK-NEXT:    br label [[JOIN]]
1169; CHECK:       join:
1170; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]
1171; CHECK-NEXT:    [[RET:%.*]] = lshr i32 [[PHI]], 1
1172; CHECK-NEXT:    ret i32 [[RET]]
1173;
1174entry:
1175  br i1 %c, label %then, label %join
1176
1177then:
1178  %m = tail call ptr @m()
1179  %i = ptrtoint ptr %m to i32
1180  br label %join
1181
1182join:
1183  %phi = phi i32 [ %i, %then ], [ undef, %entry ]
1184  %ret = lshr i32 %phi, 1
1185  ret i32 %ret
1186
1187  uselistorder label %join, { 1, 0 }
1188}
1189
1190define i1 @test_liveness(i1 %c) {
1191; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1192; TUNIT-LABEL: define {{[^@]+}}@test_liveness
1193; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
1194; TUNIT-NEXT:  entry:
1195; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1196; TUNIT:       t:
1197; TUNIT-NEXT:    br label [[F]]
1198; TUNIT:       f:
1199; TUNIT-NEXT:    ret i1 false
1200;
1201; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1202; CGSCC-LABEL: define {{[^@]+}}@test_liveness
1203; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {
1204; CGSCC-NEXT:  entry:
1205; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1206; CGSCC:       t:
1207; CGSCC-NEXT:    br label [[F]]
1208; CGSCC:       f:
1209; CGSCC-NEXT:    [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ]
1210; CGSCC-NEXT:    [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR12]]
1211; CGSCC-NEXT:    ret i1 [[RC1]]
1212;
1213entry:
1214  br i1 %c, label %t, label %f
1215t:
1216  br label %f
1217f:
1218  %p = phi i1 [true, %entry], [false, %t]
1219  %rc1 = call i1 @ret(i1 %p)
1220  ret i1 %rc1
1221}
1222
1223define internal i1 @ret(i1 %c) {
1224; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1225; CGSCC-LABEL: define {{[^@]+}}@ret
1226; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {
1227; CGSCC-NEXT:  entry:
1228; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1229; CGSCC:       t:
1230; CGSCC-NEXT:    br label [[F]]
1231; CGSCC:       f:
1232; CGSCC-NEXT:    [[P:%.*]] = phi i1 [ [[C]], [[ENTRY:%.*]] ], [ false, [[T]] ]
1233; CGSCC-NEXT:    ret i1 false
1234;
1235entry:
1236  br i1 %c, label %t, label %f
1237t:
1238  br label %f
1239f:
1240  %p = phi i1 [%c, %entry], [false, %t]
1241  ret i1 %p
1242}
1243
1244declare ptr @unknown()
1245define internal i8 @dead_ret() {
1246; CHECK-LABEL: define {{[^@]+}}@dead_ret() {
1247; CHECK-NEXT:    [[R:%.*]] = call ptr @unknown()
1248; CHECK-NEXT:    ret i8 undef
1249;
1250  %r = call ptr @unknown()
1251  %l = load i8, ptr %r
1252  ret i8 %l
1253}
1254
1255define void @dead_ret_caller() {
1256; CHECK-LABEL: define {{[^@]+}}@dead_ret_caller() {
1257; CHECK-NEXT:    [[R:%.*]] = call i8 @dead_ret()
1258; CHECK-NEXT:    ret void
1259;
1260  %r = call i8 @dead_ret()
1261  ret void
1262}
1263
1264declare void @llvm.memcpy(ptr %dest, ptr %src, i32 %len, i1 %isvolatile)
1265define internal i8 @memcpy_uses_store(i8 %arg) {
1266; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1267; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store
1268; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] {
1269; TUNIT-NEXT:    [[SRC:%.*]] = alloca i8, align 1
1270; TUNIT-NEXT:    [[DST:%.*]] = alloca i8, align 1
1271; TUNIT-NEXT:    store i8 [[ARG]], ptr [[SRC]], align 1
1272; TUNIT-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR12:[0-9]+]]
1273; TUNIT-NEXT:    [[L:%.*]] = load i8, ptr [[DST]], align 1
1274; TUNIT-NEXT:    ret i8 [[L]]
1275;
1276; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1277; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store
1278; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR1]] {
1279; CGSCC-NEXT:    [[SRC:%.*]] = alloca i8, align 1
1280; CGSCC-NEXT:    [[DST:%.*]] = alloca i8, align 1
1281; CGSCC-NEXT:    store i8 [[ARG]], ptr [[SRC]], align 1
1282; CGSCC-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR16:[0-9]+]]
1283; CGSCC-NEXT:    [[L:%.*]] = load i8, ptr [[DST]], align 1
1284; CGSCC-NEXT:    ret i8 [[L]]
1285;
1286  %src = alloca i8
1287  %dst = alloca i8
1288  store i8 %arg, ptr %src
1289  call void @llvm.memcpy(ptr %dst, ptr %src, i32 1, i1 false)
1290  %l = load i8, ptr %dst
1291  ret i8 %l
1292}
1293
1294define i8 @memcpy_uses_store_caller(i8 %arg) {
1295; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1296; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store_caller
1297; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] {
1298; TUNIT-NEXT:    [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR13:[0-9]+]]
1299; TUNIT-NEXT:    ret i8 [[R]]
1300;
1301; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1302; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store_caller
1303; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] {
1304; CGSCC-NEXT:    [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR12]]
1305; CGSCC-NEXT:    ret i8 [[R]]
1306;
1307  %r = call i8 @memcpy_uses_store(i8 %arg)
1308  ret i8 %r
1309}
1310
1311
1312declare i32 @speculatable() speculatable readnone
1313
1314define i32 @test_speculatable_expr() norecurse {
1315; TUNIT: Function Attrs: norecurse nosync memory(none)
1316; TUNIT-LABEL: define {{[^@]+}}@test_speculatable_expr
1317; TUNIT-SAME: () #[[ATTR7:[0-9]+]] {
1318; TUNIT-NEXT:    [[STACK:%.*]] = alloca i32, align 4
1319; TUNIT-NEXT:    [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR14:[0-9]+]]
1320; TUNIT-NEXT:    [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1
1321; TUNIT-NEXT:    store i32 [[PLUS1]], ptr [[STACK]], align 4
1322; TUNIT-NEXT:    [[TMP1:%.*]] = load i32, ptr [[STACK]], align 4
1323; TUNIT-NEXT:    [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[TMP1]]) #[[ATTR15:[0-9]+]]
1324; TUNIT-NEXT:    ret i32 [[RSPEC]]
1325;
1326; CGSCC: Function Attrs: norecurse nosync memory(none)
1327; CGSCC-LABEL: define {{[^@]+}}@test_speculatable_expr
1328; CGSCC-SAME: () #[[ATTR9:[0-9]+]] {
1329; CGSCC-NEXT:    [[STACK:%.*]] = alloca i32, align 4
1330; CGSCC-NEXT:    [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR17:[0-9]+]]
1331; CGSCC-NEXT:    [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1
1332; CGSCC-NEXT:    store i32 [[PLUS1]], ptr [[STACK]], align 4
1333; CGSCC-NEXT:    [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR17]]
1334; CGSCC-NEXT:    ret i32 [[RSPEC]]
1335;
1336  %stack = alloca i32
1337  %spec_result = call i32 @speculatable()
1338  %plus1 = add i32 %spec_result, 1
1339  store i32 %plus1, ptr %stack
1340  %rspec = call i32 @ret_speculatable_expr(ptr %stack, i32 13)
1341  ret i32 %rspec
1342}
1343
1344define internal i32 @ret_speculatable_expr(ptr %mem, i32 %a2) {
1345; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1346; TUNIT-LABEL: define {{[^@]+}}@ret_speculatable_expr
1347; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR2]] {
1348; TUNIT-NEXT:    [[MEM_PRIV:%.*]] = alloca i32, align 4
1349; TUNIT-NEXT:    store i32 [[TMP0]], ptr [[MEM_PRIV]], align 4
1350; TUNIT-NEXT:    [[L:%.*]] = load i32, ptr [[MEM_PRIV]], align 4
1351; TUNIT-NEXT:    [[MUL:%.*]] = mul i32 [[L]], 13
1352; TUNIT-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], 7
1353; TUNIT-NEXT:    ret i32 [[ADD]]
1354;
1355; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1356; CGSCC-LABEL: define {{[^@]+}}@ret_speculatable_expr
1357; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
1358; CGSCC-NEXT:    [[MEM_PRIV:%.*]] = alloca i32, align 4
1359; CGSCC-NEXT:    store i32 [[TMP0]], ptr [[MEM_PRIV]], align 4
1360; CGSCC-NEXT:    [[L:%.*]] = load i32, ptr [[MEM_PRIV]], align 4
1361; CGSCC-NEXT:    [[MUL:%.*]] = mul i32 [[L]], 13
1362; CGSCC-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], 7
1363; CGSCC-NEXT:    ret i32 [[ADD]]
1364;
1365  %l = load i32, ptr %mem
1366  %mul = mul i32 %l, %a2
1367  %add = add i32 %mul, 7
1368  ret i32 %add
1369}
1370
1371define internal void @not_called1() {
1372; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1373; TUNIT-LABEL: define {{[^@]+}}@not_called1
1374; TUNIT-SAME: () #[[ATTR2]] {
1375; TUNIT-NEXT:    ret void
1376;
1377; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1378; CGSCC-LABEL: define {{[^@]+}}@not_called1
1379; CGSCC-SAME: () #[[ATTR1]] {
1380; CGSCC-NEXT:    ret void
1381;
1382  ret void
1383}
1384define internal void @not_called2() {
1385; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1386; TUNIT-LABEL: define {{[^@]+}}@not_called2
1387; TUNIT-SAME: () #[[ATTR2]] {
1388; TUNIT-NEXT:    ret void
1389;
1390; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1391; CGSCC-LABEL: define {{[^@]+}}@not_called2
1392; CGSCC-SAME: () #[[ATTR1]] {
1393; CGSCC-NEXT:    ret void
1394;
1395  ret void
1396}
1397define internal void @not_called3() {
1398; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1399; CGSCC-LABEL: define {{[^@]+}}@not_called3
1400; CGSCC-SAME: () #[[ATTR1]] {
1401; CGSCC-NEXT:    ret void
1402;
1403  ret void
1404}
1405declare void @useFnDecl(ptr addrspace(42));
1406define void @useFnDef(ptr addrspace(42) %arg) {
1407; CHECK-LABEL: define {{[^@]+}}@useFnDef
1408; CHECK-SAME: (ptr addrspace(42) [[ARG:%.*]]) {
1409; CHECK-NEXT:    call void @useFnDecl(ptr addrspace(42) [[ARG]])
1410; CHECK-NEXT:    ret void
1411;
1412  call void @useFnDecl(ptr addrspace(42) %arg)
1413  ret void
1414}
1415define i1 @user_of_not_called() {
1416; CHECK-LABEL: define {{[^@]+}}@user_of_not_called() {
1417; CHECK-NEXT:    call void @useFnDecl(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called1 to ptr addrspace(42)))
1418; CHECK-NEXT:    call void @useFnDef(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called2 to ptr addrspace(42)))
1419; CHECK-NEXT:    ret i1 false
1420;
1421  call void @useFnDecl(ptr addrspace(42) addrspacecast (ptr @not_called1 to ptr addrspace(42)))
1422  call void @useFnDef(ptr addrspace(42) addrspacecast (ptr @not_called2 to ptr addrspace(42)))
1423  %cmp = icmp eq ptr addrspace(42) addrspacecast (ptr @not_called3 to ptr addrspace(42)), null
1424  ret i1 %cmp
1425}
1426
1427@x = external global i32
1428define internal void @indirect() {
1429; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1430; TUNIT-LABEL: define {{[^@]+}}@indirect
1431; TUNIT-SAME: () #[[ATTR5]] {
1432; TUNIT-NEXT:    store i32 0, ptr @x, align 4
1433; TUNIT-NEXT:    ret void
1434;
1435; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1436; CGSCC-LABEL: define {{[^@]+}}@indirect
1437; CGSCC-SAME: () #[[ATTR10:[0-9]+]] {
1438; CGSCC-NEXT:    store i32 0, ptr @x, align 4
1439; CGSCC-NEXT:    ret void
1440;
1441  store i32 0, ptr @x
1442  ret void
1443}
1444
1445define internal void @broker(ptr %ptr) {
1446; TUNIT: Function Attrs: memory(readwrite, argmem: none)
1447; TUNIT-LABEL: define {{[^@]+}}@broker
1448; TUNIT-SAME: () #[[ATTR1]] {
1449; TUNIT-NEXT:  entry:
1450; TUNIT-NEXT:    call void @indirect() #[[ATTR16:[0-9]+]]
1451; TUNIT-NEXT:    call void @unknown()
1452; TUNIT-NEXT:    ret void
1453;
1454; CGSCC: Function Attrs: memory(readwrite, argmem: none)
1455; CGSCC-LABEL: define {{[^@]+}}@broker
1456; CGSCC-SAME: () #[[ATTR2]] {
1457; CGSCC-NEXT:  entry:
1458; CGSCC-NEXT:    call void @indirect() #[[ATTR18:[0-9]+]]
1459; CGSCC-NEXT:    call void @unknown()
1460; CGSCC-NEXT:    ret void
1461;
1462entry:
1463  call void %ptr()
1464  call void @unknown()
1465  ret void
1466}
1467
1468define void @entry() {
1469; CHECK-LABEL: define {{[^@]+}}@entry() {
1470; CHECK-NEXT:  entry:
1471; CHECK-NEXT:    call void @broker()
1472; CHECK-NEXT:    ret void
1473;
1474entry:
1475  call void @broker(ptr @indirect)
1476  ret void
1477}
1478
1479define i8 @switch(i1 %c1, i1 %c2) {
1480; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1481; TUNIT-LABEL: define {{[^@]+}}@switch
1482; TUNIT-SAME: (i1 noundef [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR2]] {
1483; TUNIT-NEXT:  entry:
1484; TUNIT-NEXT:    br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]
1485; TUNIT:       t:
1486; TUNIT-NEXT:    br label [[M:%.*]]
1487; TUNIT:       f:
1488; TUNIT-NEXT:    br label [[M]]
1489; TUNIT:       m:
1490; TUNIT-NEXT:    [[J:%.*]] = phi i32 [ 0, [[T]] ], [ 4, [[F]] ]
1491; TUNIT-NEXT:    switch i32 [[J]], label [[DEFAULT1:%.*]] [
1492; TUNIT-NEXT:      i32 1, label [[DEAD1:%.*]]
1493; TUNIT-NEXT:      i32 2, label [[DEAD2:%.*]]
1494; TUNIT-NEXT:      i32 3, label [[DEAD3:%.*]]
1495; TUNIT-NEXT:      i32 4, label [[ALIVE1:%.*]]
1496; TUNIT-NEXT:    ]
1497; TUNIT:       default1:
1498; TUNIT-NEXT:    br label [[ALIVE1]]
1499; TUNIT:       alive1:
1500; TUNIT-NEXT:    [[K:%.*]] = phi i32 [ 1, [[M]] ], [ 4, [[DEFAULT1]] ]
1501; TUNIT-NEXT:    switch i32 [[K]], label [[DEAD4:%.*]] [
1502; TUNIT-NEXT:      i32 1, label [[END1:%.*]]
1503; TUNIT-NEXT:      i32 2, label [[DEAD5:%.*]]
1504; TUNIT-NEXT:      i32 4, label [[END2:%.*]]
1505; TUNIT-NEXT:    ]
1506; TUNIT:       end1:
1507; TUNIT-NEXT:    ret i8 -1
1508; TUNIT:       end2:
1509; TUNIT-NEXT:    ret i8 -2
1510; TUNIT:       dead1:
1511; TUNIT-NEXT:    unreachable
1512; TUNIT:       dead2:
1513; TUNIT-NEXT:    unreachable
1514; TUNIT:       dead3:
1515; TUNIT-NEXT:    unreachable
1516; TUNIT:       dead4:
1517; TUNIT-NEXT:    unreachable
1518; TUNIT:       dead5:
1519; TUNIT-NEXT:    unreachable
1520;
1521; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1522; CGSCC-LABEL: define {{[^@]+}}@switch
1523; CGSCC-SAME: (i1 noundef [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {
1524; CGSCC-NEXT:  entry:
1525; CGSCC-NEXT:    br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]
1526; CGSCC:       t:
1527; CGSCC-NEXT:    br label [[M:%.*]]
1528; CGSCC:       f:
1529; CGSCC-NEXT:    br label [[M]]
1530; CGSCC:       m:
1531; CGSCC-NEXT:    [[J:%.*]] = phi i32 [ 0, [[T]] ], [ 4, [[F]] ]
1532; CGSCC-NEXT:    switch i32 [[J]], label [[DEFAULT1:%.*]] [
1533; CGSCC-NEXT:      i32 1, label [[DEAD1:%.*]]
1534; CGSCC-NEXT:      i32 2, label [[DEAD2:%.*]]
1535; CGSCC-NEXT:      i32 3, label [[DEAD3:%.*]]
1536; CGSCC-NEXT:      i32 4, label [[ALIVE1:%.*]]
1537; CGSCC-NEXT:    ]
1538; CGSCC:       default1:
1539; CGSCC-NEXT:    br label [[ALIVE1]]
1540; CGSCC:       alive1:
1541; CGSCC-NEXT:    [[K:%.*]] = phi i32 [ 1, [[M]] ], [ 4, [[DEFAULT1]] ]
1542; CGSCC-NEXT:    switch i32 [[K]], label [[DEAD4:%.*]] [
1543; CGSCC-NEXT:      i32 1, label [[END1:%.*]]
1544; CGSCC-NEXT:      i32 2, label [[DEAD5:%.*]]
1545; CGSCC-NEXT:      i32 4, label [[END2:%.*]]
1546; CGSCC-NEXT:    ]
1547; CGSCC:       end1:
1548; CGSCC-NEXT:    ret i8 -1
1549; CGSCC:       end2:
1550; CGSCC-NEXT:    ret i8 -2
1551; CGSCC:       dead1:
1552; CGSCC-NEXT:    unreachable
1553; CGSCC:       dead2:
1554; CGSCC-NEXT:    unreachable
1555; CGSCC:       dead3:
1556; CGSCC-NEXT:    unreachable
1557; CGSCC:       dead4:
1558; CGSCC-NEXT:    unreachable
1559; CGSCC:       dead5:
1560; CGSCC-NEXT:    unreachable
1561;
1562entry:
1563  br i1 %c1, label %t, label %f
1564
1565t:
1566  br label %m
1567
1568f:
1569  br label %m
1570
1571m:
1572  %j = phi i32 [ 0, %t ], [ 4, %f ]
1573  switch i32 %j, label %default1 [
1574  i32 1, label %dead1
1575  i32 2, label %dead2
1576  i32 3, label %dead3
1577  i32 4, label %alive1
1578  ]
1579
1580default1:
1581  br label %alive1
1582
1583alive1:
1584  %k = phi i32 [ 1, %m ], [ 4, %default1 ]
1585  switch i32 %k, label %dead4 [
1586  i32 1, label %end1
1587  i32 2, label %dead5
1588  i32 4, label %end2
1589  ]
1590
1591end1:
1592  ret i8 -1
1593end2:
1594  ret i8 -2
1595dead1:
1596  ret i8 1
1597dead2:
1598  ret i8 2
1599dead3:
1600  ret i8 3
1601dead4:
1602  ret i8 4
1603dead5:
1604  ret i8 5
1605}
1606
1607define i32 @readConst() {
1608; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1609; TUNIT-LABEL: define {{[^@]+}}@readConst
1610; TUNIT-SAME: () #[[ATTR2]] {
1611; TUNIT-NEXT:    ret i32 0
1612;
1613; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1614; CGSCC-LABEL: define {{[^@]+}}@readConst
1615; CGSCC-SAME: () #[[ATTR1]] {
1616; CGSCC-NEXT:    ret i32 0
1617;
1618  %l = load i32, ptr @ConstPtr
1619  ret i32 %l
1620}
1621
1622define i32 @readWeakConst() {
1623; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1624; TUNIT-LABEL: define {{[^@]+}}@readWeakConst
1625; TUNIT-SAME: () #[[ATTR2]] {
1626; TUNIT-NEXT:    [[L:%.*]] = load i32, ptr @ConstWeakPtr, align 4
1627; TUNIT-NEXT:    ret i32 [[L]]
1628;
1629; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1630; CGSCC-LABEL: define {{[^@]+}}@readWeakConst
1631; CGSCC-SAME: () #[[ATTR1]] {
1632; CGSCC-NEXT:    [[L:%.*]] = load i32, ptr @ConstWeakPtr, align 4
1633; CGSCC-NEXT:    ret i32 [[L]]
1634;
1635  %l = load i32, ptr @ConstWeakPtr
1636  ret i32 %l
1637}
1638
1639define i32 @readWeakOdrConst() {
1640; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1641; TUNIT-LABEL: define {{[^@]+}}@readWeakOdrConst
1642; TUNIT-SAME: () #[[ATTR2]] {
1643; TUNIT-NEXT:    ret i32 0
1644;
1645; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1646; CGSCC-LABEL: define {{[^@]+}}@readWeakOdrConst
1647; CGSCC-SAME: () #[[ATTR1]] {
1648; CGSCC-NEXT:    ret i32 0
1649;
1650  %l = load i32, ptr @ConstWeakODRPtr
1651  ret i32 %l
1652}
1653
1654;.
1655; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
1656; TUNIT: attributes #[[ATTR1]] = { memory(readwrite, argmem: none) }
1657; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1658; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn }
1659; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
1660; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
1661; TUNIT: attributes #[[ATTR6:[0-9]+]] = { speculatable memory(none) }
1662; TUNIT: attributes #[[ATTR7]] = { norecurse nosync memory(none) }
1663; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
1664; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(none) }
1665; TUNIT: attributes #[[ATTR10]] = { nofree willreturn }
1666; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(write) }
1667; TUNIT: attributes #[[ATTR12]] = { nofree willreturn memory(readwrite) }
1668; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn }
1669; TUNIT: attributes #[[ATTR14]] = { nosync }
1670; TUNIT: attributes #[[ATTR15]] = { nosync nounwind memory(read) }
1671; TUNIT: attributes #[[ATTR16]] = { nounwind memory(write) }
1672;.
1673; TUNIT: [[RNG0]] = !{i32 0, i32 -2147483648}
1674;.
1675; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
1676; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1677; CGSCC: attributes #[[ATTR2]] = { memory(readwrite, argmem: none) }
1678; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
1679; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree nosync nounwind willreturn }
1680; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
1681; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: write) }
1682; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree nosync nounwind willreturn memory(write) }
1683; CGSCC: attributes #[[ATTR8:[0-9]+]] = { speculatable memory(none) }
1684; CGSCC: attributes #[[ATTR9]] = { norecurse nosync memory(none) }
1685; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
1686; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
1687; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn }
1688; CGSCC: attributes #[[ATTR13]] = { nofree willreturn }
1689; CGSCC: attributes #[[ATTR14]] = { nofree nounwind willreturn }
1690; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) }
1691; CGSCC: attributes #[[ATTR16]] = { nofree willreturn memory(readwrite) }
1692; CGSCC: attributes #[[ATTR17]] = { nosync }
1693; CGSCC: attributes #[[ATTR18]] = { nounwind }
1694;.
1695