1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4 ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8 ; Test cases designed for the nosync function attribute.
9 ; FIXME's are used to indicate problems and missing attributes.
22 ; int *foo(struct ST *s) {
23 ; return &s[1].Z.B[5][13];
27 ; non-convergent and readnone implies nosync
28 %struct.RT = type { i8, [10 x [20 x i32]], i8 }
29 %struct.ST = type { i32, double, %struct.RT }
32 ; CHECK: @[[A:[a-zA-Z0-9_$"\\.-]+]] = common global i32 0, align 4
34 define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
35 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable willreturn
36 ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
37 ; IS__TUNIT____-SAME: (%struct.ST* nofree readnone "no-capture-maybe-returned" [[S:%.*]]) #[[ATTR0:[0-9]+]] {
38 ; IS__TUNIT____-NEXT: entry:
39 ; IS__TUNIT____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
40 ; IS__TUNIT____-NEXT: ret i32* [[ARRAYIDX]]
42 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn
43 ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
44 ; IS__CGSCC____-SAME: (%struct.ST* nofree readnone "no-capture-maybe-returned" [[S:%.*]]) #[[ATTR0:[0-9]+]] {
45 ; IS__CGSCC____-NEXT: entry:
46 ; IS__CGSCC____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
47 ; IS__CGSCC____-NEXT: ret i32* [[ARRAYIDX]]
50 %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13
55 ; atomic load with monotonic ordering
56 ; int load_monotonic(_Atomic int *num) {
57 ; int n = atomic_load_explicit(num, memory_order_relaxed);
61 define i32 @load_monotonic(i32* nocapture readonly %0) norecurse nounwind uwtable {
62 ; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable willreturn
63 ; CHECK-LABEL: define {{[^@]+}}@load_monotonic
64 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
65 ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, i32* [[TMP0]] monotonic, align 4
66 ; CHECK-NEXT: ret i32 [[TMP2]]
68 %2 = load atomic i32, i32* %0 monotonic, align 4
74 ; atomic store with monotonic ordering.
75 ; void store_monotonic(_Atomic int *num) {
76 ; atomic_load_explicit(num, memory_order_relaxed);
79 define void @store_monotonic(i32* nocapture %0) norecurse nounwind uwtable {
80 ; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable willreturn
81 ; CHECK-LABEL: define {{[^@]+}}@store_monotonic
82 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR1]] {
83 ; CHECK-NEXT: store atomic i32 10, i32* [[TMP0]] monotonic, align 4
84 ; CHECK-NEXT: ret void
86 store atomic i32 10, i32* %0 monotonic, align 4
90 ; TEST 4 - negative, should not deduce nosync
91 ; atomic load with acquire ordering.
92 ; int load_acquire(_Atomic int *num) {
93 ; int n = atomic_load_explicit(num, memory_order_acquire);
97 define i32 @load_acquire(i32* nocapture readonly %0) norecurse nounwind uwtable {
98 ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
99 ; CHECK-LABEL: define {{[^@]+}}@load_acquire
100 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] {
101 ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, i32* [[TMP0]] acquire, align 4
102 ; CHECK-NEXT: ret i32 [[TMP2]]
104 %2 = load atomic i32, i32* %0 acquire, align 4
108 ; TEST 5 - negative, should not deduce nosync
109 ; atomic load with release ordering
110 ; void load_release(_Atomic int *num) {
111 ; atomic_store_explicit(num, 10, memory_order_release);
114 define void @load_release(i32* nocapture %0) norecurse nounwind uwtable {
115 ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
116 ; CHECK-LABEL: define {{[^@]+}}@load_release
117 ; CHECK-SAME: (i32* nocapture nofree noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR2]] {
118 ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4
119 ; CHECK-NEXT: ret void
121 store atomic volatile i32 10, i32* %0 release, align 4
125 ; TEST 6 - negative volatile, relaxed atomic
127 define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable {
128 ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
129 ; CHECK-LABEL: define {{[^@]+}}@load_volatile_release
130 ; CHECK-SAME: (i32* nocapture nofree noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR2]] {
131 ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4
132 ; CHECK-NEXT: ret void
134 store atomic volatile i32 10, i32* %0 release, align 4
138 ; TEST 7 - negative, should not deduce nosync
140 ; void volatile_store(volatile int *num) {
144 define void @volatile_store(i32* %0) norecurse nounwind uwtable {
145 ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
146 ; CHECK-LABEL: define {{[^@]+}}@volatile_store
147 ; CHECK-SAME: (i32* nofree noundef align 4 [[TMP0:%.*]]) #[[ATTR2]] {
148 ; CHECK-NEXT: store volatile i32 14, i32* [[TMP0]], align 4
149 ; CHECK-NEXT: ret void
151 store volatile i32 14, i32* %0, align 4
155 ; TEST 8 - negative, should not deduce nosync
157 ; int volatile_load(volatile int *num) {
162 define i32 @volatile_load(i32* %0) norecurse nounwind uwtable {
163 ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
164 ; CHECK-LABEL: define {{[^@]+}}@volatile_load
165 ; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]]) #[[ATTR2]] {
166 ; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4
167 ; CHECK-NEXT: ret i32 [[TMP2]]
169 %2 = load volatile i32, i32* %0, align 4
175 ; CHECK: Function Attrs: noinline nosync nounwind uwtable
176 ; CHECK-NEXT: declare void @nosync_function()
177 declare void @nosync_function() noinline nounwind uwtable nosync
179 define void @call_nosync_function() nounwind uwtable noinline {
180 ; CHECK: Function Attrs: noinline nosync nounwind uwtable
181 ; CHECK-LABEL: define {{[^@]+}}@call_nosync_function
182 ; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
183 ; CHECK-NEXT: tail call void @nosync_function() #[[ATTR4:[0-9]+]]
184 ; CHECK-NEXT: ret void
186 tail call void @nosync_function() noinline nounwind uwtable
190 ; TEST 10 - negative, should not deduce nosync
192 ; CHECK: Function Attrs: noinline nounwind uwtable
193 ; CHECK-NEXT: declare void @might_sync()
194 declare void @might_sync() noinline nounwind uwtable
196 define void @call_might_sync() nounwind uwtable noinline {
197 ; CHECK: Function Attrs: noinline nounwind uwtable
198 ; CHECK-LABEL: define {{[^@]+}}@call_might_sync
199 ; CHECK-SAME: () #[[ATTR4]] {
200 ; CHECK-NEXT: tail call void @might_sync() #[[ATTR4]]
201 ; CHECK-NEXT: ret void
203 tail call void @might_sync() noinline nounwind uwtable
207 ; TEST 11 - positive, should deduce nosync
208 ; volatile operation in same scc but dead. Call volatile_load defined in TEST 8.
210 define i32 @scc1(i32* %0) noinline nounwind uwtable {
211 ; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
212 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc1
213 ; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] {
214 ; NOT_CGSCC_NPM-NEXT: unreachable
216 ; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
217 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc1
218 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] {
219 ; IS__CGSCC_NPM-NEXT: unreachable
221 tail call void @scc2(i32* %0);
222 %val = tail call i32 @volatile_load(i32* %0);
226 define void @scc2(i32* %0) noinline nounwind uwtable {
227 ; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
228 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc2
229 ; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5]] {
230 ; NOT_CGSCC_NPM-NEXT: unreachable
232 ; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
233 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc2
234 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5]] {
235 ; IS__CGSCC_NPM-NEXT: unreachable
237 tail call i32 @scc1(i32* %0);
241 ; TEST 12 - fences, negative
243 ; void foo1(int *a, std::atomic<bool> flag){
245 ; atomic_thread_fence(std::memory_order_release);
246 ; flag.store(true, std::memory_order_relaxed);
249 ; void bar(int *a, std::atomic<bool> flag){
250 ; while(!flag.load(std::memory_order_relaxed))
253 ; atomic_thread_fence(std::memory_order_acquire);
257 %"struct.std::atomic" = type { %"struct.std::__atomic_base" }
258 %"struct.std::__atomic_base" = type { i8 }
260 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
261 ; IS__TUNIT____: Function Attrs: nofree nounwind willreturn
262 ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1
263 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR6:[0-9]+]] {
264 ; IS__TUNIT____-NEXT: store i32 100, i32* [[TMP0]], align 4
265 ; IS__TUNIT____-NEXT: fence release
266 ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
267 ; IS__TUNIT____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
268 ; IS__TUNIT____-NEXT: ret void
270 ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind willreturn
271 ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1
272 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR6:[0-9]+]] {
273 ; IS__CGSCC____-NEXT: store i32 100, i32* [[TMP0]], align 4
274 ; IS__CGSCC____-NEXT: fence release
275 ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
276 ; IS__CGSCC____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
277 ; IS__CGSCC____-NEXT: ret void
279 store i32 100, i32* %0, align 4
281 %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
282 store atomic i8 1, i8* %3 monotonic, align 1
286 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
287 ; IS__TUNIT____: Function Attrs: nofree nounwind
288 ; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
289 ; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR7:[0-9]+]] {
290 ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
291 ; IS__TUNIT____-NEXT: br label [[TMP4:%.*]]
293 ; IS__TUNIT____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
294 ; IS__TUNIT____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
295 ; IS__TUNIT____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
296 ; IS__TUNIT____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
298 ; IS__TUNIT____-NEXT: fence acquire
299 ; IS__TUNIT____-NEXT: ret void
301 ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind
302 ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
303 ; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR7:[0-9]+]] {
304 ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
305 ; IS__CGSCC____-NEXT: br label [[TMP4:%.*]]
307 ; IS__CGSCC____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
308 ; IS__CGSCC____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
309 ; IS__CGSCC____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
310 ; IS__CGSCC____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
312 ; IS__CGSCC____-NEXT: fence acquire
313 ; IS__CGSCC____-NEXT: ret void
315 %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
319 %5 = load atomic i8, i8* %3 monotonic, align 1
321 %7 = icmp eq i8 %6, 0
322 br i1 %7, label %4, label %8
329 ; TEST 13 - Fence syncscope("singlethread") seq_cst
330 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
331 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
332 ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1_singlethread
333 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] {
334 ; IS__TUNIT____-NEXT: store i32 100, i32* [[TMP0]], align 4
335 ; IS__TUNIT____-NEXT: fence syncscope("singlethread") release
336 ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
337 ; IS__TUNIT____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
338 ; IS__TUNIT____-NEXT: ret void
340 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
341 ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1_singlethread
342 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] {
343 ; IS__CGSCC____-NEXT: store i32 100, i32* [[TMP0]], align 4
344 ; IS__CGSCC____-NEXT: fence syncscope("singlethread") release
345 ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
346 ; IS__CGSCC____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
347 ; IS__CGSCC____-NEXT: ret void
349 store i32 100, i32* %0, align 4
350 fence syncscope("singlethread") release
351 %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
352 store atomic i8 1, i8* %3 monotonic, align 1
356 define void @bar_singlethread(i32* %0, %"struct.std::atomic"* %1) {
357 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind
358 ; IS__TUNIT____-LABEL: define {{[^@]+}}@bar_singlethread
359 ; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] {
360 ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
361 ; IS__TUNIT____-NEXT: br label [[TMP4:%.*]]
363 ; IS__TUNIT____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
364 ; IS__TUNIT____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
365 ; IS__TUNIT____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
366 ; IS__TUNIT____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
368 ; IS__TUNIT____-NEXT: fence syncscope("singlethread") acquire
369 ; IS__TUNIT____-NEXT: ret void
371 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind
372 ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar_singlethread
373 ; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] {
374 ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
375 ; IS__CGSCC____-NEXT: br label [[TMP4:%.*]]
377 ; IS__CGSCC____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
378 ; IS__CGSCC____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
379 ; IS__CGSCC____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
380 ; IS__CGSCC____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
382 ; IS__CGSCC____-NEXT: fence syncscope("singlethread") acquire
383 ; IS__CGSCC____-NEXT: ret void
385 %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
389 %5 = load atomic i8, i8* %3 monotonic, align 1
391 %7 = icmp eq i8 %6, 0
392 br i1 %7, label %4, label %8
395 fence syncscope("singlethread") acquire
399 declare void @llvm.memcpy(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
400 declare void @llvm.memset(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
402 ; TEST 14 - negative, checking volatile intrinsics.
404 ; It is odd to add nocapture but a result of the llvm.memcpy nocapture.
406 define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) {
407 ; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
408 ; IS__TUNIT____-LABEL: define {{[^@]+}}@memcpy_volatile
409 ; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR10:[0-9]+]] {
410 ; IS__TUNIT____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR18:[0-9]+]]
411 ; IS__TUNIT____-NEXT: ret i32 4
413 ; IS__CGSCC____: Function Attrs: argmemonly nofree nounwind willreturn
414 ; IS__CGSCC____-LABEL: define {{[^@]+}}@memcpy_volatile
415 ; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR10:[0-9]+]] {
416 ; IS__CGSCC____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR19:[0-9]+]]
417 ; IS__CGSCC____-NEXT: ret i32 4
419 call void @llvm.memcpy(i8* %ptr1, i8* %ptr2, i32 8, i1 1)
423 ; TEST 15 - positive, non-volatile intrinsic.
425 ; It is odd to add nocapture but a result of the llvm.memset nocapture.
427 define i32 @memset_non_volatile(i8* %ptr1, i8 %val) {
428 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
429 ; IS__TUNIT____-LABEL: define {{[^@]+}}@memset_non_volatile
430 ; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR11:[0-9]+]] {
431 ; IS__TUNIT____-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR19:[0-9]+]]
432 ; IS__TUNIT____-NEXT: ret i32 4
434 ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
435 ; IS__CGSCC____-LABEL: define {{[^@]+}}@memset_non_volatile
436 ; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR11:[0-9]+]] {
437 ; IS__CGSCC____-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR20:[0-9]+]]
438 ; IS__CGSCC____-NEXT: ret i32 4
440 call void @llvm.memset(i8* %ptr1, i8 %val, i32 8, i1 0)
444 ; TEST 16 - negative, inline assembly.
446 define i32 @inline_asm_test(i32 %x) {
447 ; CHECK-LABEL: define {{[^@]+}}@inline_asm_test
448 ; CHECK-SAME: (i32 [[X:%.*]]) {
449 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 asm "bswap $0", "=r,r"(i32 [[X]])
450 ; CHECK-NEXT: ret i32 4
452 call i32 asm "bswap $0", "=r,r"(i32 %x)
456 declare void @readnone_test() convergent readnone
458 ; TEST 17 - negative. Convergent
459 define void @convergent_readnone(){
460 ; CHECK: Function Attrs: readnone
461 ; CHECK-LABEL: define {{[^@]+}}@convergent_readnone
462 ; CHECK-SAME: () #[[ATTR13:[0-9]+]] {
463 ; CHECK-NEXT: call void @readnone_test()
464 ; CHECK-NEXT: ret void
466 call void @readnone_test()
470 ; CHECK: Function Attrs: nounwind
471 ; CHECK-NEXT: declare void @llvm.x86.sse2.clflush(i8*)
472 declare void @llvm.x86.sse2.clflush(i8*)
473 @a = common global i32 0, align 4
475 ; TEST 18 - negative. Synchronizing intrinsic
477 define void @i_totally_sync() {
478 ; CHECK: Function Attrs: nounwind
479 ; CHECK-LABEL: define {{[^@]+}}@i_totally_sync
480 ; CHECK-SAME: () #[[ATTR14:[0-9]+]] {
481 ; CHECK-NEXT: tail call void @llvm.x86.sse2.clflush(i8* noundef nonnull align 4 dereferenceable(4) bitcast (i32* @a to i8*))
482 ; CHECK-NEXT: ret void
484 tail call void @llvm.x86.sse2.clflush(i8* bitcast (i32* @a to i8*))
488 declare float @llvm.cos(float %val) readnone
490 ; TEST 19 - positive, readnone & non-convergent intrinsic.
492 define i32 @cos_test(float %x) {
493 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
494 ; IS__TUNIT____-LABEL: define {{[^@]+}}@cos_test
495 ; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR15:[0-9]+]] {
496 ; IS__TUNIT____-NEXT: ret i32 4
498 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
499 ; IS__CGSCC____-LABEL: define {{[^@]+}}@cos_test
500 ; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR15:[0-9]+]] {
501 ; IS__CGSCC____-NEXT: ret i32 4
503 call float @llvm.cos(float %x)
507 define float @cos_test2(float %x) {
508 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
509 ; IS__TUNIT____-LABEL: define {{[^@]+}}@cos_test2
510 ; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR15]] {
511 ; IS__TUNIT____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR20:[0-9]+]]
512 ; IS__TUNIT____-NEXT: ret float [[C]]
514 ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
515 ; IS__CGSCC____-LABEL: define {{[^@]+}}@cos_test2
516 ; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR16:[0-9]+]] {
517 ; IS__CGSCC____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR21:[0-9]+]]
518 ; IS__CGSCC____-NEXT: ret float [[C]]
520 %c = call float @llvm.cos(float %x)
524 ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind optsize readnone ssp uwtable willreturn }
525 ; IS__TUNIT____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn }
526 ; IS__TUNIT____: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind uwtable willreturn }
527 ; IS__TUNIT____: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable }
528 ; IS__TUNIT____: attributes #[[ATTR4]] = { noinline nounwind uwtable }
529 ; IS__TUNIT____: attributes #[[ATTR5]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
530 ; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nounwind willreturn }
531 ; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nounwind }
532 ; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn }
533 ; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind }
534 ; IS__TUNIT____: attributes #[[ATTR10]] = { argmemonly nofree nounwind willreturn }
535 ; IS__TUNIT____: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly }
536 ; IS__TUNIT____: attributes #[[ATTR12:[0-9]+]] = { convergent readnone }
537 ; IS__TUNIT____: attributes #[[ATTR13]] = { readnone }
538 ; IS__TUNIT____: attributes #[[ATTR14]] = { nounwind }
539 ; IS__TUNIT____: attributes #[[ATTR15]] = { nofree nosync nounwind readnone willreturn }
540 ; IS__TUNIT____: attributes #[[ATTR16:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly }
541 ; IS__TUNIT____: attributes #[[ATTR17:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
542 ; IS__TUNIT____: attributes #[[ATTR18]] = { willreturn }
543 ; IS__TUNIT____: attributes #[[ATTR19]] = { willreturn writeonly }
544 ; IS__TUNIT____: attributes #[[ATTR20]] = { readnone willreturn }
546 ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn }
547 ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn }
548 ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind uwtable willreturn }
549 ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable }
550 ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noinline nounwind uwtable }
551 ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
552 ; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree norecurse nounwind willreturn }
553 ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree norecurse nounwind }
554 ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn }
555 ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind }
556 ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { argmemonly nofree nounwind willreturn }
557 ; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly }
558 ; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { convergent readnone }
559 ; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone }
560 ; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nounwind }
561 ; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind readnone willreturn }
562 ; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree nosync nounwind readnone willreturn }
563 ; IS__CGSCC_OPM: attributes #[[ATTR17:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly }
564 ; IS__CGSCC_OPM: attributes #[[ATTR18:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
565 ; IS__CGSCC_OPM: attributes #[[ATTR19]] = { willreturn }
566 ; IS__CGSCC_OPM: attributes #[[ATTR20]] = { willreturn writeonly }
567 ; IS__CGSCC_OPM: attributes #[[ATTR21]] = { readnone willreturn }
569 ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn }
570 ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn }
571 ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind uwtable willreturn }
572 ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable }
573 ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { noinline nounwind uwtable }
574 ; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn }
575 ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree norecurse nounwind willreturn }
576 ; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nounwind }
577 ; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn }
578 ; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind }
579 ; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree nounwind willreturn }
580 ; IS__CGSCC_NPM: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly }
581 ; IS__CGSCC_NPM: attributes #[[ATTR12:[0-9]+]] = { convergent readnone }
582 ; IS__CGSCC_NPM: attributes #[[ATTR13]] = { readnone }
583 ; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nounwind }
584 ; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind readnone willreturn }
585 ; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind readnone willreturn }
586 ; IS__CGSCC_NPM: attributes #[[ATTR17:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly }
587 ; IS__CGSCC_NPM: attributes #[[ATTR18:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
588 ; IS__CGSCC_NPM: attributes #[[ATTR19]] = { willreturn }
589 ; IS__CGSCC_NPM: attributes #[[ATTR20]] = { willreturn writeonly }
590 ; IS__CGSCC_NPM: attributes #[[ATTR21]] = { readnone willreturn }