[LoongArch] Fix the assertion for atomic store with 'ptr' type
[llvm-project.git] / llvm / test / Transforms / FunctionAttrs / nosync.ll
blobde5398f17ce51d4aff3271fe5ae7151ad916d68d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
2 ; RUN: opt < %s -passes=function-attrs -S | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 ; Base case, empty function
7 define void @test1() {
8 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
9 ; CHECK-LABEL: @test1(
10 ; CHECK-NEXT:    ret void
12   ret void
15 ; Show the bottom up walk
16 define void @test2() {
17 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
18 ; CHECK-LABEL: @test2(
19 ; CHECK-NEXT:    call void @test1()
20 ; CHECK-NEXT:    ret void
22   call void @test1()
23   ret void
26 declare void @unknown() convergent
28 ; Negative case with convergent function
29 define void @test3() convergent {
30 ; CHECK: Function Attrs: convergent
31 ; CHECK-LABEL: @test3(
32 ; CHECK-NEXT:    call void @unknown()
33 ; CHECK-NEXT:    ret void
35   call void @unknown()
36   ret void
39 define i32 @test4(i32 %a, i32 %b) {
40 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
41 ; CHECK-LABEL: @test4(
42 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
43 ; CHECK-NEXT:    ret i32 [[A]]
45   %add = add i32 %a, %b
46   ret i32 %a
49 ; negative case - explicit sync
50 define void @test5(ptr %p) {
51 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
52 ; CHECK-LABEL: @test5(
53 ; CHECK-NEXT:    store atomic i8 0, ptr [[P:%.*]] seq_cst, align 1
54 ; CHECK-NEXT:    ret void
56   store atomic i8 0, ptr %p seq_cst, align 1
57   ret void
60 ; negative case - explicit sync
61 define i8 @test6(ptr %p) {
62 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
63 ; CHECK-LABEL: @test6(
64 ; CHECK-NEXT:    [[V:%.*]] = load atomic i8, ptr [[P:%.*]] seq_cst, align 1
65 ; CHECK-NEXT:    ret i8 [[V]]
67   %v = load atomic i8, ptr %p seq_cst, align 1
68   ret i8 %v
71 ; negative case - explicit sync
72 define void @test7(ptr %p) {
73 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
74 ; CHECK-LABEL: @test7(
75 ; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw add ptr [[P:%.*]], i8 0 seq_cst, align 1
76 ; CHECK-NEXT:    ret void
78   atomicrmw add ptr %p, i8 0 seq_cst, align 1
79   ret void
82 ; negative case - explicit sync
83 define void @test8(ptr %p) {
84 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn
85 ; CHECK-LABEL: @test8(
86 ; CHECK-NEXT:    fence seq_cst
87 ; CHECK-NEXT:    ret void
89   fence seq_cst
90   ret void
93 ; singlethread fences are okay
94 define void @test9(ptr %p) {
95 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
96 ; CHECK-LABEL: @test9(
97 ; CHECK-NEXT:    fence syncscope("singlethread") seq_cst
98 ; CHECK-NEXT:    ret void
100   fence syncscope("singlethread") seq_cst
101   ret void
104 ; atomic load with monotonic ordering
105 define i32 @load_monotonic(ptr nocapture readonly %0) norecurse nounwind uwtable {
106 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
107 ; CHECK-LABEL: @load_monotonic(
108 ; CHECK-NEXT:    [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] monotonic, align 4
109 ; CHECK-NEXT:    ret i32 [[TMP2]]
111   %2 = load atomic i32, ptr %0 monotonic, align 4
112   ret i32 %2
115 ; atomic store with monotonic ordering.
116 define void @store_monotonic(ptr nocapture %0) norecurse nounwind uwtable {
117 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
118 ; CHECK-LABEL: @store_monotonic(
119 ; CHECK-NEXT:    store atomic i32 10, ptr [[TMP0:%.*]] monotonic, align 4
120 ; CHECK-NEXT:    ret void
122   store atomic i32 10, ptr %0 monotonic, align 4
123   ret void
126 ; negative, should not deduce nosync
127 ; atomic load with acquire ordering.
128 define i32 @load_acquire(ptr nocapture readonly %0) norecurse nounwind uwtable {
129 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
130 ; CHECK-LABEL: @load_acquire(
131 ; CHECK-NEXT:    [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] acquire, align 4
132 ; CHECK-NEXT:    ret i32 [[TMP2]]
134   %2 = load atomic i32, ptr %0 acquire, align 4
135   ret i32 %2
138 define i32 @load_unordered(ptr nocapture readonly %0) norecurse nounwind uwtable {
139 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) uwtable
140 ; CHECK-LABEL: @load_unordered(
141 ; CHECK-NEXT:    [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] unordered, align 4
142 ; CHECK-NEXT:    ret i32 [[TMP2]]
144   %2 = load atomic i32, ptr %0 unordered, align 4
145   ret i32 %2
148 ; atomic store with unordered ordering.
149 define void @store_unordered(ptr nocapture %0) norecurse nounwind uwtable {
150 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) uwtable
151 ; CHECK-LABEL: @store_unordered(
152 ; CHECK-NEXT:    store atomic i32 10, ptr [[TMP0:%.*]] unordered, align 4
153 ; CHECK-NEXT:    ret void
155   store atomic i32 10, ptr %0 unordered, align 4
156   ret void
160 ; negative, should not deduce nosync
161 ; atomic load with release ordering
162 define void @load_release(ptr nocapture %0) norecurse nounwind uwtable {
163 ; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
164 ; CHECK-LABEL: @load_release(
165 ; CHECK-NEXT:    store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4
166 ; CHECK-NEXT:    ret void
168   store atomic volatile i32 10, ptr %0 release, align 4
169   ret void
172 ; negative volatile, relaxed atomic
173 define void @load_volatile_release(ptr nocapture %0) norecurse nounwind uwtable {
174 ; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
175 ; CHECK-LABEL: @load_volatile_release(
176 ; CHECK-NEXT:    store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4
177 ; CHECK-NEXT:    ret void
179   store atomic volatile i32 10, ptr %0 release, align 4
180   ret void
183 ; volatile store.
184 define void @volatile_store(ptr %0) norecurse nounwind uwtable {
185 ; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
186 ; CHECK-LABEL: @volatile_store(
187 ; CHECK-NEXT:    store volatile i32 14, ptr [[TMP0:%.*]], align 4
188 ; CHECK-NEXT:    ret void
190   store volatile i32 14, ptr %0, align 4
191   ret void
194 ; negative, should not deduce nosync
195 ; volatile load.
196 define i32 @volatile_load(ptr %0) norecurse nounwind uwtable {
197 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
198 ; CHECK-LABEL: @volatile_load(
199 ; CHECK-NEXT:    [[TMP2:%.*]] = load volatile i32, ptr [[TMP0:%.*]], align 4
200 ; CHECK-NEXT:    ret i32 [[TMP2]]
202   %2 = load volatile i32, ptr %0, align 4
203   ret i32 %2
206 ; CHECK: Function Attrs: noinline nosync nounwind uwtable
207 ; CHECK-NEXT: declare void @nosync_function()
208 declare void @nosync_function() noinline nounwind uwtable nosync
210 define void @call_nosync_function() nounwind uwtable noinline {
211 ; CHECK: Function Attrs: noinline nosync nounwind uwtable
212 ; CHECK-LABEL: @call_nosync_function(
213 ; CHECK-NEXT:    tail call void @nosync_function() #[[ATTR11:[0-9]+]]
214 ; CHECK-NEXT:    ret void
216   tail call void @nosync_function() noinline nounwind uwtable
217   ret void
220 ; CHECK: Function Attrs: noinline nounwind uwtable
221 ; CHECK-NEXT: declare void @might_sync()
222 declare void @might_sync() noinline nounwind uwtable
224 define void @call_might_sync() nounwind uwtable noinline {
225 ; CHECK: Function Attrs: noinline nounwind uwtable
226 ; CHECK-LABEL: @call_might_sync(
227 ; CHECK-NEXT:    tail call void @might_sync() #[[ATTR11]]
228 ; CHECK-NEXT:    ret void
230   tail call void @might_sync() noinline nounwind uwtable
231   ret void
234 declare void @llvm.memcpy(ptr %dest, ptr %src, i32 %len, i1 %isvolatile)
235 declare void @llvm.memset(ptr %dest, i8 %val, i32 %len, i1 %isvolatile)
237 ; negative, checking volatile intrinsics.
238 define i32 @memcpy_volatile(ptr %ptr1, ptr %ptr2) {
239 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
240 ; CHECK-LABEL: @memcpy_volatile(
241 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1:%.*]], ptr [[PTR2:%.*]], i32 8, i1 true)
242 ; CHECK-NEXT:    ret i32 4
244   call void @llvm.memcpy(ptr %ptr1, ptr %ptr2, i32 8, i1 1)
245   ret i32 4
248 ; positive, non-volatile intrinsic.
249 define i32 @memset_non_volatile(ptr %ptr1, i8 %val) {
250 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
251 ; CHECK-LABEL: @memset_non_volatile(
252 ; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr [[PTR1:%.*]], i8 [[VAL:%.*]], i32 8, i1 false)
253 ; CHECK-NEXT:    ret i32 4
255   call void @llvm.memset(ptr %ptr1, i8 %val, i32 8, i1 0)
256   ret i32 4
259 ; negative, inline assembly.
260 define i32 @inline_asm_test(i32 %x) {
261 ; CHECK-LABEL: @inline_asm_test(
262 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 asm "bswap $0", "=r,r"(i32 [[X:%.*]])
263 ; CHECK-NEXT:    ret i32 4
265   call i32 asm "bswap $0", "=r,r"(i32 %x)
266   ret i32 4
269 declare void @readnone_test() convergent readnone
271 ; negative. Convergent
272 define void @convergent_readnone(){
273 ; CHECK: Function Attrs: nofree nosync memory(none)
274 ; CHECK-LABEL: @convergent_readnone(
275 ; CHECK-NEXT:    call void @readnone_test()
276 ; CHECK-NEXT:    ret void
278   call void @readnone_test()
279   ret void
282 ; CHECK: Function Attrs: nounwind
283 ; CHECK-NEXT: declare void @llvm.x86.sse2.clflush(ptr)
284 declare void @llvm.x86.sse2.clflush(ptr)
285 @a = common global i32 0, align 4
287 ; negative. Synchronizing intrinsic
288 define void @i_totally_sync() {
289 ; CHECK: Function Attrs: nounwind
290 ; CHECK-LABEL: @i_totally_sync(
291 ; CHECK-NEXT:    tail call void @llvm.x86.sse2.clflush(ptr @a)
292 ; CHECK-NEXT:    ret void
294   tail call void @llvm.x86.sse2.clflush(ptr @a)
295   ret void
298 declare float @llvm.cos(float %val) readnone
300 define float @cos_test(float %x) {
301 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
302 ; CHECK-LABEL: @cos_test(
303 ; CHECK-NEXT:    [[C:%.*]] = call float @llvm.cos.f32(float [[X:%.*]])
304 ; CHECK-NEXT:    ret float [[C]]
306   %c = call float @llvm.cos(float %x)
307   ret float %c