[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / Attributor / nosync.ll
blobcb2b7eddb06417674a1cd152eba4457e7e725c99
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.
11 ; struct RT {
12 ;   char A;
13 ;   int B[10][20];
14 ;   char C;
15 ; };
16 ; struct ST {
17 ;   int X;
18 ;   double Y;
19 ;   struct RT Z;
20 ; };
22 ; int *foo(struct ST *s) {
23 ;   return &s[1].Z.B[5][13];
24 ; }
26 ; TEST 1
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]]
49 entry:
50   %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13
51   ret i32* %arrayidx
54 ; TEST 2
55 ; atomic load with monotonic ordering
56 ; int load_monotonic(_Atomic int *num) {
57 ;   int n = atomic_load_explicit(num, memory_order_relaxed);
58 ;   return n;
59 ; }
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
69   ret i32 %2
73 ; TEST 3
74 ; atomic store with monotonic ordering.
75 ; void store_monotonic(_Atomic int *num) {
76 ;   atomic_load_explicit(num, memory_order_relaxed);
77 ; }
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
87   ret void
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);
94 ;   return n;
95 ; }
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
105   ret i32 %2
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);
112 ; }
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
122   ret void
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
135   ret void
138 ; TEST 7 - negative, should not deduce nosync
139 ; volatile store.
140 ; void volatile_store(volatile int *num) {
141 ;   *num = 14;
142 ; }
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
152   ret void
155 ; TEST 8 - negative, should not deduce nosync
156 ; volatile load.
157 ; int volatile_load(volatile int *num) {
158 ;   int n = *num;
159 ;   return n;
160 ; }
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
170   ret i32 %2
173 ; TEST 9
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
187   ret void
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
204   ret void
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);
223   ret i32 %val;
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);
238   ret void;
241 ; TEST 12 - fences, negative
243 ; void foo1(int *a, std::atomic<bool> flag){
244 ;   *a = 100;
245 ;   atomic_thread_fence(std::memory_order_release);
246 ;   flag.store(true, std::memory_order_relaxed);
247 ; }
249 ; void bar(int *a, std::atomic<bool> flag){
250 ;   while(!flag.load(std::memory_order_relaxed))
251 ;     ;
253 ;   atomic_thread_fence(std::memory_order_acquire);
254 ;   int b = *a;
255 ; }
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
280   fence release
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
283   ret void
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:%.*]]
292 ; IS__TUNIT____:       4:
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:%.*]]
297 ; IS__TUNIT____:       8:
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:%.*]]
306 ; IS__CGSCC____:       4:
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:%.*]]
311 ; IS__CGSCC____:       8:
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
316   br label %4
318 4:                                                ; preds = %4, %2
319   %5 = load atomic i8, i8* %3  monotonic, align 1
320   %6 = and i8 %5, 1
321   %7 = icmp eq i8 %6, 0
322   br i1 %7, label %4, label %8
324 8:                                                ; preds = %4
325   fence acquire
326   ret void
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
353   ret void
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:%.*]]
362 ; IS__TUNIT____:       4:
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:%.*]]
367 ; IS__TUNIT____:       8:
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:%.*]]
376 ; IS__CGSCC____:       4:
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:%.*]]
381 ; IS__CGSCC____:       8:
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
386   br label %4
388 4:                                                ; preds = %4, %2
389   %5 = load atomic i8, i8* %3  monotonic, align 1
390   %6 = and i8 %5, 1
391   %7 = icmp eq i8 %6, 0
392   br i1 %7, label %4, label %8
394 8:                                                ; preds = %4
395   fence syncscope("singlethread") acquire
396   ret void
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)
420   ret i32 4
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)
441   ret i32 4
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)
453   ret i32 4
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()
467   ret void
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*))
485   ret void
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)
504   ret i32 4
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)
521   ret float %c
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 }