1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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; CHECK-LABEL: define {{[^@]+}}@test1
16; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]])
17; CHECK-NEXT:    ret i32* [[TMP0]]
18;
19  ret i32* %0
20}
21
22; TEST 2
23define i32* @test2(i32* %0) #0 {
24; CHECK-LABEL: define {{[^@]+}}@test2
25; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]])
26; CHECK-NEXT:    ret i32* [[TMP0]]
27;
28  ret i32* %0
29}
30
31; TEST 3
32define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 {
33; CHECK-LABEL: define {{[^@]+}}@test3
34; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
35; CHECK-NEXT:    [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
36; CHECK-NEXT:    ret i32* [[RET]]
37;
38  %ret = select i1 %2, i32* %0, i32* %1
39  ret i32* %ret
40}
41
42; TEST 4
43define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 {
44; CHECK-LABEL: define {{[^@]+}}@test4
45; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
46; CHECK-NEXT:    [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
47; CHECK-NEXT:    ret i32* [[RET]]
48;
49  %ret = select i1 %2, i32* %0, i32* %1
50  ret i32* %ret
51}
52
53; TEST 5
54declare i32* @unknown()
55declare align 8 i32* @align8()
56
57
58define i32* @test5_1() {
59; CHECK-LABEL: define {{[^@]+}}@test5_1()
60; CHECK-NEXT:    [[RET:%.*]] = tail call align 8 i32* @unknown()
61; CHECK-NEXT:    ret i32* [[RET]]
62;
63  %ret = tail call align 8 i32* @unknown()
64  ret i32* %ret
65}
66
67define i32* @test5_2() {
68; CHECK-LABEL: define {{[^@]+}}@test5_2()
69; CHECK-NEXT:    [[RET:%.*]] = tail call align 8 i32* @align8()
70; CHECK-NEXT:    ret i32* [[RET]]
71;
72  %ret = tail call i32* @align8()
73  ret i32* %ret
74}
75
76; TEST 6
77; SCC
78define i32* @test6_1() #0 {
79; CHECK-LABEL: define {{[^@]+}}@test6_1()
80; CHECK-NEXT:    unreachable
81;
82  %ret = tail call i32* @test6_2()
83  ret i32* %ret
84}
85
86define i32* @test6_2() #0 {
87; CHECK-LABEL: define {{[^@]+}}@test6_2()
88; CHECK-NEXT:    unreachable
89;
90  %ret = tail call i32* @test6_1()
91  ret i32* %ret
92}
93
94
95; char a1 __attribute__((aligned(8)));
96; char a2 __attribute__((aligned(16)));
97;
98; char* f1(char* a ){
99;     return a?a:f2(&a1);
100; }
101; char* f2(char* a){
102;     return a?f1(a):f3(&a2);
103; }
104;
105; char* f3(char* a){
106;     return a?&a1: f1(&a2);
107; }
108
109@a1 = common global i8 0, align 8
110@a2 = common global i8 0, align 16
111
112; Function Attrs: nounwind readnone ssp uwtable
113define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
114; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
115; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
116; IS__TUNIT____-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
117; IS__TUNIT____-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
118; IS__TUNIT____:       3:
119; IS__TUNIT____-NEXT:    [[TMP4:%.*]] = tail call align 8 i8* @f2()
120; IS__TUNIT____-NEXT:    br label [[TMP5]]
121; IS__TUNIT____:       5:
122; IS__TUNIT____-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
123; IS__TUNIT____-NEXT:    ret i8* [[TMP6]]
124;
125; IS__CGSCC____-LABEL: define {{[^@]+}}@f1
126; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
127; IS__CGSCC____-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
128; IS__CGSCC____-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
129; IS__CGSCC____:       3:
130; IS__CGSCC____-NEXT:    [[TMP4:%.*]] = tail call align 8 i8* @f2()
131; IS__CGSCC____-NEXT:    br label [[TMP5]]
132; IS__CGSCC____:       5:
133; IS__CGSCC____-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
134; IS__CGSCC____-NEXT:    ret i8* [[TMP6]]
135;
136  %2 = icmp eq i8* %0, null
137  br i1 %2, label %3, label %5
138
139; <label>:3:                                      ; preds = %1
140  %4 = tail call i8* @f2(i8* nonnull @a1)
141  %l = load i8, i8* %4
142  br label %5
143
144; <label>:5:                                      ; preds = %1, %3
145  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
146  ret i8* %6
147}
148
149; Function Attrs: nounwind readnone ssp uwtable
150define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
151; CHECK-LABEL: define {{[^@]+}}@f2() local_unnamed_addr
152; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* @a1, null
153; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]
154; CHECK:       2:
155; CHECK-NEXT:    [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
156; CHECK-NEXT:    br label [[TMP6:%.*]]
157; CHECK:       4:
158; CHECK-NEXT:    [[TMP5:%.*]] = tail call i8* @f3()
159; CHECK-NEXT:    br label [[TMP6]]
160; CHECK:       6:
161; CHECK-NEXT:    [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]
162; CHECK-NEXT:    ret i8* [[TMP7]]
163;
164  %2 = icmp eq i8* %0, null
165  br i1 %2, label %5, label %3
166
167; <label>:3:                                      ; preds = %1
168
169  %4 = tail call i8* @f1(i8* nonnull %0)
170  br label %7
171
172; <label>:5:                                      ; preds = %1
173  %6 = tail call i8* @f3(i8* nonnull @a2)
174  br label %7
175
176; <label>:7:                                      ; preds = %5, %3
177  %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
178  ret i8* %8
179}
180
181; Function Attrs: nounwind readnone ssp uwtable
182define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
183; CHECK-LABEL: define {{[^@]+}}@f3() local_unnamed_addr
184; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* @a2, null
185; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
186; CHECK:       2:
187; CHECK-NEXT:    [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2)
188; CHECK-NEXT:    br label [[TMP4]]
189; CHECK:       4:
190; CHECK-NEXT:    [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ]
191; CHECK-NEXT:    ret i8* [[TMP5]]
192;
193  %2 = icmp eq i8* %0, null
194  br i1 %2, label %3, label %5
195
196; <label>:3:                                      ; preds = %1
197  %4 = tail call i8* @f1(i8* nonnull @a2)
198  br label %5
199
200; <label>:5:                                      ; preds = %1, %3
201  %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
202  ret i8* %6
203}
204
205; TEST 7
206; Better than IR information
207define align 4 i8* @test7() #0 {
208; IS__TUNIT____-LABEL: define {{[^@]+}}@test7()
209; IS__TUNIT____-NEXT:    [[C:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
210; IS__TUNIT____-NEXT:    ret i8* [[C]]
211;
212; IS__CGSCC____-LABEL: define {{[^@]+}}@test7()
213; IS__CGSCC____-NEXT:    [[C:%.*]] = tail call nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
214; IS__CGSCC____-NEXT:    ret i8* [[C]]
215;
216  %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
217  ret i8* %c
218}
219
220; TEST 7b
221; Function Attrs: nounwind readnone ssp uwtable
222define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
223; IS__TUNIT____-LABEL: define {{[^@]+}}@f1b
224; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
225; IS__TUNIT____-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
226; IS__TUNIT____-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
227; IS__TUNIT____:       3:
228; IS__TUNIT____-NEXT:    [[TMP4:%.*]] = tail call align 8 i8* @f2b()
229; IS__TUNIT____-NEXT:    [[L:%.*]] = load i8, i8* [[TMP4]], align 8
230; IS__TUNIT____-NEXT:    store i8 [[L]], i8* @a1, align 8
231; IS__TUNIT____-NEXT:    br label [[TMP5]]
232; IS__TUNIT____:       5:
233; IS__TUNIT____-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
234; IS__TUNIT____-NEXT:    ret i8* [[TMP6]]
235;
236; IS__CGSCC____-LABEL: define {{[^@]+}}@f1b
237; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
238; IS__CGSCC____-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
239; IS__CGSCC____-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
240; IS__CGSCC____:       3:
241; IS__CGSCC____-NEXT:    [[TMP4:%.*]] = tail call align 8 i8* @f2b()
242; IS__CGSCC____-NEXT:    [[L:%.*]] = load i8, i8* [[TMP4]], align 8
243; IS__CGSCC____-NEXT:    store i8 [[L]], i8* @a1, align 8
244; IS__CGSCC____-NEXT:    br label [[TMP5]]
245; IS__CGSCC____:       5:
246; IS__CGSCC____-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
247; IS__CGSCC____-NEXT:    ret i8* [[TMP6]]
248;
249  %2 = icmp eq i8* %0, null
250  br i1 %2, label %3, label %5
251
252; <label>:3:                                      ; preds = %1
253  %4 = tail call i8* @f2b(i8* nonnull @a1)
254  %l = load i8, i8* %4
255  store i8 %l, i8* @a1
256  br label %5
257
258; <label>:5:                                      ; preds = %1, %3
259  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
260  ret i8* %6
261}
262
263; Function Attrs: nounwind readnone ssp uwtable
264define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
265;
266; CHECK-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr
267; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* @a1, null
268; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]
269; CHECK:       2:
270; CHECK-NEXT:    [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
271; CHECK-NEXT:    br label [[TMP6:%.*]]
272; CHECK:       4:
273; CHECK-NEXT:    [[TMP5:%.*]] = tail call i8* @f3b()
274; CHECK-NEXT:    br label [[TMP6]]
275; CHECK:       6:
276; CHECK-NEXT:    [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]
277; CHECK-NEXT:    ret i8* [[TMP7]]
278;
279  %2 = icmp eq i8* %0, null
280  br i1 %2, label %5, label %3
281
282; <label>:3:                                      ; preds = %1
283
284  %4 = tail call i8* @f1b(i8* nonnull %0)
285  br label %7
286
287; <label>:5:                                      ; preds = %1
288  %6 = tail call i8* @f3b(i8* nonnull @a2)
289  br label %7
290
291; <label>:7:                                      ; preds = %5, %3
292  %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
293  ret i8* %8
294}
295
296; Function Attrs: nounwind readnone ssp uwtable
297define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
298;
299; CHECK-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr
300; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* @a2, null
301; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
302; CHECK:       2:
303; CHECK-NEXT:    [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2)
304; CHECK-NEXT:    br label [[TMP4]]
305; CHECK:       4:
306; CHECK-NEXT:    [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ]
307; CHECK-NEXT:    ret i8* [[TMP5]]
308;
309  %2 = icmp eq i8* %0, null
310  br i1 %2, label %3, label %5
311
312; <label>:3:                                      ; preds = %1
313  %4 = tail call i8* @f1b(i8* nonnull @a2)
314  br label %5
315
316; <label>:5:                                      ; preds = %1, %3
317  %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
318  ret i8* %6
319}
320
321define align 4 i32* @test7b(i32* align 32 %p) #0 {
322; CHECK-LABEL: define {{[^@]+}}@test7b
323; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
324; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
325; CHECK-NEXT:    ret i32* [[P]]
326;
327  tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
328  ret i32* %p
329}
330
331; TEST 8
332define void @test8_helper() {
333; CHECK-LABEL: define {{[^@]+}}@test8_helper()
334; CHECK-NEXT:    [[PTR0:%.*]] = tail call i32* @unknown()
335; CHECK-NEXT:    [[PTR1:%.*]] = tail call align 4 i32* @unknown()
336; CHECK-NEXT:    [[PTR2:%.*]] = tail call align 8 i32* @unknown()
337; CHECK-NEXT:    tail call void @test8(i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone [[PTR0]])
338; CHECK-NEXT:    tail call void @test8(i32* noalias readnone align 8 [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]])
339; CHECK-NEXT:    tail call void @test8(i32* noalias readnone align 8 [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]])
340; CHECK-NEXT:    ret void
341;
342  %ptr0 = tail call i32* @unknown()
343  %ptr1 = tail call align 4 i32* @unknown()
344  %ptr2 = tail call align 8 i32* @unknown()
345
346  tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
347  tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
348  tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
349  ret void
350}
351
352declare void @user_i32_ptr(i32* nocapture readnone) nounwind
353define internal void @test8(i32* %a, i32* %b, i32* %c) {
354; IS__TUNIT____-LABEL: define {{[^@]+}}@test8
355; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]])
356; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]])
357; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]])
358; IS__TUNIT____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone [[C]])
359; IS__TUNIT____-NEXT:    ret void
360;
361; IS__CGSCC____-LABEL: define {{[^@]+}}@test8
362; IS__CGSCC____-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]])
363; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]])
364; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]])
365; IS__CGSCC____-NEXT:    call void @user_i32_ptr(i32* noalias nocapture readnone [[C]])
366; IS__CGSCC____-NEXT:    ret void
367;
368  call void @user_i32_ptr(i32* %a)
369  call void @user_i32_ptr(i32* %b)
370  call void @user_i32_ptr(i32* %c)
371  ret void
372}
373
374declare void @test9_helper(i32* %A)
375define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) {
376; CHECK-LABEL: define {{[^@]+}}@test9_traversal
377; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8 [[C:%.*]])
378; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]]
379; CHECK-NEXT:    call void @test9_helper(i32* align 4 [[SEL]])
380; CHECK-NEXT:    ret void
381;
382  %sel = select i1 %cnd, i32* %B, i32* %C
383  call void @test9_helper(i32* %sel)
384  ret void
385}
386
387; FIXME: This will work with an upcoming patch (D66618 or similar)
388;             define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p)
389; FIXME: This will work with an upcoming patch (D66618 or similar)
390;             store i32 1, i32* %r, align 32
391; FIXME: This will work with an upcoming patch (D66618 or similar)
392;             store i32 -1, i32* %g1, align 32
393define i32* @test10a(i32* align 32 %p) {
394; CHECK-LABEL: define {{[^@]+}}@test10a
395; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
396; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
397; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
398; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
399; CHECK:       t:
400; CHECK-NEXT:    [[R:%.*]] = call i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]])
401; CHECK-NEXT:    store i32 1, i32* [[R]]
402; CHECK-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
403; CHECK-NEXT:    br label [[E:%.*]]
404; CHECK:       f:
405; CHECK-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
406; CHECK-NEXT:    store i32 -1, i32* [[G1]], align 4
407; CHECK-NEXT:    br label [[E]]
408; CHECK:       e:
409; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
410; CHECK-NEXT:    ret i32* [[PHI]]
411;
412  %l = load i32, i32* %p
413  %c = icmp eq i32 %l, 0
414  br i1 %c, label %t, label %f
415t:
416  %r = call i32* @test10a(i32* %p)
417  store i32 1, i32* %r
418  %g0 = getelementptr i32, i32* %p, i32 8
419  br label %e
420f:
421  %g1 = getelementptr i32, i32* %p, i32 8
422  store i32 -1, i32* %g1
423  br label %e
424e:
425  %phi = phi i32* [%g0, %t], [%g1, %f]
426  ret i32* %phi
427}
428
429; FIXME: This will work with an upcoming patch (D66618 or similar)
430;             define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p)
431; FIXME: This will work with an upcoming patch (D66618 or similar)
432;             store i32 1, i32* %r, align 32
433; FIXME: This will work with an upcoming patch (D66618 or similar)
434;             store i32 -1, i32* %g1, align 32
435define i32* @test10b(i32* align 32 %p) {
436; CHECK-LABEL: define {{[^@]+}}@test10b
437; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
438; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[P]], align 32
439; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 0
440; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
441; CHECK:       t:
442; CHECK-NEXT:    [[R:%.*]] = call i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]])
443; CHECK-NEXT:    store i32 1, i32* [[R]]
444; CHECK-NEXT:    [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
445; CHECK-NEXT:    br label [[E:%.*]]
446; CHECK:       f:
447; CHECK-NEXT:    [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
448; CHECK-NEXT:    store i32 -1, i32* [[G1]], align 4
449; CHECK-NEXT:    br label [[E]]
450; CHECK:       e:
451; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
452; CHECK-NEXT:    ret i32* [[PHI]]
453;
454  %l = load i32, i32* %p
455  %c = icmp eq i32 %l, 0
456  br i1 %c, label %t, label %f
457t:
458  %r = call i32* @test10b(i32* %p)
459  store i32 1, i32* %r
460  %g0 = getelementptr i32, i32* %p, i32 8
461  br label %e
462f:
463  %g1 = getelementptr i32, i32* %p, i32 -8
464  store i32 -1, i32* %g1
465  br label %e
466e:
467  %phi = phi i32* [%g0, %t], [%g1, %f]
468  ret i32* %phi
469}
470
471
472define i64 @test11(i32* %p) {
473; CHECK-LABEL: define {{[^@]+}}@test11
474; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]])
475; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
476; CHECK-NEXT:    [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
477; CHECK-NEXT:    ret i64 [[RET]]
478;
479  %p-cast = bitcast i32* %p to i64*
480  %ret = load i64, i64* %p-cast, align 8
481  ret i64 %ret
482}
483
484; TEST 12
485; Test for deduction using must-be-executed-context and GEP instruction
486
487; FXIME: %p should have nonnull
488define i64 @test12-1(i32* align 4 %p) {
489; CHECK-LABEL: define {{[^@]+}}@test12-1
490; CHECK-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]])
491; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
492; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
493; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
494; CHECK-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
495; CHECK-NEXT:    ret i64 [[RET]]
496;
497  %p-cast = bitcast i32* %p to i64*
498  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
499  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
500  %ret = load i64, i64* %arrayidx1, align 16
501  ret i64 %ret
502}
503
504define i64 @test12-2(i32* align 4 %p) {
505; CHECK-LABEL: define {{[^@]+}}@test12-2
506; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]])
507; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
508; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
509; CHECK-NEXT:    [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
510; CHECK-NEXT:    ret i64 [[RET]]
511;
512  %p-cast = bitcast i32* %p to i64*
513  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
514  %ret = load i64, i64* %arrayidx0, align 16
515  ret i64 %ret
516}
517
518; FXIME: %p should have nonnull
519define void @test12-3(i32* align 4 %p) {
520; CHECK-LABEL: define {{[^@]+}}@test12-3
521; CHECK-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]])
522; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
523; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
524; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
525; CHECK-NEXT:    store i64 0, i64* [[ARRAYIDX1]], align 16
526; CHECK-NEXT:    ret void
527;
528  %p-cast = bitcast i32* %p to i64*
529  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
530  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
531  store i64 0, i64* %arrayidx1, align 16
532  ret void
533}
534
535define void @test12-4(i32* align 4 %p) {
536; CHECK-LABEL: define {{[^@]+}}@test12-4
537; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]])
538; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
539; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
540; CHECK-NEXT:    store i64 0, i64* [[ARRAYIDX0]], align 16
541; CHECK-NEXT:    ret void
542;
543  %p-cast = bitcast i32* %p to i64*
544  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
545  store i64 0, i64* %arrayidx0, align 16
546  ret void
547}
548
549declare void @use(i64*) willreturn nounwind
550
551define void @test12-5(i32* align 4 %p) {
552; CHECK-LABEL: define {{[^@]+}}@test12-5
553; CHECK-SAME: (i32* align 16 [[P:%.*]])
554; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
555; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
556; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
557; CHECK-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX1]])
558; CHECK-NEXT:    ret void
559;
560  %p-cast = bitcast i32* %p to i64*
561  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
562  %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
563  tail call void @use(i64* align 16 %arrayidx1)
564  ret void
565}
566
567define void @test12-6(i32* align 4 %p) {
568; CHECK-LABEL: define {{[^@]+}}@test12-6
569; CHECK-SAME: (i32* align 16 [[P:%.*]])
570; CHECK-NEXT:    [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
571; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
572; CHECK-NEXT:    tail call void @use(i64* align 16 [[ARRAYIDX0]])
573; CHECK-NEXT:    ret void
574;
575  %p-cast = bitcast i32* %p to i64*
576  %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
577  tail call void @use(i64* align 16 %arrayidx0)
578  ret void
579}
580
581define void @test13(i1 %c, i32* align 32 %dst) #0 {
582; CHECK-LABEL: define {{[^@]+}}@test13
583; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
584; CHECK-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
585; CHECK:       truebb:
586; CHECK-NEXT:    br label [[END:%.*]]
587; CHECK:       falsebb:
588; CHECK-NEXT:    br label [[END]]
589; CHECK:       end:
590; CHECK-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
591; CHECK-NEXT:    store i32 0, i32* [[PTR]], align 32
592; CHECK-NEXT:    ret void
593;
594  br i1 %c, label %truebb, label %falsebb
595truebb:
596  br label %end
597falsebb:
598  br label %end
599end:
600  %ptr = phi i32* [ %dst, %truebb ], [ null, %falsebb ]
601  store i32 0, i32* %ptr
602  ret void
603}
604
605define void @test13-1(i1 %c, i32* align 32 %dst) {
606; CHECK-LABEL: define {{[^@]+}}@test13-1
607; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
608; CHECK-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
609; CHECK:       truebb:
610; CHECK-NEXT:    br label [[END:%.*]]
611; CHECK:       falsebb:
612; CHECK-NEXT:    br label [[END]]
613; CHECK:       end:
614; CHECK-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
615; CHECK-NEXT:    store i32 0, i32* [[PTR]], align 16
616; CHECK-NEXT:    ret void
617;
618  br i1 %c, label %truebb, label %falsebb
619truebb:
620  br label %end
621falsebb:
622  br label %end
623end:
624  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 48 to i32*), %falsebb ]
625  store i32 0, i32* %ptr
626  ret void
627}
628
629define void @test13-2(i1 %c, i32* align 32 %dst) {
630; CHECK-LABEL: define {{[^@]+}}@test13-2
631; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
632; CHECK-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
633; CHECK:       truebb:
634; CHECK-NEXT:    br label [[END:%.*]]
635; CHECK:       falsebb:
636; CHECK-NEXT:    br label [[END]]
637; CHECK:       end:
638; CHECK-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
639; CHECK-NEXT:    store i32 0, i32* [[PTR]], align 32
640; CHECK-NEXT:    ret void
641;
642  br i1 %c, label %truebb, label %falsebb
643truebb:
644  br label %end
645falsebb:
646  br label %end
647end:
648  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 160 to i32*), %falsebb ]
649  store i32 0, i32* %ptr
650  ret void
651}
652
653define void @test13-3(i1 %c, i32* align 32 %dst) {
654; CHECK-LABEL: define {{[^@]+}}@test13-3
655; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
656; CHECK-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
657; CHECK:       truebb:
658; CHECK-NEXT:    br label [[END:%.*]]
659; CHECK:       falsebb:
660; CHECK-NEXT:    br label [[END]]
661; CHECK:       end:
662; CHECK-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
663; CHECK-NEXT:    store i32 0, i32* [[PTR]], align 32
664; CHECK-NEXT:    ret void
665;
666  br i1 %c, label %truebb, label %falsebb
667truebb:
668  br label %end
669falsebb:
670  br label %end
671end:
672  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 128 to i32*), %falsebb ]
673  store i32 0, i32* %ptr
674  ret void
675}
676
677; Don't crash on ptr2int/int2ptr uses.
678define i64 @ptr2int(i32* %p) {
679; CHECK-LABEL: define {{[^@]+}}@ptr2int
680; CHECK-SAME: (i32* nofree readnone [[P:%.*]])
681; CHECK-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
682; CHECK-NEXT:    ret i64 [[P2I]]
683;
684  %p2i = ptrtoint i32* %p to i64
685  ret i64 %p2i
686}
687define i64* @int2ptr(i64 %i) {
688; CHECK-LABEL: define {{[^@]+}}@int2ptr
689; CHECK-SAME: (i64 [[I:%.*]])
690; CHECK-NEXT:    [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
691; CHECK-NEXT:    ret i64* [[I2P]]
692;
693  %i2p = inttoptr i64 %i to i64*
694  ret i64* %i2p
695}
696
697; Use the store alignment only for the pointer operand.
698define void @aligned_store(i8* %Value, i8** %Ptr) {
699; CHECK-LABEL: define {{[^@]+}}@aligned_store
700; CHECK-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]])
701; CHECK-NEXT:    store i8* [[VALUE]], i8** [[PTR]], align 32
702; CHECK-NEXT:    ret void
703;
704  store i8* %Value, i8** %Ptr, align 32
705  ret void
706}
707
708declare i8* @some_func(i8*)
709define void @align_call_op_not_store(i8* align 2048 %arg) {
710; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store
711; CHECK-SAME: (i8* align 2048 [[ARG:%.*]])
712; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]])
713; CHECK-NEXT:    store i8 0, i8* [[UNKNOWN]]
714; CHECK-NEXT:    ret void
715;
716  %unknown = call i8* @some_func(i8* %arg)
717  store i8 0, i8* %unknown
718  ret void
719}
720define void @align_store_after_bc(i32* align 2048 %arg) {
721;
722; CHECK-LABEL: define {{[^@]+}}@align_store_after_bc
723; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]])
724; CHECK-NEXT:    [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
725; CHECK-NEXT:    store i8 0, i8* [[BC]], align 2048
726; CHECK-NEXT:    ret void
727;
728  %bc = bitcast i32* %arg to i8*
729  store i8 0, i8* %bc
730  ret void
731}
732
733; Make sure we do not annotate the callee of a must-tail call with an alignment
734; we cannot also put on the caller.
735@cnd = external global i1
736define i32 @musttail_callee_1(i32* %p) {
737; CHECK-LABEL: define {{[^@]+}}@musttail_callee_1
738; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]])
739; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P]], align 32
740; CHECK-NEXT:    ret i32 [[V]]
741;
742  %v = load i32, i32* %p, align 32
743  ret i32 %v
744}
745define i32 @musttail_caller_1(i32* %p) {
746; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1
747; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]])
748; IS__TUNIT____-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
749; IS__TUNIT____-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
750; IS__TUNIT____:       mt:
751; IS__TUNIT____-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]])
752; IS__TUNIT____-NEXT:    ret i32 [[V]]
753; IS__TUNIT____:       exit:
754; IS__TUNIT____-NEXT:    ret i32 0
755;
756; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_caller_1
757; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]])
758; IS__CGSCC____-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
759; IS__CGSCC____-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
760; IS__CGSCC____:       mt:
761; IS__CGSCC____-NEXT:    [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]])
762; IS__CGSCC____-NEXT:    ret i32 [[V]]
763; IS__CGSCC____:       exit:
764; IS__CGSCC____-NEXT:    ret i32 0
765;
766  %c = load i1, i1* @cnd
767  br i1 %c, label %mt, label %exit
768mt:
769  %v = musttail call i32 @musttail_callee_1(i32* %p)
770  ret i32 %v
771exit:
772  ret i32 0
773}
774
775attributes #0 = { nounwind uwtable noinline }
776attributes #1 = { uwtable noinline }
777attributes #2 = { "null-pointer-is-valid"="true" }
778