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=6 -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=6 -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; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
249; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
250; IS__TUNIT____-SAME: () #[[ATTR0]] {
251; IS__TUNIT____-NEXT:    ret i8* @a1
252;
253; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
254; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test7
255; IS__CGSCC_OPM-SAME: () #[[ATTR1]] {
256; IS__CGSCC_OPM-NEXT:    ret i8* @a1
257;
258; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
259; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test7
260; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
261; IS__CGSCC_NPM-NEXT:    ret i8* @a1
262;
263  %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
264  ret i8* %c
265}
266
267; TEST 7b
268; Function Attrs: nounwind readnone ssp uwtable
269define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
270; IS__CGSCC_OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
271; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b
272; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
273; IS__CGSCC_OPM-NEXT:    br label [[TMP3:%.*]]
274; IS__CGSCC_OPM:       2:
275; IS__CGSCC_OPM-NEXT:    unreachable
276; IS__CGSCC_OPM:       3:
277; IS__CGSCC_OPM-NEXT:    ret i8* undef
278;
279; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
280; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b
281; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] {
282; IS__CGSCC_NPM-NEXT:    br label [[TMP2:%.*]]
283; IS__CGSCC_NPM:       1:
284; IS__CGSCC_NPM-NEXT:    unreachable
285; IS__CGSCC_NPM:       2:
286; IS__CGSCC_NPM-NEXT:    ret i8* undef
287;
288  %2 = icmp eq i8* %0, null
289  br i1 %2, label %3, label %5
290
291; <label>:3:                                      ; preds = %1
292  %4 = tail call i8* @f2b(i8* nonnull @a1)
293  %l = load i8, i8* %4
294  store i8 %l, i8* @a1
295  br label %5
296
297; <label>:5:                                      ; preds = %1, %3
298  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
299  ret i8* %6
300}
301
302; Function Attrs: nounwind readnone ssp uwtable
303define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
304;
305; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable
306; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2b
307; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
308; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
309; IS__CGSCC_OPM-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
310; IS__CGSCC_OPM:       3:
311; IS__CGSCC_OPM-NEXT:    br label [[TMP6:%.*]]
312; IS__CGSCC_OPM:       4:
313; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i8* @f3b(i8* nonnull @a2)
314; IS__CGSCC_OPM-NEXT:    br label [[TMP6]]
315; IS__CGSCC_OPM:       6:
316; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i8* [ undef, [[TMP3]] ], [ [[TMP5]], [[TMP4]] ]
317; IS__CGSCC_OPM-NEXT:    ret i8* [[TMP7]]
318;
319; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
320; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2b
321; IS__CGSCC_NPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] {
322; IS__CGSCC_NPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
323; IS__CGSCC_NPM-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
324; IS__CGSCC_NPM:       3:
325; IS__CGSCC_NPM-NEXT:    br label [[TMP6:%.*]]
326; IS__CGSCC_NPM:       4:
327; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i8* @f3b()
328; IS__CGSCC_NPM-NEXT:    br label [[TMP6]]
329; IS__CGSCC_NPM:       6:
330; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i8* [ undef, [[TMP3]] ], [ [[TMP5]], [[TMP4]] ]
331; IS__CGSCC_NPM-NEXT:    ret i8* [[TMP7]]
332;
333  %2 = icmp eq i8* %0, null
334  br i1 %2, label %5, label %3
335
336; <label>:3:                                      ; preds = %1
337
338  %4 = tail call i8* @f1b(i8* nonnull %0)
339  br label %7
340
341; <label>:5:                                      ; preds = %1
342  %6 = tail call i8* @f3b(i8* nonnull @a2)
343  br label %7
344
345; <label>:7:                                      ; preds = %5, %3
346  %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
347  ret i8* %8
348}
349
350; Function Attrs: nounwind readnone ssp uwtable
351define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
352;
353; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable
354; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3b
355; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
356; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
357; IS__CGSCC_OPM-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
358; IS__CGSCC_OPM:       3:
359; IS__CGSCC_OPM-NEXT:    br label [[TMP4]]
360; IS__CGSCC_OPM:       4:
361; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = phi i8* [ @a2, [[TMP3]] ], [ @a1, [[TMP1:%.*]] ]
362; IS__CGSCC_OPM-NEXT:    ret i8* [[TMP5]]
363;
364; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
365; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3b
366; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] {
367; IS__CGSCC_NPM-NEXT:    br label [[TMP2:%.*]]
368; IS__CGSCC_NPM:       1:
369; IS__CGSCC_NPM-NEXT:    unreachable
370; IS__CGSCC_NPM:       2:
371; IS__CGSCC_NPM-NEXT:    ret i8* @a1
372;
373  %2 = icmp eq i8* %0, null
374  br i1 %2, label %3, label %5
375
376; <label>:3:                                      ; preds = %1
377  %4 = tail call i8* @f1b(i8* nonnull @a2)
378  br label %5
379
380; <label>:5:                                      ; preds = %1, %3
381  %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
382  ret i8* %6
383}
384
385define align 4 i32* @test7b(i32* align 32 %p) #0 {
386; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
387; IS__TUNIT____-LABEL: define {{[^@]+}}@test7b
388; IS__TUNIT____-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0]] {
389; IS__TUNIT____-NEXT:    ret i32* [[P]]
390;
391; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
392; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test7b
393; IS__CGSCC_OPM-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
394; IS__CGSCC_OPM-NEXT:    ret i32* [[P]]
395;
396; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
397; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test7b
398; IS__CGSCC_NPM-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] {
399; IS__CGSCC_NPM-NEXT:    ret i32* [[P]]
400;
401  tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
402  ret i32* %p
403}
404
405; TEST 8
406define void @test8_helper() {
407; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_helper() {
408; IS__TUNIT____-NEXT:    [[PTR0:%.*]] = tail call i32* @unknown()
409; IS__TUNIT____-NEXT:    [[PTR1:%.*]] = tail call align 4 i32* @unknown()
410; IS__TUNIT____-NEXT:    [[PTR2:%.*]] = tail call align 8 i32* @unknown()
411; IS__TUNIT____-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]+]]
412; IS__TUNIT____-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]]
413; IS__TUNIT____-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]]
414; IS__TUNIT____-NEXT:    ret void
415;
416; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_helper() {
417; IS__CGSCC____-NEXT:    [[PTR0:%.*]] = tail call i32* @unknown()
418; IS__CGSCC____-NEXT:    [[PTR1:%.*]] = tail call align 4 i32* @unknown()
419; IS__CGSCC____-NEXT:    [[PTR2:%.*]] = tail call align 8 i32* @unknown()
420; IS__CGSCC____-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]+]]
421; IS__CGSCC____-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]]
422; IS__CGSCC____-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]]
423; IS__CGSCC____-NEXT:    ret void
424;
425  %ptr0 = tail call i32* @unknown()
426  %ptr1 = tail call align 4 i32* @unknown()
427  %ptr2 = tail call align 8 i32* @unknown()
428
429  tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
430  tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
431  tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
432  ret void
433}
434
435declare void @user_i32_ptr(i32* nocapture readnone) nounwind
436define internal void @test8(i32* %a, i32* %b, i32* %c) {
437; IS__TUNIT____: Function Attrs: nounwind
438; IS__TUNIT____-LABEL: define {{[^@]+}}@test8
439; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR2]] {
440; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR2]]
441; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR2]]
442; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR2]]
443; IS__TUNIT____-NEXT:    ret void
444;
445; IS__CGSCC____: Function Attrs: nounwind
446; IS__CGSCC____-LABEL: define {{[^@]+}}@test8
447; IS__CGSCC____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR3]] {
448; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR3]]
449; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR3]]
450; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR3]]
451; IS__CGSCC____-NEXT:    ret void
452;
453  call void @user_i32_ptr(i32* %a)
454  call void @user_i32_ptr(i32* %b)
455  call void @user_i32_ptr(i32* %c)
456  ret void
457}
458
459declare void @test9_helper(i32* %A)
460define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) {
461; CHECK-LABEL: define {{[^@]+}}@test9_traversal
462; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8 [[C:%.*]]) {
463; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]]
464; CHECK-NEXT:    call void @test9_helper(i32* align 4 [[SEL]])
465; CHECK-NEXT:    ret void
466;
467  %sel = select i1 %cnd, i32* %B, i32* %C
468  call void @test9_helper(i32* %sel)
469  ret void
470}
471
472; FIXME: This will work with an upcoming patch (D66618 or similar)
473;             define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p)
474; FIXME: This will work with an upcoming patch (D66618 or similar)
475;             store i32 1, i32* %r, align 32
476; FIXME: This will work with an upcoming patch (D66618 or similar)
477;             store i32 -1, i32* %g1, align 32
478define i32* @test10a(i32* align 32 %p) {
479; IS__TUNIT____: Function Attrs: nofree nosync nounwind
480; IS__TUNIT____-LABEL: define {{[^@]+}}@test10a
481; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3:[0-9]+]] {
482; IS__TUNIT____-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
483; IS__TUNIT____-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
484; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
485; IS__TUNIT____:       t:
486; IS__TUNIT____-NEXT:    [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]]
487; IS__TUNIT____-NEXT:    store i32 1, i32* [[R]], align 32
488; IS__TUNIT____-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
489; IS__TUNIT____-NEXT:    br label [[E:%.*]]
490; IS__TUNIT____:       f:
491; IS__TUNIT____-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
492; IS__TUNIT____-NEXT:    store i32 -1, i32* [[G1]], align 32
493; IS__TUNIT____-NEXT:    br label [[E]]
494; IS__TUNIT____:       e:
495; IS__TUNIT____-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
496; IS__TUNIT____-NEXT:    ret i32* [[PHI]]
497;
498; IS__CGSCC____: Function Attrs: nofree nosync nounwind
499; IS__CGSCC____-LABEL: define {{[^@]+}}@test10a
500; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4:[0-9]+]] {
501; IS__CGSCC____-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
502; IS__CGSCC____-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
503; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
504; IS__CGSCC____:       t:
505; IS__CGSCC____-NEXT:    [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]]
506; IS__CGSCC____-NEXT:    store i32 1, i32* [[R]], align 32
507; IS__CGSCC____-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
508; IS__CGSCC____-NEXT:    br label [[E:%.*]]
509; IS__CGSCC____:       f:
510; IS__CGSCC____-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
511; IS__CGSCC____-NEXT:    store i32 -1, i32* [[G1]], align 32
512; IS__CGSCC____-NEXT:    br label [[E]]
513; IS__CGSCC____:       e:
514; IS__CGSCC____-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
515; IS__CGSCC____-NEXT:    ret i32* [[PHI]]
516;
517  %l = load i32, i32* %p
518  %c = icmp eq i32 %l, 0
519  br i1 %c, label %t, label %f
520t:
521  %r = call i32* @test10a(i32* %p)
522  store i32 1, i32* %r
523  %g0 = getelementptr i32, i32* %p, i32 8
524  br label %e
525f:
526  %g1 = getelementptr i32, i32* %p, i32 8
527  store i32 -1, i32* %g1
528  br label %e
529e:
530  %phi = phi i32* [%g0, %t], [%g1, %f]
531  ret i32* %phi
532}
533
534; FIXME: This will work with an upcoming patch (D66618 or similar)
535;             define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p)
536; FIXME: This will work with an upcoming patch (D66618 or similar)
537;             store i32 1, i32* %r, align 32
538; FIXME: This will work with an upcoming patch (D66618 or similar)
539;             store i32 -1, i32* %g1, align 32
540define i32* @test10b(i32* align 32 %p) {
541; IS__TUNIT____: Function Attrs: nofree nosync nounwind
542; IS__TUNIT____-LABEL: define {{[^@]+}}@test10b
543; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] {
544; IS__TUNIT____-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
545; IS__TUNIT____-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
546; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
547; IS__TUNIT____:       t:
548; IS__TUNIT____-NEXT:    [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]]
549; IS__TUNIT____-NEXT:    store i32 1, i32* [[R]], align 32
550; IS__TUNIT____-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
551; IS__TUNIT____-NEXT:    br label [[E:%.*]]
552; IS__TUNIT____:       f:
553; IS__TUNIT____-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
554; IS__TUNIT____-NEXT:    store i32 -1, i32* [[G1]], align 32
555; IS__TUNIT____-NEXT:    br label [[E]]
556; IS__TUNIT____:       e:
557; IS__TUNIT____-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
558; IS__TUNIT____-NEXT:    ret i32* [[PHI]]
559;
560; IS__CGSCC____: Function Attrs: nofree nosync nounwind
561; IS__CGSCC____-LABEL: define {{[^@]+}}@test10b
562; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
563; IS__CGSCC____-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
564; IS__CGSCC____-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
565; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
566; IS__CGSCC____:       t:
567; IS__CGSCC____-NEXT:    [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]]
568; IS__CGSCC____-NEXT:    store i32 1, i32* [[R]], align 32
569; IS__CGSCC____-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
570; IS__CGSCC____-NEXT:    br label [[E:%.*]]
571; IS__CGSCC____:       f:
572; IS__CGSCC____-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
573; IS__CGSCC____-NEXT:    store i32 -1, i32* [[G1]], align 32
574; IS__CGSCC____-NEXT:    br label [[E]]
575; IS__CGSCC____:       e:
576; IS__CGSCC____-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
577; IS__CGSCC____-NEXT:    ret i32* [[PHI]]
578;
579  %l = load i32, i32* %p
580  %c = icmp eq i32 %l, 0
581  br i1 %c, label %t, label %f
582t:
583  %r = call i32* @test10b(i32* %p)
584  store i32 1, i32* %r
585  %g0 = getelementptr i32, i32* %p, i32 8
586  br label %e
587f:
588  %g1 = getelementptr i32, i32* %p, i32 -8
589  store i32 -1, i32* %g1
590  br label %e
591e:
592  %phi = phi i32* [%g0, %t], [%g1, %f]
593  ret i32* %phi
594}
595
596
597define i64 @test11(i32* %p) {
598; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
599; IS__TUNIT____-LABEL: define {{[^@]+}}@test11
600; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR4:[0-9]+]] {
601; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
602; IS__TUNIT____-NEXT:    [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
603; IS__TUNIT____-NEXT:    ret i64 [[RET]]
604;
605; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
606; IS__CGSCC____-LABEL: define {{[^@]+}}@test11
607; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR5:[0-9]+]] {
608; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
609; IS__CGSCC____-NEXT:    [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
610; IS__CGSCC____-NEXT:    ret i64 [[RET]]
611;
612  %p-cast = bitcast i32* %p to i64*
613  %ret = load i64, i64* %p-cast, align 8
614  ret i64 %ret
615}
616
617; TEST 12
618; Test for deduction using must-be-executed-context and GEP instruction
619
620; FXIME: %p should have nonnull
621define i64 @test12-1(i32* align 4 %p) {
622; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
623; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-1
624; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR4]] {
625; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
626; IS__TUNIT____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
627; IS__TUNIT____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
628; IS__TUNIT____-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
629; IS__TUNIT____-NEXT:    ret i64 [[RET]]
630;
631; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
632; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-1
633; IS__CGSCC____-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR5]] {
634; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
635; IS__CGSCC____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
636; IS__CGSCC____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
637; IS__CGSCC____-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
638; IS__CGSCC____-NEXT:    ret i64 [[RET]]
639;
640  %p-cast = bitcast i32* %p to i64*
641  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
642  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
643  %ret = load i64, i64* %arrayidx1, align 16
644  ret i64 %ret
645}
646
647define i64 @test12-2(i32* align 4 %p) {
648; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
649; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-2
650; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR4]] {
651; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
652; IS__TUNIT____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
653; IS__TUNIT____-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
654; IS__TUNIT____-NEXT:    ret i64 [[RET]]
655;
656; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
657; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-2
658; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] {
659; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
660; IS__CGSCC____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
661; IS__CGSCC____-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
662; IS__CGSCC____-NEXT:    ret i64 [[RET]]
663;
664  %p-cast = bitcast i32* %p to i64*
665  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
666  %ret = load i64, i64* %arrayidx0, align 16
667  ret i64 %ret
668}
669
670; FXIME: %p should have nonnull
671define void @test12-3(i32* align 4 %p) {
672; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
673; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-3
674; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR5:[0-9]+]] {
675; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
676; IS__TUNIT____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
677; IS__TUNIT____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
678; IS__TUNIT____-NEXT:    store i64 0, i64* [[ARRAYIDX1]], align 16
679; IS__TUNIT____-NEXT:    ret void
680;
681; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
682; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-3
683; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] {
684; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
685; IS__CGSCC____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
686; IS__CGSCC____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
687; IS__CGSCC____-NEXT:    store i64 0, i64* [[ARRAYIDX1]], align 16
688; IS__CGSCC____-NEXT:    ret void
689;
690  %p-cast = bitcast i32* %p to i64*
691  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
692  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
693  store i64 0, i64* %arrayidx1, align 16
694  ret void
695}
696
697define void @test12-4(i32* align 4 %p) {
698; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
699; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-4
700; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] {
701; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
702; IS__TUNIT____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
703; IS__TUNIT____-NEXT:    store i64 0, i64* [[ARRAYIDX0]], align 16
704; IS__TUNIT____-NEXT:    ret void
705;
706; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
707; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-4
708; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR6]] {
709; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
710; IS__CGSCC____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
711; IS__CGSCC____-NEXT:    store i64 0, i64* [[ARRAYIDX0]], align 16
712; IS__CGSCC____-NEXT:    ret void
713;
714  %p-cast = bitcast i32* %p to i64*
715  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
716  store i64 0, i64* %arrayidx0, align 16
717  ret void
718}
719
720declare void @use(i64*) willreturn nounwind
721
722define void @test12-5(i32* align 4 %p) {
723; IS__TUNIT____: Function Attrs: nounwind willreturn
724; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-5
725; IS__TUNIT____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] {
726; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
727; IS__TUNIT____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
728; IS__TUNIT____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
729; IS__TUNIT____-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR6]]
730; IS__TUNIT____-NEXT:    ret void
731;
732; IS__CGSCC____: Function Attrs: nounwind willreturn
733; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-5
734; IS__CGSCC____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7:[0-9]+]] {
735; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
736; IS__CGSCC____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
737; IS__CGSCC____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
738; IS__CGSCC____-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR7]]
739; IS__CGSCC____-NEXT:    ret void
740;
741  %p-cast = bitcast i32* %p to i64*
742  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
743  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
744  tail call void @use(i64* align 16 %arrayidx1)
745  ret void
746}
747
748define void @test12-6(i32* align 4 %p) {
749; IS__TUNIT____: Function Attrs: nounwind willreturn
750; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-6
751; IS__TUNIT____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6]] {
752; IS__TUNIT____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
753; IS__TUNIT____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
754; IS__TUNIT____-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR6]]
755; IS__TUNIT____-NEXT:    ret void
756;
757; IS__CGSCC____: Function Attrs: nounwind willreturn
758; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-6
759; IS__CGSCC____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7]] {
760; IS__CGSCC____-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
761; IS__CGSCC____-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
762; IS__CGSCC____-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR7]]
763; IS__CGSCC____-NEXT:    ret void
764;
765  %p-cast = bitcast i32* %p to i64*
766  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
767  tail call void @use(i64* align 16 %arrayidx0)
768  ret void
769}
770
771define void @test13(i1 %c, i32* align 32 %dst) #0 {
772; IS__TUNIT____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable
773; IS__TUNIT____-LABEL: define {{[^@]+}}@test13
774; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR7:[0-9]+]] {
775; IS__TUNIT____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
776; IS__TUNIT____:       truebb:
777; IS__TUNIT____-NEXT:    br label [[END:%.*]]
778; IS__TUNIT____:       falsebb:
779; IS__TUNIT____-NEXT:    br label [[END]]
780; IS__TUNIT____:       end:
781; IS__TUNIT____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
782; IS__TUNIT____-NEXT:    store i32 0, i32* [[PTR]], align 32
783; IS__TUNIT____-NEXT:    ret void
784;
785; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable
786; IS__CGSCC____-LABEL: define {{[^@]+}}@test13
787; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] {
788; IS__CGSCC____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
789; IS__CGSCC____:       truebb:
790; IS__CGSCC____-NEXT:    br label [[END:%.*]]
791; IS__CGSCC____:       falsebb:
792; IS__CGSCC____-NEXT:    br label [[END]]
793; IS__CGSCC____:       end:
794; IS__CGSCC____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
795; IS__CGSCC____-NEXT:    store i32 0, i32* [[PTR]], align 32
796; IS__CGSCC____-NEXT:    ret void
797;
798  br i1 %c, label %truebb, label %falsebb
799truebb:
800  br label %end
801falsebb:
802  br label %end
803end:
804  %ptr = phi i32* [ %dst, %truebb ], [ null, %falsebb ]
805  store i32 0, i32* %ptr
806  ret void
807}
808
809define void @test13-1(i1 %c, i32* align 32 %dst) {
810; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
811; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-1
812; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] {
813; IS__TUNIT____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
814; IS__TUNIT____:       truebb:
815; IS__TUNIT____-NEXT:    br label [[END:%.*]]
816; IS__TUNIT____:       falsebb:
817; IS__TUNIT____-NEXT:    br label [[END]]
818; IS__TUNIT____:       end:
819; IS__TUNIT____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
820; IS__TUNIT____-NEXT:    store i32 0, i32* [[PTR]], align 16
821; IS__TUNIT____-NEXT:    ret void
822;
823; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
824; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-1
825; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9:[0-9]+]] {
826; IS__CGSCC____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
827; IS__CGSCC____:       truebb:
828; IS__CGSCC____-NEXT:    br label [[END:%.*]]
829; IS__CGSCC____:       falsebb:
830; IS__CGSCC____-NEXT:    br label [[END]]
831; IS__CGSCC____:       end:
832; IS__CGSCC____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
833; IS__CGSCC____-NEXT:    store i32 0, i32* [[PTR]], align 16
834; IS__CGSCC____-NEXT:    ret void
835;
836  br i1 %c, label %truebb, label %falsebb
837truebb:
838  br label %end
839falsebb:
840  br label %end
841end:
842  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 48 to i32*), %falsebb ]
843  store i32 0, i32* %ptr
844  ret void
845}
846
847define void @test13-2(i1 %c, i32* align 32 %dst) {
848; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
849; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-2
850; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] {
851; IS__TUNIT____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
852; IS__TUNIT____:       truebb:
853; IS__TUNIT____-NEXT:    br label [[END:%.*]]
854; IS__TUNIT____:       falsebb:
855; IS__TUNIT____-NEXT:    br label [[END]]
856; IS__TUNIT____:       end:
857; IS__TUNIT____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
858; IS__TUNIT____-NEXT:    store i32 0, i32* [[PTR]], align 32
859; IS__TUNIT____-NEXT:    ret void
860;
861; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
862; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-2
863; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] {
864; IS__CGSCC____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
865; IS__CGSCC____:       truebb:
866; IS__CGSCC____-NEXT:    br label [[END:%.*]]
867; IS__CGSCC____:       falsebb:
868; IS__CGSCC____-NEXT:    br label [[END]]
869; IS__CGSCC____:       end:
870; IS__CGSCC____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
871; IS__CGSCC____-NEXT:    store i32 0, i32* [[PTR]], align 32
872; IS__CGSCC____-NEXT:    ret void
873;
874  br i1 %c, label %truebb, label %falsebb
875truebb:
876  br label %end
877falsebb:
878  br label %end
879end:
880  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 160 to i32*), %falsebb ]
881  store i32 0, i32* %ptr
882  ret void
883}
884
885define void @test13-3(i1 %c, i32* align 32 %dst) {
886; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
887; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-3
888; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] {
889; IS__TUNIT____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
890; IS__TUNIT____:       truebb:
891; IS__TUNIT____-NEXT:    br label [[END:%.*]]
892; IS__TUNIT____:       falsebb:
893; IS__TUNIT____-NEXT:    br label [[END]]
894; IS__TUNIT____:       end:
895; IS__TUNIT____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
896; IS__TUNIT____-NEXT:    store i32 0, i32* [[PTR]], align 32
897; IS__TUNIT____-NEXT:    ret void
898;
899; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
900; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-3
901; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] {
902; IS__CGSCC____-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
903; IS__CGSCC____:       truebb:
904; IS__CGSCC____-NEXT:    br label [[END:%.*]]
905; IS__CGSCC____:       falsebb:
906; IS__CGSCC____-NEXT:    br label [[END]]
907; IS__CGSCC____:       end:
908; IS__CGSCC____-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
909; IS__CGSCC____-NEXT:    store i32 0, i32* [[PTR]], align 32
910; IS__CGSCC____-NEXT:    ret void
911;
912  br i1 %c, label %truebb, label %falsebb
913truebb:
914  br label %end
915falsebb:
916  br label %end
917end:
918  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 128 to i32*), %falsebb ]
919  store i32 0, i32* %ptr
920  ret void
921}
922
923; Don't crash on ptr2int/int2ptr uses.
924define i64 @ptr2int(i32* %p) {
925; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
926; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr2int
927; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] {
928; IS__TUNIT____-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
929; IS__TUNIT____-NEXT:    ret i64 [[P2I]]
930;
931; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
932; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr2int
933; IS__CGSCC____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR10:[0-9]+]] {
934; IS__CGSCC____-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
935; IS__CGSCC____-NEXT:    ret i64 [[P2I]]
936;
937  %p2i = ptrtoint i32* %p to i64
938  ret i64 %p2i
939}
940define i64* @int2ptr(i64 %i) {
941; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
942; IS__TUNIT____-LABEL: define {{[^@]+}}@int2ptr
943; IS__TUNIT____-SAME: (i64 [[I:%.*]]) #[[ATTR9]] {
944; IS__TUNIT____-NEXT:    [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
945; IS__TUNIT____-NEXT:    ret i64* [[I2P]]
946;
947; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
948; IS__CGSCC____-LABEL: define {{[^@]+}}@int2ptr
949; IS__CGSCC____-SAME: (i64 [[I:%.*]]) #[[ATTR10]] {
950; IS__CGSCC____-NEXT:    [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
951; IS__CGSCC____-NEXT:    ret i64* [[I2P]]
952;
953  %i2p = inttoptr i64 %i to i64*
954  ret i64* %i2p
955}
956
957; Use the store alignment only for the pointer operand.
958define void @aligned_store(i8* %Value, i8** %Ptr) {
959; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
960; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_store
961; IS__TUNIT____-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR5]] {
962; IS__TUNIT____-NEXT:    store i8* [[VALUE]], i8** [[PTR]], align 32
963; IS__TUNIT____-NEXT:    ret void
964;
965; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
966; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_store
967; IS__CGSCC____-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR6]] {
968; IS__CGSCC____-NEXT:    store i8* [[VALUE]], i8** [[PTR]], align 32
969; IS__CGSCC____-NEXT:    ret void
970;
971  store i8* %Value, i8** %Ptr, align 32
972  ret void
973}
974
975declare i8* @some_func(i8*)
976define void @align_call_op_not_store(i8* align 2048 %arg) {
977; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store
978; CHECK-SAME: (i8* align 2048 [[ARG:%.*]]) {
979; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]])
980; CHECK-NEXT:    store i8 0, i8* [[UNKNOWN]], align 1
981; CHECK-NEXT:    ret void
982;
983  %unknown = call i8* @some_func(i8* %arg)
984  store i8 0, i8* %unknown
985  ret void
986}
987define void @align_store_after_bc(i32* align 2048 %arg) {
988;
989; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
990; IS__TUNIT____-LABEL: define {{[^@]+}}@align_store_after_bc
991; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR5]] {
992; IS__TUNIT____-NEXT:    [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
993; IS__TUNIT____-NEXT:    store i8 0, i8* [[BC]], align 2048
994; IS__TUNIT____-NEXT:    ret void
995;
996; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
997; IS__CGSCC____-LABEL: define {{[^@]+}}@align_store_after_bc
998; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR6]] {
999; IS__CGSCC____-NEXT:    [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
1000; IS__CGSCC____-NEXT:    store i8 0, i8* [[BC]], align 2048
1001; IS__CGSCC____-NEXT:    ret void
1002;
1003  %bc = bitcast i32* %arg to i8*
1004  store i8 0, i8* %bc
1005  ret void
1006}
1007
1008; Make sure we do not annotate the callee of a must-tail call with an alignment
1009; we cannot also put on the caller.
1010@cnd = external global i1
1011define i32 @musttail_callee_1(i32* %p) {
1012; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
1013; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_callee_1
1014; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR4]] {
1015; IS__TUNIT____-NEXT:    [[V:%.*]] = load i32, i32* [[P]], align 32
1016; IS__TUNIT____-NEXT:    ret i32 [[V]]
1017;
1018; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
1019; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_callee_1
1020; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR5]] {
1021; IS__CGSCC____-NEXT:    [[V:%.*]] = load i32, i32* [[P]], align 32
1022; IS__CGSCC____-NEXT:    ret i32 [[V]]
1023;
1024  %v = load i32, i32* %p, align 32
1025  ret i32 %v
1026}
1027define i32 @musttail_caller_1(i32* %p) {
1028; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
1029; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1
1030; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] {
1031; IS__TUNIT____-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
1032; IS__TUNIT____-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
1033; IS__TUNIT____:       mt:
1034; IS__TUNIT____-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) #[[ATTR11:[0-9]+]]
1035; IS__TUNIT____-NEXT:    ret i32 [[V]]
1036; IS__TUNIT____:       exit:
1037; IS__TUNIT____-NEXT:    ret i32 0
1038;
1039; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn
1040; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_caller_1
1041; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR11:[0-9]+]] {
1042; IS__CGSCC____-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
1043; IS__CGSCC____-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
1044; IS__CGSCC____:       mt:
1045; IS__CGSCC____-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]]
1046; IS__CGSCC____-NEXT:    ret i32 [[V]]
1047; IS__CGSCC____:       exit:
1048; IS__CGSCC____-NEXT:    ret i32 0
1049;
1050  %c = load i1, i1* @cnd
1051  br i1 %c, label %mt, label %exit
1052mt:
1053  %v = musttail call i32 @musttail_callee_1(i32* %p)
1054  ret i32 %v
1055exit:
1056  ret i32 0
1057}
1058
1059define i32* @checkAndAdvance(i32* align(16) %p) {
1060; IS__TUNIT____: Function Attrs: nounwind
1061; IS__TUNIT____-LABEL: define {{[^@]+}}@checkAndAdvance
1062; IS__TUNIT____-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] {
1063; IS__TUNIT____-NEXT:  entry:
1064; IS__TUNIT____-NEXT:    [[TMP0:%.*]] = load i32, i32* [[P]], align 16
1065; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
1066; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
1067; IS__TUNIT____:       if.then:
1068; IS__TUNIT____-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4
1069; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR2]]
1070; IS__TUNIT____-NEXT:    br label [[RETURN]]
1071; IS__TUNIT____:       return:
1072; IS__TUNIT____-NEXT:    [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ]
1073; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR2]]
1074; IS__TUNIT____-NEXT:    ret i32* [[RETVAL_0]]
1075;
1076; IS__CGSCC____: Function Attrs: nounwind
1077; IS__CGSCC____-LABEL: define {{[^@]+}}@checkAndAdvance
1078; IS__CGSCC____-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] {
1079; IS__CGSCC____-NEXT:  entry:
1080; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = load i32, i32* [[P]], align 16
1081; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
1082; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
1083; IS__CGSCC____:       if.then:
1084; IS__CGSCC____-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4
1085; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR3]]
1086; IS__CGSCC____-NEXT:    br label [[RETURN]]
1087; IS__CGSCC____:       return:
1088; IS__CGSCC____-NEXT:    [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ]
1089; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR3]]
1090; IS__CGSCC____-NEXT:    ret i32* [[RETVAL_0]]
1091;
1092entry:
1093  %0 = load i32, i32* %p, align 4
1094  %cmp = icmp eq i32 %0, 0
1095  br i1 %cmp, label %if.then, label %return
1096
1097if.then:                                          ; preds = %entry
1098  %add.ptr = getelementptr inbounds i32, i32* %p, i64 4
1099  %call = call i32* @checkAndAdvance(i32* nonnull %add.ptr)
1100  br label %return
1101
1102return:                                           ; preds = %entry, %if.then
1103  %retval.0 = phi i32* [ %call, %if.then ], [ %p, %entry ]
1104  call void @user_i32_ptr(i32* %retval.0)
1105  ret i32* %retval.0
1106}
1107
1108; FIXME: align 4 should not be propagated to the caller's p unless there is noundef
1109define void @align4_caller(i8* %p) {
1110; CHECK-LABEL: define {{[^@]+}}@align4_caller
1111; CHECK-SAME: (i8* align 4 [[P:%.*]]) {
1112; CHECK-NEXT:    call void @align4_callee(i8* align 4 [[P]])
1113; CHECK-NEXT:    ret void
1114;
1115  call void @align4_callee(i8* %p)
1116  ret void
1117}
1118
1119declare void @align4_callee(i8* align(4) %p)
1120
1121@G = global i8 0, align 32
1122
1123define internal i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) norecurse {
1124; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1125; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_8_return
1126; IS__TUNIT____-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] {
1127; IS__TUNIT____-NEXT:    [[STACK:%.*]] = alloca i8*, align 8
1128; IS__TUNIT____-NEXT:    br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]
1129; IS__TUNIT____:       t:
1130; IS__TUNIT____-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8
1131; IS__TUNIT____-NEXT:    [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]]
1132; IS__TUNIT____-NEXT:    store i8* [[SEL]], i8** [[STACK]], align 8
1133; IS__TUNIT____-NEXT:    br label [[END:%.*]]
1134; IS__TUNIT____:       f:
1135; IS__TUNIT____-NEXT:    store i8* @G, i8** [[STACK]], align 8
1136; IS__TUNIT____-NEXT:    br label [[END]]
1137; IS__TUNIT____:       end:
1138; IS__TUNIT____-NEXT:    [[L:%.*]] = load i8*, i8** [[STACK]], align 8
1139; IS__TUNIT____-NEXT:    ret i8* [[L]]
1140;
1141; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1142; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_8_return
1143; IS__CGSCC____-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] {
1144; IS__CGSCC____-NEXT:    [[STACK:%.*]] = alloca i8*, align 8
1145; IS__CGSCC____-NEXT:    br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]
1146; IS__CGSCC____:       t:
1147; IS__CGSCC____-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8
1148; IS__CGSCC____-NEXT:    [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]]
1149; IS__CGSCC____-NEXT:    store i8* [[SEL]], i8** [[STACK]], align 8
1150; IS__CGSCC____-NEXT:    br label [[END:%.*]]
1151; IS__CGSCC____:       f:
1152; IS__CGSCC____-NEXT:    store i8* @G, i8** [[STACK]], align 8
1153; IS__CGSCC____-NEXT:    br label [[END]]
1154; IS__CGSCC____:       end:
1155; IS__CGSCC____-NEXT:    [[L:%.*]] = load i8*, i8** [[STACK]], align 8
1156; IS__CGSCC____-NEXT:    ret i8* [[L]]
1157;
1158  %stack = alloca i8*
1159  br i1 %c1, label %t, label %f
1160t:
1161  %gep = getelementptr i8, i8* @G, i32 8
1162  %sel = select i1 %c2, i8* %a, i8* %gep
1163  store i8* %sel, i8** %stack
1164  br label %end
1165f:
1166  store i8* @G, i8** %stack
1167  br label %end
1168end:
1169  %l = load i8*, i8** %stack
1170  ret i8* %l
1171}
1172
1173define i8* @aligned_8_return_caller(i8* align(16) %a, i1 %c1, i1 %c2) {
1174; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1175; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_8_return_caller
1176; IS__TUNIT____-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] {
1177; IS__TUNIT____-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]+]]
1178; IS__TUNIT____-NEXT:    ret i8* [[R]]
1179;
1180; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
1181; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_8_return_caller
1182; IS__CGSCC____-SAME: (i8* nofree readnone align 16 [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR12:[0-9]+]] {
1183; IS__CGSCC____-NEXT:    [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR14:[0-9]+]]
1184; IS__CGSCC____-NEXT:    ret i8* [[R]]
1185;
1186  %r = call i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2)
1187  ret i8* %r
1188}
1189
1190attributes #0 = { nounwind uwtable noinline }
1191attributes #1 = { uwtable noinline }
1192attributes #2 = { null_pointer_is_valid }
1193;.
1194; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1195; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1196; IS__TUNIT____: attributes #[[ATTR2]] = { nounwind }
1197; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind }
1198; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
1199; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1200; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind willreturn }
1201; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable }
1202; IS__TUNIT____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly }
1203; IS__TUNIT____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn }
1204; IS__TUNIT____: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn }
1205; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn }
1206; IS__TUNIT____: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn }
1207;.
1208; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1209; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1210; IS__CGSCC_OPM: attributes #[[ATTR2]] = { noinline nounwind uwtable }
1211; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nounwind }
1212; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree nosync nounwind }
1213; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
1214; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1215; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn }
1216; IS__CGSCC_OPM: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable }
1217; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly }
1218; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn }
1219; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn }
1220; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn }
1221; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readonly willreturn }
1222; IS__CGSCC_OPM: attributes #[[ATTR14]] = { readnone willreturn }
1223;.
1224; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1225; IS__CGSCC_NPM: attributes #[[ATTR1]] = { noinline nounwind uwtable }
1226; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1227; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nounwind }
1228; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind }
1229; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
1230; IS__CGSCC_NPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1231; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nounwind willreturn }
1232; IS__CGSCC_NPM: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable }
1233; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly }
1234; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn }
1235; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn }
1236; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn }
1237; IS__CGSCC_NPM: attributes #[[ATTR13]] = { readonly willreturn }
1238; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readnone willreturn }
1239;.
1240