1 ; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 ; Test cases specifically designed for "align" attribute.
6 ; We use FIXME's to indicate problems and missing attributes.
10 ; ATTRIBUTOR: define align 8 i32* @test1(i32* readnone returned align 8 "no-capture-maybe-returned" %0)
11 define i32* @test1(i32* align 8 %0) #0 {
16 ; ATTRIBUTOR: define i32* @test2(i32* readnone returned "no-capture-maybe-returned" %0)
17 define i32* @test2(i32* %0) #0 {
22 ; ATTRIBUTOR: define align 4 i32* @test3(i32* readnone align 8 "no-capture-maybe-returned" %0, i32* readnone align 4 "no-capture-maybe-returned" %1, i1 %2)
23 define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 {
24 %ret = select i1 %2, i32* %0, i32* %1
29 ; ATTRIBUTOR: define align 32 i32* @test4(i32* readnone align 32 "no-capture-maybe-returned" %0, i32* readnone align 32 "no-capture-maybe-returned" %1, i1 %2)
30 define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 {
31 %ret = select i1 %2, i32* %0, i32* %1
36 declare i32* @unknown()
37 declare align 8 i32* @align8()
40 ; ATTRIBUTOR: define align 8 i32* @test5_1()
41 define i32* @test5_1() {
42 %ret = tail call align 8 i32* @unknown()
46 ; ATTRIBUTOR: define align 8 i32* @test5_2()
47 define i32* @test5_2() {
48 %ret = tail call i32* @align8()
54 ; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @test6_1()
55 define i32* @test6_1() #0 {
56 %ret = tail call i32* @test6_2()
60 ; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @test6_2()
61 define i32* @test6_2() #0 {
62 %ret = tail call i32* @test6_1()
67 ; char a1 __attribute__((aligned(8)));
68 ; char a2 __attribute__((aligned(16)));
74 ; return a?f1(a):f3(&a2);
78 ; return a?&a1: f1(&a2);
81 @a1 = common global i8 0, align 8
82 @a2 = common global i8 0, align 16
84 ; Function Attrs: nounwind readnone ssp uwtable
85 define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
86 ; ATTRIBUTOR: define internal nonnull align 8 dereferenceable(1) i8* @f1(i8* nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" %0)
87 %2 = icmp eq i8* %0, null
88 br i1 %2, label %3, label %5
90 ; <label>:3: ; preds = %1
91 ; ATTRIBUTOR: %4 = tail call align 8 i8* @f2(i8* nonnull align 8 dereferenceable(1) @a1)
92 %4 = tail call i8* @f2(i8* nonnull @a1)
93 ; ATTRIBUTOR: %l = load i8, i8* %4, align 8
97 ; <label>:5: ; preds = %1, %3
98 %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
102 ; Function Attrs: nounwind readnone ssp uwtable
103 define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
104 ; ATTRIBUTOR: define internal nonnull align 8 dereferenceable(1) i8* @f2(i8* nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" %0)
105 %2 = icmp eq i8* %0, null
106 br i1 %2, label %5, label %3
108 ; <label>:3: ; preds = %1
110 ; ATTRIBUTOR: %4 = tail call i8* @f1(i8* nonnull align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
111 %4 = tail call i8* @f1(i8* nonnull %0)
114 ; <label>:5: ; preds = %1
115 ; ATTRIBUTOR: %6 = tail call i8* @f3(i8* nonnull align 16 dereferenceable(1) @a2)
116 %6 = tail call i8* @f3(i8* nonnull @a2)
119 ; <label>:7: ; preds = %5, %3
120 %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
124 ; Function Attrs: nounwind readnone ssp uwtable
125 define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
126 ; ATTRIBUTOR: define internal nonnull align 8 dereferenceable(1) i8* @f3(i8* nocapture nonnull readnone align 16 dereferenceable(1) %0)
127 %2 = icmp eq i8* %0, null
128 br i1 %2, label %3, label %5
130 ; <label>:3: ; preds = %1
131 ; ATTRIBUTOR: %4 = tail call i8* @f1(i8* nonnull align 16 dereferenceable(1) @a2)
132 %4 = tail call i8* @f1(i8* nonnull @a2)
135 ; <label>:5: ; preds = %1, %3
136 %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
141 ; Better than IR information
142 ; ATTRIBUTOR: define align 32 i32* @test7(i32* readnone returned align 32 "no-capture-maybe-returned" %p)
143 define align 4 i32* @test7(i32* align 32 %p) #0 {
144 tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
150 define void @test8_helper() {
151 %ptr0 = tail call i32* @unknown()
152 %ptr1 = tail call align 4 i32* @unknown()
153 %ptr2 = tail call align 8 i32* @unknown()
155 tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
156 ; ATTRIBUTOR: tail call void @test8(i32* align 4 %ptr1, i32* align 4 %ptr1, i32* %ptr0)
157 tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
158 ; ATTRIBUTOR: tail call void @test8(i32* align 8 %ptr2, i32* align 4 %ptr1, i32* align 4 %ptr1)
159 tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
160 ; ATTRIBUTOR: tail call void @test8(i32* align 8 %ptr2, i32* align 4 %ptr1, i32* align 4 %ptr1)
164 define internal void @test8(i32* %a, i32* %b, i32* %c) {
165 ; ATTRIBUTOR: define internal void @test8(i32* nocapture readnone align 4 %a, i32* nocapture readnone align 4 %b, i32* nocapture readnone %c)
169 declare void @test9_helper(i32* %A)
170 define void @test9_traversal(i1 %c, i32* align 4 %B, i32* align 8 %C) {
171 %sel = select i1 %c, i32* %B, i32* %C
172 call void @test9_helper(i32* %sel)
176 ; FIXME: This will work with an upcoming patch (D66618 or similar)
177 ; define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p)
178 ; ATTRIBUTOR: define i32* @test10a(i32* nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" %p)
179 define i32* @test10a(i32* align 32 %p) {
180 ; ATTRIBUTOR: %l = load i32, i32* %p, align 32
181 %l = load i32, i32* %p
182 %c = icmp eq i32 %l, 0
183 br i1 %c, label %t, label %f
185 %r = call i32* @test10a(i32* %p)
186 ; FIXME: This will work with an upcoming patch (D66618 or similar)
187 ; store i32 1, i32* %r, align 32
188 ; ATTRIBUTOR: store i32 1, i32* %r
190 %g0 = getelementptr i32, i32* %p, i32 8
193 %g1 = getelementptr i32, i32* %p, i32 8
194 ; FIXME: This will work with an upcoming patch (D66618 or similar)
195 ; store i32 -1, i32* %g1, align 32
196 ; ATTRIBUTOR: store i32 -1, i32* %g1
197 store i32 -1, i32* %g1
200 %phi = phi i32* [%g0, %t], [%g1, %f]
204 ; FIXME: This will work with an upcoming patch (D66618 or similar)
205 ; define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p)
206 ; ATTRIBUTOR: define i32* @test10b(i32* nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" %p)
207 define i32* @test10b(i32* align 32 %p) {
208 ; ATTRIBUTOR: %l = load i32, i32* %p, align 32
209 %l = load i32, i32* %p
210 %c = icmp eq i32 %l, 0
211 br i1 %c, label %t, label %f
213 %r = call i32* @test10b(i32* %p)
214 ; FIXME: This will work with an upcoming patch (D66618 or similar)
215 ; store i32 1, i32* %r, align 32
216 ; ATTRIBUTOR: store i32 1, i32* %r
218 %g0 = getelementptr i32, i32* %p, i32 8
221 %g1 = getelementptr i32, i32* %p, i32 -8
222 ; FIXME: This will work with an upcoming patch (D66618 or similar)
223 ; store i32 -1, i32* %g1, align 32
224 ; ATTRIBUTOR: store i32 -1, i32* %g1
225 store i32 -1, i32* %g1
228 %phi = phi i32* [%g0, %t], [%g1, %f]
232 attributes #0 = { nounwind uwtable noinline }
233 attributes #1 = { uwtable noinline }