1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9; Test cases specifically designed for "align" attribute.
10; We use FIXME's to indicate problems and missing attributes.
11
12
13; TEST 1
14;;
15;.
16; CHECK: @[[A1:[a-zA-Z0-9_$"\\.-]+]] = common global i8 0, align 8
17; CHECK: @[[A2:[a-zA-Z0-9_$"\\.-]+]] = common global i8 0, align 16
18; CHECK: @[[CND:[a-zA-Z0-9_$"\\.-]+]] = external global i1
19; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = global i8 0, align 32
20;.
21define i32* @test1(i32* align 8 %0) #0 {
22; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
23; CHECK-LABEL: define {{[^@]+}}@test1
24; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
25; CHECK-NEXT:    ret i32* [[TMP0]]
26;
27  ret i32* %0
28}
29
30; TEST 2
31define i32* @test2(i32* %0) #0 {
32; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
33; CHECK-LABEL: define {{[^@]+}}@test2
34; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]]) #[[ATTR0]] {
35; CHECK-NEXT:    ret i32* [[TMP0]]
36;
37  ret i32* %0
38}
39
40; TEST 3
41define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 {
42; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
43; CHECK-LABEL: define {{[^@]+}}@test3
44; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) #[[ATTR0]] {
45; CHECK-NEXT:    [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
46; CHECK-NEXT:    ret i32* [[RET]]
47;
48  %ret = select i1 %2, i32* %0, i32* %1
49  ret i32* %ret
50}
51
52; TEST 4
53define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 {
54; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
55; CHECK-LABEL: define {{[^@]+}}@test4
56; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) #[[ATTR0]] {
57; CHECK-NEXT:    [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
58; CHECK-NEXT:    ret i32* [[RET]]
59;
60  %ret = select i1 %2, i32* %0, i32* %1
61  ret i32* %ret
62}
63
64; TEST 5
65declare i32* @unknown()
66declare align 8 i32* @align8()
67
68
69define i32* @test5_1() {
70; CHECK-LABEL: define {{[^@]+}}@test5_1() {
71; CHECK-NEXT:    [[RET:%.*]] = tail call align 8 i32* @unknown()
72; CHECK-NEXT:    ret i32* [[RET]]
73;
74  %ret = tail call align 8 i32* @unknown()
75  ret i32* %ret
76}
77
78define i32* @test5_2() {
79; CHECK-LABEL: define {{[^@]+}}@test5_2() {
80; CHECK-NEXT:    [[RET:%.*]] = tail call align 8 i32* @align8()
81; CHECK-NEXT:    ret i32* [[RET]]
82;
83  %ret = tail call i32* @align8()
84  ret i32* %ret
85}
86
87; TEST 6
88; SCC
89define i32* @test6_1() #0 {
90; NOT_CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
91; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
92; NOT_CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
93; NOT_CGSCC_NPM-NEXT:    ret i32* undef
94;
95; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
96; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
97; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
98; IS__CGSCC_NPM-NEXT:    ret i32* undef
99;
100  %ret = tail call i32* @test6_2()
101  ret i32* %ret
102}
103
104define i32* @test6_2() #0 {
105; NOT_CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
106; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
107; NOT_CGSCC_NPM-SAME: () #[[ATTR1]] {
108; NOT_CGSCC_NPM-NEXT:    ret i32* undef
109;
110; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
111; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
112; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
113; IS__CGSCC_NPM-NEXT:    ret i32* undef
114;
115  %ret = tail call i32* @test6_1()
116  ret i32* %ret
117}
118
119
120; char a1 __attribute__((aligned(8)));
121; char a2 __attribute__((aligned(16)));
122;
123; char* f1(char* a ){
124;     return a?a:f2(&a1);
125; }
126; char* f2(char* a){
127;     return a?f1(a):f3(&a2);
128; }
129;
130; char* f3(char* a){
131;     return a?&a1: f1(&a2);
132; }
133
134@a1 = common global i8 0, align 8
135@a2 = common global i8 0, align 16
136
137; Function Attrs: nounwind readnone ssp uwtable
138define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
139; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
140; IS__CGSCC____-LABEL: define {{[^@]+}}@f1
141; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
142; IS__CGSCC____-NEXT:    br label [[TMP3:%.*]]
143; IS__CGSCC____:       2:
144; IS__CGSCC____-NEXT:    unreachable
145; IS__CGSCC____:       3:
146; IS__CGSCC____-NEXT:    ret i8* [[TMP0]]
147;
148  %2 = icmp eq i8* %0, null
149  br i1 %2, label %3, label %5
150
151; <label>:3:                                      ; preds = %1
152  %4 = tail call i8* @f2(i8* nonnull @a1)
153  %l = load i8, i8* %4
154  br label %5
155
156; <label>:5:                                      ; preds = %1, %3
157  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
158  ret i8* %6
159}
160
161; Function Attrs: nounwind readnone ssp uwtable
162define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
163; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable
164; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2
165; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
166; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
167; IS__CGSCC_OPM-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
168; IS__CGSCC_OPM:       3:
169; IS__CGSCC_OPM-NEXT:    [[TMP4:%.*]] = tail call i8* @f1(i8* noalias noundef nonnull readnone align 4294967296 dereferenceable(4294967295) [[TMP0]])
170; IS__CGSCC_OPM-NEXT:    br label [[TMP7:%.*]]
171; IS__CGSCC_OPM:       5:
172; IS__CGSCC_OPM-NEXT:    [[TMP6:%.*]] = tail call i8* @f3(i8* nonnull @a2)
173; IS__CGSCC_OPM-NEXT:    br label [[TMP7]]
174; IS__CGSCC_OPM:       7:
175; IS__CGSCC_OPM-NEXT:    [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ]
176; IS__CGSCC_OPM-NEXT:    ret i8* [[TMP8]]
177;
178; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
179; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2
180; IS__CGSCC_NPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
181; IS__CGSCC_NPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
182; IS__CGSCC_NPM-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
183; IS__CGSCC_NPM:       3:
184; IS__CGSCC_NPM-NEXT:    [[TMP4:%.*]] = tail call i8* @f1(i8* noalias noundef nonnull readnone align 4294967296 dereferenceable(4294967295) [[TMP0]])
185; IS__CGSCC_NPM-NEXT:    br label [[TMP7:%.*]]
186; IS__CGSCC_NPM:       5:
187; IS__CGSCC_NPM-NEXT:    [[TMP6:%.*]] = tail call i8* @f3()
188; IS__CGSCC_NPM-NEXT:    br label [[TMP7]]
189; IS__CGSCC_NPM:       7:
190; IS__CGSCC_NPM-NEXT:    [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ]
191; IS__CGSCC_NPM-NEXT:    ret i8* [[TMP8]]
192;
193  %2 = icmp eq i8* %0, null
194  br i1 %2, label %5, label %3
195
196; <label>:3:                                      ; preds = %1
197
198  %4 = tail call i8* @f1(i8* nonnull %0)
199  br label %7
200
201; <label>:5:                                      ; preds = %1
202  %6 = tail call i8* @f3(i8* nonnull @a2)
203  br label %7
204
205; <label>:7:                                      ; preds = %5, %3
206  %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
207  ret i8* %8
208}
209
210; Function Attrs: nounwind readnone ssp uwtable
211define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
212; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable
213; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3
214; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
215; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
216; IS__CGSCC_OPM-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
217; IS__CGSCC_OPM:       3:
218; IS__CGSCC_OPM-NEXT:    [[TMP4:%.*]] = tail call i8* @f1(i8* noalias noundef nonnull readnone align 16 dereferenceable(1) @a2)
219; IS__CGSCC_OPM-NEXT:    br label [[TMP5]]
220; IS__CGSCC_OPM:       5:
221; IS__CGSCC_OPM-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ @a1, [[TMP1:%.*]] ]
222; IS__CGSCC_OPM-NEXT:    ret i8* [[TMP6]]
223;
224; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
225; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3
226; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] {
227; IS__CGSCC_NPM-NEXT:    br label [[TMP2:%.*]]
228; IS__CGSCC_NPM:       1:
229; IS__CGSCC_NPM-NEXT:    unreachable
230; IS__CGSCC_NPM:       2:
231; IS__CGSCC_NPM-NEXT:    ret i8* @a1
232;
233  %2 = icmp eq i8* %0, null
234  br i1 %2, label %3, label %5
235
236; <label>:3:                                      ; preds = %1
237  %4 = tail call i8* @f1(i8* nonnull @a2)
238  br label %5
239
240; <label>:5:                                      ; preds = %1, %3
241  %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
242  ret i8* %6
243}
244
245; TEST 7
246; Better than IR information
247define align 4 i8* @test7() #0 {
248; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
249; CHECK-LABEL: define {{[^@]+}}@test7
250; CHECK-SAME: () #[[ATTR0]] {
251; CHECK-NEXT:    ret i8* @a1
252;
253  %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
254  ret i8* %c
255}
256
257; TEST 7b
258; Function Attrs: nounwind readnone ssp uwtable
259define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
260; IS__CGSCC_OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
261; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b
262; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
263; IS__CGSCC_OPM-NEXT:    br label [[TMP3:%.*]]
264; IS__CGSCC_OPM:       2:
265; IS__CGSCC_OPM-NEXT:    unreachable
266; IS__CGSCC_OPM:       3:
267; IS__CGSCC_OPM-NEXT:    ret i8* undef
268;
269; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
270; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b
271; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] {
272; IS__CGSCC_NPM-NEXT:    br label [[TMP2:%.*]]
273; IS__CGSCC_NPM:       1:
274; IS__CGSCC_NPM-NEXT:    unreachable
275; IS__CGSCC_NPM:       2:
276; IS__CGSCC_NPM-NEXT:    ret i8* undef
277;
278  %2 = icmp eq i8* %0, null
279  br i1 %2, label %3, label %5
280
281; <label>:3:                                      ; preds = %1
282  %4 = tail call i8* @f2b(i8* nonnull @a1)
283  %l = load i8, i8* %4
284  store i8 %l, i8* @a1
285  br label %5
286
287; <label>:5:                                      ; preds = %1, %3
288  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
289  ret i8* %6
290}
291
292; Function Attrs: nounwind readnone ssp uwtable
293define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
294;
295; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable
296; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2b
297; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
298; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
299; IS__CGSCC_OPM-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
300; IS__CGSCC_OPM:       3:
301; IS__CGSCC_OPM-NEXT:    br label [[TMP6:%.*]]
302; IS__CGSCC_OPM:       4:
303; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i8* @f3b(i8* nonnull @a2)
304; IS__CGSCC_OPM-NEXT:    br label [[TMP6]]
305; IS__CGSCC_OPM:       6:
306; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i8* [ undef, [[TMP3]] ], [ [[TMP5]], [[TMP4]] ]
307; IS__CGSCC_OPM-NEXT:    ret i8* [[TMP7]]
308;
309; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
310; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2b
311; IS__CGSCC_NPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] {
312; IS__CGSCC_NPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
313; IS__CGSCC_NPM-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
314; IS__CGSCC_NPM:       3:
315; IS__CGSCC_NPM-NEXT:    br label [[TMP6:%.*]]
316; IS__CGSCC_NPM:       4:
317; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i8* @f3b()
318; IS__CGSCC_NPM-NEXT:    br label [[TMP6]]
319; IS__CGSCC_NPM:       6:
320; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i8* [ undef, [[TMP3]] ], [ [[TMP5]], [[TMP4]] ]
321; IS__CGSCC_NPM-NEXT:    ret i8* [[TMP7]]
322;
323  %2 = icmp eq i8* %0, null
324  br i1 %2, label %5, label %3
325
326; <label>:3:                                      ; preds = %1
327
328  %4 = tail call i8* @f1b(i8* nonnull %0)
329  br label %7
330
331; <label>:5:                                      ; preds = %1
332  %6 = tail call i8* @f3b(i8* nonnull @a2)
333  br label %7
334
335; <label>:7:                                      ; preds = %5, %3
336  %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
337  ret i8* %8
338}
339
340; Function Attrs: nounwind readnone ssp uwtable
341define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
342;
343; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable
344; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3b
345; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
346; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
347; IS__CGSCC_OPM-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
348; IS__CGSCC_OPM:       3:
349; IS__CGSCC_OPM-NEXT:    br label [[TMP4]]
350; IS__CGSCC_OPM:       4:
351; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = phi i8* [ @a2, [[TMP3]] ], [ @a1, [[TMP1:%.*]] ]
352; IS__CGSCC_OPM-NEXT:    ret i8* [[TMP5]]
353;
354; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
355; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3b
356; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] {
357; IS__CGSCC_NPM-NEXT:    br label [[TMP2:%.*]]
358; IS__CGSCC_NPM:       1:
359; IS__CGSCC_NPM-NEXT:    unreachable
360; IS__CGSCC_NPM:       2:
361; IS__CGSCC_NPM-NEXT:    ret i8* @a1
362;
363  %2 = icmp eq i8* %0, null
364  br i1 %2, label %3, label %5
365
366; <label>:3:                                      ; preds = %1
367  %4 = tail call i8* @f1b(i8* nonnull @a2)
368  br label %5
369
370; <label>:5:                                      ; preds = %1, %3
371  %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
372  ret i8* %6
373}
374
375define align 4 i32* @test7b(i32* align 32 %p) #0 {
376; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
377; CHECK-LABEL: define {{[^@]+}}@test7b
378; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0]] {
379; CHECK-NEXT:    ret i32* [[P]]
380;
381  tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
382  ret i32* %p
383}
384
385; TEST 8
386define void @test8_helper() {
387; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8_helper() {
388; NOT_CGSCC_OPM-NEXT:    [[PTR0:%.*]] = tail call i32* @unknown()
389; NOT_CGSCC_OPM-NEXT:    [[PTR1:%.*]] = tail call align 4 i32* @unknown()
390; NOT_CGSCC_OPM-NEXT:    [[PTR2:%.*]] = tail call align 8 i32* @unknown()
391; NOT_CGSCC_OPM-NEXT:    tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR2:[0-9]+]]
392; NOT_CGSCC_OPM-NEXT:    tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]]
393; NOT_CGSCC_OPM-NEXT:    tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]]
394; NOT_CGSCC_OPM-NEXT:    ret void
395;
396; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8_helper() {
397; IS__CGSCC_OPM-NEXT:    [[PTR0:%.*]] = tail call i32* @unknown()
398; IS__CGSCC_OPM-NEXT:    [[PTR1:%.*]] = tail call align 4 i32* @unknown()
399; IS__CGSCC_OPM-NEXT:    [[PTR2:%.*]] = tail call align 8 i32* @unknown()
400; IS__CGSCC_OPM-NEXT:    tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR3:[0-9]+]]
401; IS__CGSCC_OPM-NEXT:    tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]]
402; IS__CGSCC_OPM-NEXT:    tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]]
403; IS__CGSCC_OPM-NEXT:    ret void
404;
405  %ptr0 = tail call i32* @unknown()
406  %ptr1 = tail call align 4 i32* @unknown()
407  %ptr2 = tail call align 8 i32* @unknown()
408
409  tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
410  tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
411  tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
412  ret void
413}
414
415declare void @user_i32_ptr(i32* nocapture readnone) nounwind
416define internal void @test8(i32* %a, i32* %b, i32* %c) {
417; NOT_CGSCC_OPM: Function Attrs: nounwind
418; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8
419; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR2]] {
420; NOT_CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR2]]
421; NOT_CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR2]]
422; NOT_CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR2]]
423; NOT_CGSCC_OPM-NEXT:    ret void
424;
425; IS__CGSCC_OPM: Function Attrs: nounwind
426; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8
427; IS__CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR3]] {
428; IS__CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR3]]
429; IS__CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR3]]
430; IS__CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR3]]
431; IS__CGSCC_OPM-NEXT:    ret void
432;
433  call void @user_i32_ptr(i32* %a)
434  call void @user_i32_ptr(i32* %b)
435  call void @user_i32_ptr(i32* %c)
436  ret void
437}
438
439declare void @test9_helper(i32* %A)
440define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) {
441; CHECK-LABEL: define {{[^@]+}}@test9_traversal
442; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8 [[C:%.*]]) {
443; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]]
444; CHECK-NEXT:    call void @test9_helper(i32* align 4 [[SEL]])
445; CHECK-NEXT:    ret void
446;
447  %sel = select i1 %cnd, i32* %B, i32* %C
448  call void @test9_helper(i32* %sel)
449  ret void
450}
451
452; FIXME: This will work with an upcoming patch (D66618 or similar)
453;             define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p)
454; FIXME: This will work with an upcoming patch (D66618 or similar)
455;             store i32 1, i32* %r, align 32
456; FIXME: This will work with an upcoming patch (D66618 or similar)
457;             store i32 -1, i32* %g1, align 32
458define i32* @test10a(i32* align 32 %p) {
459; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind
460; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10a
461; NOT_CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3:[0-9]+]] {
462; NOT_CGSCC_OPM-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
463; NOT_CGSCC_OPM-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
464; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
465; NOT_CGSCC_OPM:       t:
466; NOT_CGSCC_OPM-NEXT:    [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]]
467; NOT_CGSCC_OPM-NEXT:    store i32 1, i32* [[R]], align 32
468; NOT_CGSCC_OPM-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
469; NOT_CGSCC_OPM-NEXT:    br label [[E:%.*]]
470; NOT_CGSCC_OPM:       f:
471; NOT_CGSCC_OPM-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
472; NOT_CGSCC_OPM-NEXT:    store i32 -1, i32* [[G1]], align 32
473; NOT_CGSCC_OPM-NEXT:    br label [[E]]
474; NOT_CGSCC_OPM:       e:
475; NOT_CGSCC_OPM-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
476; NOT_CGSCC_OPM-NEXT:    ret i32* [[PHI]]
477;
478; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind
479; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10a
480; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4:[0-9]+]] {
481; IS__CGSCC_OPM-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
482; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
483; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
484; IS__CGSCC_OPM:       t:
485; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]]
486; IS__CGSCC_OPM-NEXT:    store i32 1, i32* [[R]], align 32
487; IS__CGSCC_OPM-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
488; IS__CGSCC_OPM-NEXT:    br label [[E:%.*]]
489; IS__CGSCC_OPM:       f:
490; IS__CGSCC_OPM-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
491; IS__CGSCC_OPM-NEXT:    store i32 -1, i32* [[G1]], align 32
492; IS__CGSCC_OPM-NEXT:    br label [[E]]
493; IS__CGSCC_OPM:       e:
494; IS__CGSCC_OPM-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
495; IS__CGSCC_OPM-NEXT:    ret i32* [[PHI]]
496;
497  %l = load i32, i32* %p
498  %c = icmp eq i32 %l, 0
499  br i1 %c, label %t, label %f
500t:
501  %r = call i32* @test10a(i32* %p)
502  store i32 1, i32* %r
503  %g0 = getelementptr i32, i32* %p, i32 8
504  br label %e
505f:
506  %g1 = getelementptr i32, i32* %p, i32 8
507  store i32 -1, i32* %g1
508  br label %e
509e:
510  %phi = phi i32* [%g0, %t], [%g1, %f]
511  ret i32* %phi
512}
513
514; FIXME: This will work with an upcoming patch (D66618 or similar)
515;             define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p)
516; FIXME: This will work with an upcoming patch (D66618 or similar)
517;             store i32 1, i32* %r, align 32
518; FIXME: This will work with an upcoming patch (D66618 or similar)
519;             store i32 -1, i32* %g1, align 32
520define i32* @test10b(i32* align 32 %p) {
521; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind
522; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10b
523; NOT_CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] {
524; NOT_CGSCC_OPM-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
525; NOT_CGSCC_OPM-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
526; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
527; NOT_CGSCC_OPM:       t:
528; NOT_CGSCC_OPM-NEXT:    [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]]
529; NOT_CGSCC_OPM-NEXT:    store i32 1, i32* [[R]], align 32
530; NOT_CGSCC_OPM-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
531; NOT_CGSCC_OPM-NEXT:    br label [[E:%.*]]
532; NOT_CGSCC_OPM:       f:
533; NOT_CGSCC_OPM-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
534; NOT_CGSCC_OPM-NEXT:    store i32 -1, i32* [[G1]], align 32
535; NOT_CGSCC_OPM-NEXT:    br label [[E]]
536; NOT_CGSCC_OPM:       e:
537; NOT_CGSCC_OPM-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
538; NOT_CGSCC_OPM-NEXT:    ret i32* [[PHI]]
539;
540; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind
541; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10b
542; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
543; IS__CGSCC_OPM-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
544; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
545; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
546; IS__CGSCC_OPM:       t:
547; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]]
548; IS__CGSCC_OPM-NEXT:    store i32 1, i32* [[R]], align 32
549; IS__CGSCC_OPM-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
550; IS__CGSCC_OPM-NEXT:    br label [[E:%.*]]
551; IS__CGSCC_OPM:       f:
552; IS__CGSCC_OPM-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
553; IS__CGSCC_OPM-NEXT:    store i32 -1, i32* [[G1]], align 32
554; IS__CGSCC_OPM-NEXT:    br label [[E]]
555; IS__CGSCC_OPM:       e:
556; IS__CGSCC_OPM-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
557; IS__CGSCC_OPM-NEXT:    ret i32* [[PHI]]
558;
559  %l = load i32, i32* %p
560  %c = icmp eq i32 %l, 0
561  br i1 %c, label %t, label %f
562t:
563  %r = call i32* @test10b(i32* %p)
564  store i32 1, i32* %r
565  %g0 = getelementptr i32, i32* %p, i32 8
566  br label %e
567f:
568  %g1 = getelementptr i32, i32* %p, i32 -8
569  store i32 -1, i32* %g1
570  br label %e
571e:
572  %phi = phi i32* [%g0, %t], [%g1, %f]
573  ret i32* %phi
574}
575
576
577define i64 @test11(i32* %p) {
578; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
579; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test11
580; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR4:[0-9]+]] {
581; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
582; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
583; NOT_CGSCC_OPM-NEXT:    ret i64 [[RET]]
584;
585; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
586; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test11
587; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR5:[0-9]+]] {
588; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
589; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
590; IS__CGSCC_OPM-NEXT:    ret i64 [[RET]]
591;
592  %p-cast = bitcast i32* %p to i64*
593  %ret = load i64, i64* %p-cast, align 8
594  ret i64 %ret
595}
596
597; TEST 12
598; Test for deduction using must-be-executed-context and GEP instruction
599
600; FXIME: %p should have nonnull
601define i64 @test12-1(i32* align 4 %p) {
602; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
603; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-1
604; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR4]] {
605; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
606; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
607; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
608; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
609; NOT_CGSCC_OPM-NEXT:    ret i64 [[RET]]
610;
611; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
612; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-1
613; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR5]] {
614; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
615; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
616; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
617; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
618; IS__CGSCC_OPM-NEXT:    ret i64 [[RET]]
619;
620  %p-cast = bitcast i32* %p to i64*
621  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
622  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
623  %ret = load i64, i64* %arrayidx1, align 16
624  ret i64 %ret
625}
626
627define i64 @test12-2(i32* align 4 %p) {
628; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
629; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-2
630; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR4]] {
631; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
632; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
633; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
634; NOT_CGSCC_OPM-NEXT:    ret i64 [[RET]]
635;
636; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
637; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-2
638; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] {
639; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
640; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
641; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
642; IS__CGSCC_OPM-NEXT:    ret i64 [[RET]]
643;
644  %p-cast = bitcast i32* %p to i64*
645  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
646  %ret = load i64, i64* %arrayidx0, align 16
647  ret i64 %ret
648}
649
650; FXIME: %p should have nonnull
651define void @test12-3(i32* align 4 %p) {
652; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
653; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-3
654; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR5:[0-9]+]] {
655; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
656; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
657; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
658; NOT_CGSCC_OPM-NEXT:    store i64 0, i64* [[ARRAYIDX1]], align 16
659; NOT_CGSCC_OPM-NEXT:    ret void
660;
661; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
662; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-3
663; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] {
664; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
665; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
666; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
667; IS__CGSCC_OPM-NEXT:    store i64 0, i64* [[ARRAYIDX1]], align 16
668; IS__CGSCC_OPM-NEXT:    ret void
669;
670  %p-cast = bitcast i32* %p to i64*
671  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
672  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
673  store i64 0, i64* %arrayidx1, align 16
674  ret void
675}
676
677define void @test12-4(i32* align 4 %p) {
678; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
679; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-4
680; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] {
681; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
682; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
683; NOT_CGSCC_OPM-NEXT:    store i64 0, i64* [[ARRAYIDX0]], align 16
684; NOT_CGSCC_OPM-NEXT:    ret void
685;
686; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
687; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-4
688; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR6]] {
689; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
690; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
691; IS__CGSCC_OPM-NEXT:    store i64 0, i64* [[ARRAYIDX0]], align 16
692; IS__CGSCC_OPM-NEXT:    ret void
693;
694  %p-cast = bitcast i32* %p to i64*
695  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
696  store i64 0, i64* %arrayidx0, align 16
697  ret void
698}
699
700declare void @use(i64*) willreturn nounwind
701
702define void @test12-5(i32* align 4 %p) {
703; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
704; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-5
705; NOT_CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] {
706; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
707; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
708; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
709; NOT_CGSCC_OPM-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR6]]
710; NOT_CGSCC_OPM-NEXT:    ret void
711;
712; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
713; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-5
714; IS__CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7:[0-9]+]] {
715; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
716; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
717; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
718; IS__CGSCC_OPM-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR7]]
719; IS__CGSCC_OPM-NEXT:    ret void
720;
721  %p-cast = bitcast i32* %p to i64*
722  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
723  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
724  tail call void @use(i64* align 16 %arrayidx1)
725  ret void
726}
727
728define void @test12-6(i32* align 4 %p) {
729; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
730; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-6
731; NOT_CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6]] {
732; NOT_CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
733; NOT_CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
734; NOT_CGSCC_OPM-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR6]]
735; NOT_CGSCC_OPM-NEXT:    ret void
736;
737; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
738; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-6
739; IS__CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7]] {
740; IS__CGSCC_OPM-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
741; IS__CGSCC_OPM-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
742; IS__CGSCC_OPM-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR7]]
743; IS__CGSCC_OPM-NEXT:    ret void
744;
745  %p-cast = bitcast i32* %p to i64*
746  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
747  tail call void @use(i64* align 16 %arrayidx0)
748  ret void
749}
750
751define void @test13(i1 %c, i32* align 32 %dst) #0 {
752; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable
753; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13
754; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR7:[0-9]+]] {
755; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
756; NOT_CGSCC_OPM:       truebb:
757; NOT_CGSCC_OPM-NEXT:    br label [[END:%.*]]
758; NOT_CGSCC_OPM:       falsebb:
759; NOT_CGSCC_OPM-NEXT:    br label [[END]]
760; NOT_CGSCC_OPM:       end:
761; NOT_CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
762; NOT_CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 32
763; NOT_CGSCC_OPM-NEXT:    ret void
764;
765; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable
766; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13
767; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] {
768; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
769; IS__CGSCC_OPM:       truebb:
770; IS__CGSCC_OPM-NEXT:    br label [[END:%.*]]
771; IS__CGSCC_OPM:       falsebb:
772; IS__CGSCC_OPM-NEXT:    br label [[END]]
773; IS__CGSCC_OPM:       end:
774; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
775; IS__CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 32
776; IS__CGSCC_OPM-NEXT:    ret void
777;
778  br i1 %c, label %truebb, label %falsebb
779truebb:
780  br label %end
781falsebb:
782  br label %end
783end:
784  %ptr = phi i32* [ %dst, %truebb ], [ null, %falsebb ]
785  store i32 0, i32* %ptr
786  ret void
787}
788
789define void @test13-1(i1 %c, i32* align 32 %dst) {
790; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
791; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-1
792; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] {
793; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
794; NOT_CGSCC_OPM:       truebb:
795; NOT_CGSCC_OPM-NEXT:    br label [[END:%.*]]
796; NOT_CGSCC_OPM:       falsebb:
797; NOT_CGSCC_OPM-NEXT:    br label [[END]]
798; NOT_CGSCC_OPM:       end:
799; NOT_CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
800; NOT_CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 16
801; NOT_CGSCC_OPM-NEXT:    ret void
802;
803; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
804; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-1
805; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9:[0-9]+]] {
806; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
807; IS__CGSCC_OPM:       truebb:
808; IS__CGSCC_OPM-NEXT:    br label [[END:%.*]]
809; IS__CGSCC_OPM:       falsebb:
810; IS__CGSCC_OPM-NEXT:    br label [[END]]
811; IS__CGSCC_OPM:       end:
812; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
813; IS__CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 16
814; IS__CGSCC_OPM-NEXT:    ret void
815;
816  br i1 %c, label %truebb, label %falsebb
817truebb:
818  br label %end
819falsebb:
820  br label %end
821end:
822  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 48 to i32*), %falsebb ]
823  store i32 0, i32* %ptr
824  ret void
825}
826
827define void @test13-2(i1 %c, i32* align 32 %dst) {
828; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
829; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-2
830; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] {
831; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
832; NOT_CGSCC_OPM:       truebb:
833; NOT_CGSCC_OPM-NEXT:    br label [[END:%.*]]
834; NOT_CGSCC_OPM:       falsebb:
835; NOT_CGSCC_OPM-NEXT:    br label [[END]]
836; NOT_CGSCC_OPM:       end:
837; NOT_CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
838; NOT_CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 32
839; NOT_CGSCC_OPM-NEXT:    ret void
840;
841; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
842; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-2
843; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] {
844; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
845; IS__CGSCC_OPM:       truebb:
846; IS__CGSCC_OPM-NEXT:    br label [[END:%.*]]
847; IS__CGSCC_OPM:       falsebb:
848; IS__CGSCC_OPM-NEXT:    br label [[END]]
849; IS__CGSCC_OPM:       end:
850; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
851; IS__CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 32
852; IS__CGSCC_OPM-NEXT:    ret void
853;
854  br i1 %c, label %truebb, label %falsebb
855truebb:
856  br label %end
857falsebb:
858  br label %end
859end:
860  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 160 to i32*), %falsebb ]
861  store i32 0, i32* %ptr
862  ret void
863}
864
865define void @test13-3(i1 %c, i32* align 32 %dst) {
866; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
867; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-3
868; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] {
869; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
870; NOT_CGSCC_OPM:       truebb:
871; NOT_CGSCC_OPM-NEXT:    br label [[END:%.*]]
872; NOT_CGSCC_OPM:       falsebb:
873; NOT_CGSCC_OPM-NEXT:    br label [[END]]
874; NOT_CGSCC_OPM:       end:
875; NOT_CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
876; NOT_CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 32
877; NOT_CGSCC_OPM-NEXT:    ret void
878;
879; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
880; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-3
881; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] {
882; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
883; IS__CGSCC_OPM:       truebb:
884; IS__CGSCC_OPM-NEXT:    br label [[END:%.*]]
885; IS__CGSCC_OPM:       falsebb:
886; IS__CGSCC_OPM-NEXT:    br label [[END]]
887; IS__CGSCC_OPM:       end:
888; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
889; IS__CGSCC_OPM-NEXT:    store i32 0, i32* [[PTR]], align 32
890; IS__CGSCC_OPM-NEXT:    ret void
891;
892  br i1 %c, label %truebb, label %falsebb
893truebb:
894  br label %end
895falsebb:
896  br label %end
897end:
898  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 128 to i32*), %falsebb ]
899  store i32 0, i32* %ptr
900  ret void
901}
902
903; Don't crash on ptr2int/int2ptr uses.
904define i64 @ptr2int(i32* %p) {
905; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
906; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@ptr2int
907; NOT_CGSCC_OPM-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] {
908; NOT_CGSCC_OPM-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
909; NOT_CGSCC_OPM-NEXT:    ret i64 [[P2I]]
910;
911; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
912; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ptr2int
913; IS__CGSCC_OPM-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR10:[0-9]+]] {
914; IS__CGSCC_OPM-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
915; IS__CGSCC_OPM-NEXT:    ret i64 [[P2I]]
916;
917  %p2i = ptrtoint i32* %p to i64
918  ret i64 %p2i
919}
920define i64* @int2ptr(i64 %i) {
921; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
922; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@int2ptr
923; NOT_CGSCC_OPM-SAME: (i64 [[I:%.*]]) #[[ATTR9]] {
924; NOT_CGSCC_OPM-NEXT:    [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
925; NOT_CGSCC_OPM-NEXT:    ret i64* [[I2P]]
926;
927; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
928; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@int2ptr
929; IS__CGSCC_OPM-SAME: (i64 [[I:%.*]]) #[[ATTR10]] {
930; IS__CGSCC_OPM-NEXT:    [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
931; IS__CGSCC_OPM-NEXT:    ret i64* [[I2P]]
932;
933  %i2p = inttoptr i64 %i to i64*
934  ret i64* %i2p
935}
936
937; Use the store alignment only for the pointer operand.
938define void @aligned_store(i8* %Value, i8** %Ptr) {
939; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
940; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_store
941; NOT_CGSCC_OPM-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR5]] {
942; NOT_CGSCC_OPM-NEXT:    store i8* [[VALUE]], i8** [[PTR]], align 32
943; NOT_CGSCC_OPM-NEXT:    ret void
944;
945; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
946; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_store
947; IS__CGSCC_OPM-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR6]] {
948; IS__CGSCC_OPM-NEXT:    store i8* [[VALUE]], i8** [[PTR]], align 32
949; IS__CGSCC_OPM-NEXT:    ret void
950;
951  store i8* %Value, i8** %Ptr, align 32
952  ret void
953}
954
955declare i8* @some_func(i8*)
956define void @align_call_op_not_store(i8* align 2048 %arg) {
957; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store
958; CHECK-SAME: (i8* align 2048 [[ARG:%.*]]) {
959; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]])
960; CHECK-NEXT:    store i8 0, i8* [[UNKNOWN]], align 1
961; CHECK-NEXT:    ret void
962;
963  %unknown = call i8* @some_func(i8* %arg)
964  store i8 0, i8* %unknown
965  ret void
966}
967define void @align_store_after_bc(i32* align 2048 %arg) {
968;
969; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
970; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@align_store_after_bc
971; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR5]] {
972; NOT_CGSCC_OPM-NEXT:    [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
973; NOT_CGSCC_OPM-NEXT:    store i8 0, i8* [[BC]], align 2048
974; NOT_CGSCC_OPM-NEXT:    ret void
975;
976; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
977; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@align_store_after_bc
978; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR6]] {
979; IS__CGSCC_OPM-NEXT:    [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
980; IS__CGSCC_OPM-NEXT:    store i8 0, i8* [[BC]], align 2048
981; IS__CGSCC_OPM-NEXT:    ret void
982;
983  %bc = bitcast i32* %arg to i8*
984  store i8 0, i8* %bc
985  ret void
986}
987
988; Make sure we do not annotate the callee of a must-tail call with an alignment
989; we cannot also put on the caller.
990@cnd = external global i1
991define i32 @musttail_callee_1(i32* %p) {
992; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
993; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_callee_1
994; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR4]] {
995; NOT_CGSCC_OPM-NEXT:    [[V:%.*]] = load i32, i32* [[P]], align 32
996; NOT_CGSCC_OPM-NEXT:    ret i32 [[V]]
997;
998; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
999; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_callee_1
1000; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR5]] {
1001; IS__CGSCC_OPM-NEXT:    [[V:%.*]] = load i32, i32* [[P]], align 32
1002; IS__CGSCC_OPM-NEXT:    ret i32 [[V]]
1003;
1004  %v = load i32, i32* %p, align 32
1005  ret i32 %v
1006}
1007define i32 @musttail_caller_1(i32* %p) {
1008; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
1009; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1
1010; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] {
1011; IS__TUNIT____-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
1012; IS__TUNIT____-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
1013; IS__TUNIT____:       mt:
1014; IS__TUNIT____-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) #[[ATTR11:[0-9]+]]
1015; IS__TUNIT____-NEXT:    ret i32 [[V]]
1016; IS__TUNIT____:       exit:
1017; IS__TUNIT____-NEXT:    ret i32 0
1018;
1019; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
1020; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_caller_1
1021; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR11:[0-9]+]] {
1022; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
1023; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
1024; IS__CGSCC_OPM:       mt:
1025; IS__CGSCC_OPM-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR12:[0-9]+]]
1026; IS__CGSCC_OPM-NEXT:    ret i32 [[V]]
1027; IS__CGSCC_OPM:       exit:
1028; IS__CGSCC_OPM-NEXT:    ret i32 0
1029;
1030; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
1031; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@musttail_caller_1
1032; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] {
1033; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
1034; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
1035; IS__CGSCC_NPM:       mt:
1036; IS__CGSCC_NPM-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR11:[0-9]+]]
1037; IS__CGSCC_NPM-NEXT:    ret i32 [[V]]
1038; IS__CGSCC_NPM:       exit:
1039; IS__CGSCC_NPM-NEXT:    ret i32 0
1040;
1041  %c = load i1, i1* @cnd
1042  br i1 %c, label %mt, label %exit
1043mt:
1044  %v = musttail call i32 @musttail_callee_1(i32* %p)
1045  ret i32 %v
1046exit:
1047  ret i32 0
1048}
1049
1050define i32* @checkAndAdvance(i32* align(16) %p) {
1051; NOT_CGSCC_OPM: Function Attrs: nounwind
1052; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance
1053; NOT_CGSCC_OPM-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] {
1054; NOT_CGSCC_OPM-NEXT:  entry:
1055; NOT_CGSCC_OPM-NEXT:    [[TMP0:%.*]] = load i32, i32* [[P]], align 16
1056; NOT_CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
1057; NOT_CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
1058; NOT_CGSCC_OPM:       if.then:
1059; NOT_CGSCC_OPM-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4
1060; NOT_CGSCC_OPM-NEXT:    [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR2]]
1061; NOT_CGSCC_OPM-NEXT:    br label [[RETURN]]
1062; NOT_CGSCC_OPM:       return:
1063; NOT_CGSCC_OPM-NEXT:    [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ]
1064; NOT_CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR2]]
1065; NOT_CGSCC_OPM-NEXT:    ret i32* [[RETVAL_0]]
1066;
1067; IS__CGSCC_OPM: Function Attrs: nounwind
1068; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance
1069; IS__CGSCC_OPM-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] {
1070; IS__CGSCC_OPM-NEXT:  entry:
1071; IS__CGSCC_OPM-NEXT:    [[TMP0:%.*]] = load i32, i32* [[P]], align 16
1072; IS__CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
1073; IS__CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
1074; IS__CGSCC_OPM:       if.then:
1075; IS__CGSCC_OPM-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4
1076; IS__CGSCC_OPM-NEXT:    [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR3]]
1077; IS__CGSCC_OPM-NEXT:    br label [[RETURN]]
1078; IS__CGSCC_OPM:       return:
1079; IS__CGSCC_OPM-NEXT:    [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ]
1080; IS__CGSCC_OPM-NEXT:    call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR3]]
1081; IS__CGSCC_OPM-NEXT:    ret i32* [[RETVAL_0]]
1082;
1083entry:
1084  %0 = load i32, i32* %p, align 4
1085  %cmp = icmp eq i32 %0, 0
1086  br i1 %cmp, label %if.then, label %return
1087
1088if.then:                                          ; preds = %entry
1089  %add.ptr = getelementptr inbounds i32, i32* %p, i64 4
1090  %call = call i32* @checkAndAdvance(i32* nonnull %add.ptr)
1091  br label %return
1092
1093return:                                           ; preds = %entry, %if.then
1094  %retval.0 = phi i32* [ %call, %if.then ], [ %p, %entry ]
1095  call void @user_i32_ptr(i32* %retval.0)
1096  ret i32* %retval.0
1097}
1098
1099; FIXME: align 4 should not be propagated to the caller's p unless there is noundef
1100define void @align4_caller(i8* %p) {
1101; CHECK-LABEL: define {{[^@]+}}@align4_caller
1102; CHECK-SAME: (i8* align 4 [[P:%.*]]) {
1103; CHECK-NEXT:    call void @align4_callee(i8* align 4 [[P]])
1104; CHECK-NEXT:    ret void
1105;
1106  call void @align4_callee(i8* %p)
1107  ret void
1108}
1109
1110declare void @align4_callee(i8* align(4) %p)
1111
1112@G = global i8 0, align 32
1113
1114define internal i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) norecurse {
1115; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1116; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return
1117; NOT_CGSCC_OPM-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] {
1118; NOT_CGSCC_OPM-NEXT:    [[STACK:%.*]] = alloca i8*, align 8
1119; NOT_CGSCC_OPM-NEXT:    br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]
1120; NOT_CGSCC_OPM:       t:
1121; NOT_CGSCC_OPM-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8
1122; NOT_CGSCC_OPM-NEXT:    [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]]
1123; NOT_CGSCC_OPM-NEXT:    store i8* [[SEL]], i8** [[STACK]], align 8
1124; NOT_CGSCC_OPM-NEXT:    br label [[END:%.*]]
1125; NOT_CGSCC_OPM:       f:
1126; NOT_CGSCC_OPM-NEXT:    store i8* @G, i8** [[STACK]], align 8
1127; NOT_CGSCC_OPM-NEXT:    br label [[END]]
1128; NOT_CGSCC_OPM:       end:
1129; NOT_CGSCC_OPM-NEXT:    [[L:%.*]] = load i8*, i8** [[STACK]], align 8
1130; NOT_CGSCC_OPM-NEXT:    ret i8* [[L]]
1131;
1132; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1133; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return
1134; IS__CGSCC_OPM-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] {
1135; IS__CGSCC_OPM-NEXT:    [[STACK:%.*]] = alloca i8*, align 8
1136; IS__CGSCC_OPM-NEXT:    br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]
1137; IS__CGSCC_OPM:       t:
1138; IS__CGSCC_OPM-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8
1139; IS__CGSCC_OPM-NEXT:    [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]]
1140; IS__CGSCC_OPM-NEXT:    store i8* [[SEL]], i8** [[STACK]], align 8
1141; IS__CGSCC_OPM-NEXT:    br label [[END:%.*]]
1142; IS__CGSCC_OPM:       f:
1143; IS__CGSCC_OPM-NEXT:    store i8* @G, i8** [[STACK]], align 8
1144; IS__CGSCC_OPM-NEXT:    br label [[END]]
1145; IS__CGSCC_OPM:       end:
1146; IS__CGSCC_OPM-NEXT:    [[L:%.*]] = load i8*, i8** [[STACK]], align 8
1147; IS__CGSCC_OPM-NEXT:    ret i8* [[L]]
1148;
1149  %stack = alloca i8*
1150  br i1 %c1, label %t, label %f
1151t:
1152  %gep = getelementptr i8, i8* @G, i32 8
1153  %sel = select i1 %c2, i8* %a, i8* %gep
1154  store i8* %sel, i8** %stack
1155  br label %end
1156f:
1157  store i8* @G, i8** %stack
1158  br label %end
1159end:
1160  %l = load i8*, i8** %stack
1161  ret i8* %l
1162}
1163
1164define i8* @aligned_8_return_caller(i8* align(16) %a, i1 %c1, i1 %c2) {
1165; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1166; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return_caller
1167; NOT_CGSCC_OPM-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] {
1168; NOT_CGSCC_OPM-NEXT:    [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR12:[0-9]+]]
1169; NOT_CGSCC_OPM-NEXT:    ret i8* [[R]]
1170;
1171; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1172; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return_caller
1173; IS__CGSCC_OPM-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] {
1174; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR13:[0-9]+]]
1175; IS__CGSCC_OPM-NEXT:    ret i8* [[R]]
1176;
1177  %r = call i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2)
1178  ret i8* %r
1179}
1180
1181attributes #0 = { nounwind uwtable noinline }
1182attributes #1 = { uwtable noinline }
1183attributes #2 = { null_pointer_is_valid }
1184;.
1185; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1186; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1187; IS__TUNIT____: attributes #[[ATTR2]] = { nounwind }
1188; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind }
1189; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
1190; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1191; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind willreturn }
1192; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable }
1193; IS__TUNIT____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly }
1194; IS__TUNIT____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn }
1195; IS__TUNIT____: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn }
1196; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn }
1197; IS__TUNIT____: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn }
1198;.
1199; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1200; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1201; IS__CGSCC_OPM: attributes #[[ATTR2]] = { noinline nounwind uwtable }
1202; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nounwind }
1203; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree nosync nounwind }
1204; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
1205; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1206; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn }
1207; IS__CGSCC_OPM: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable }
1208; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly }
1209; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn }
1210; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readonly willreturn }
1211; IS__CGSCC_OPM: attributes #[[ATTR12]] = { readonly willreturn }
1212; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone willreturn }
1213;.
1214; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1215; IS__CGSCC_NPM: attributes #[[ATTR1]] = { noinline nounwind uwtable }
1216; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nounwind }
1217; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind }
1218; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
1219; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1220; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn }
1221; IS__CGSCC_NPM: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable }
1222; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly }
1223; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn }
1224; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn }
1225; IS__CGSCC_NPM: attributes #[[ATTR11]] = { readonly willreturn }
1226; IS__CGSCC_NPM: attributes #[[ATTR12]] = { readnone willreturn }
1227;.
1228