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