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