Skip to content

Commit da9abaf

Browse files
committed
Add a SIL optimizer test that ensures we dont destroy atomics before use
1 parent d6824a7 commit da9abaf

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// RUN: %target-swift-frontend -O -emit-sil -disable-availability-checking %s | %FileCheck %s
2+
3+
// REQUIRES: synchronization
4+
5+
import Synchronization
6+
7+
//===----------------------------------------------------------------------===//
8+
// Ensure that we don't destroy the atomic before operations
9+
//===----------------------------------------------------------------------===//
10+
11+
// CHECK-LABEL: @localLoad
12+
// CHECK: [[ATOMIC:%.*]] = alloc_stack [lexical] $Atomic<Int>
13+
// CHECK: [[ATOMIC_PTR:%.*]] = address_to_pointer [[ATOMIC]] : $*Atomic<Int> to $Builtin.RawPointer
14+
// CHECK-NEXT: [[LOAD:%.*]] = builtin "atomicload_monotonic_Int64"([[ATOMIC_PTR]] : $Builtin.RawPointer) : $Builtin.Int64
15+
// CHECK-NEXT: [[INT:%.*]] = struct $Int ([[LOAD]] : $Builtin.Int64)
16+
// CHECK-NEXT: destroy_addr [[ATOMIC]] : $*Atomic<Int>
17+
// CHECK-NEXT: dealloc_stack [[ATOMIC]] : $*Atomic<Int>
18+
// CHECK-NEXT: return [[INT]] : $Int
19+
@_silgen_name("localLoad")
20+
func localLoad() -> Int {
21+
let x = Atomic(128)
22+
return x.load(ordering: .relaxed)
23+
}
24+
25+
// CHECK-LABEL: @localStore
26+
// CHECK: [[ATOMIC:%.*]] = alloc_stack [lexical] $Atomic<Int>
27+
// CHECK: [[STORE_INT:%.*]] = integer_literal $Builtin.Int64, 0
28+
// CHECK-NEXT: [[ATOMIC_PTR:%.*]] = address_to_pointer [[ATOMIC]] : $*Atomic<Int> to $Builtin.RawPointer
29+
// CHECK-NEXT: {{%.*}} = builtin "atomicstore_release_Int64"([[ATOMIC_PTR]] : $Builtin.RawPointer, [[STORE_INT]] : $Builtin.Int64) : $()
30+
// CHECK-NEXT: destroy_addr [[ATOMIC]] : $*Atomic<Int>
31+
// CHECK-NEXT: dealloc_stack [[ATOMIC]] : $*Atomic<Int>
32+
// CHECK: return {{%.*}} : $()
33+
@_silgen_name("localStore")
34+
func localStore() {
35+
let x = Atomic(128)
36+
x.store(0, ordering: .releasing)
37+
}
38+
39+
// CHECK-LABEL: @localExchange
40+
// CHECK: [[ATOMIC:%.*]] = alloc_stack [lexical] $Atomic<Int>
41+
// CHECK: [[EXCHANGE_INT:%.*]] = integer_literal $Builtin.Int64, 0
42+
// CHECK: [[ATOMIC_PTR:%.*]] = address_to_pointer [[ATOMIC]] : $*Atomic<Int> to $Builtin.RawPointer
43+
// CHECK-NEXT: [[LOAD:%.*]] = builtin "atomicrmw_xchg_acquire_Int64"([[ATOMIC_PTR]] : $Builtin.RawPointer, [[EXCHANGE_INT]] : $Builtin.Int64) : $Builtin.Int64
44+
// CHECK-NEXT: [[INT:%.*]] = struct $Int ([[LOAD]] : $Builtin.Int64)
45+
// CHECK-NEXT: destroy_addr [[ATOMIC]] : $*Atomic<Int>
46+
// CHECK-NEXT: dealloc_stack [[ATOMIC]] : $*Atomic<Int>
47+
// CHECK-NEXT: return [[INT]] : $Int
48+
@_silgen_name("localExchange")
49+
func localExchange() -> Int {
50+
let x = Atomic(128)
51+
return x.exchange(0, ordering: .acquiring)
52+
}
53+
54+
// CHECK-LABEL: @localCompareExchange
55+
// CHECK: [[ATOMIC:%.*]] = alloc_stack [lexical] $Atomic<Int>
56+
// CHECK-NEXT: [[EXPECTED_INT:%.*]] = integer_literal $Builtin.Int64, 128
57+
// CHECK: [[DESIRED_INT:%.*]] = integer_literal $Builtin.Int64, 316
58+
// CHECK-NEXT: [[ATOMIC_PTR:%.*]] = address_to_pointer [[ATOMIC]] : $*Atomic<Int> to $Builtin.RawPointer
59+
// CHECK-NEXT: [[CMPXCHG:%.*]] = builtin "cmpxchg_seqcst_seqcst_Int64"([[ATOMIC_PTR]] : $Builtin.RawPointer, [[EXPECTED_INT]] : $Builtin.Int64, [[DESIRED_INT]] : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1)
60+
// CHECK-NEXT: [[LOADED:%.*]] = tuple_extract [[CMPXCHG]] : $(Builtin.Int64, Builtin.Int1), 0
61+
// CHECK-NEXT: [[EXCHANGED:%.*]] = tuple_extract [[CMPXCHG]] : $(Builtin.Int64, Builtin.Int1), 1
62+
// CHECK-NEXT: [[BOOL:%.*]] = struct $Bool ([[EXCHANGED]] : $Builtin.Int1)
63+
// CHECK-NEXT: [[INT:%.*]] = struct $Int ([[LOADED]] : $Builtin.Int64)
64+
// CHECK-NEXT: destroy_addr [[ATOMIC]] : $*Atomic<Int>
65+
// CHECK-NEXT: dealloc_stack [[ATOMIC]] : $*Atomic<Int>
66+
// CHECK-NEXT: [[RETURN:%.*]] = tuple ([[BOOL]] : $Bool, [[INT]] : $Int)
67+
// CHECK-NEXT: return [[RETURN]] : $(Bool, Int)
68+
@_silgen_name("localCompareExchange")
69+
func localCompareExchange() -> (exchanged: Bool, original: Int) {
70+
let x = Atomic(128)
71+
return x.compareExchange(
72+
expected: 128,
73+
desired: 316,
74+
ordering: .sequentiallyConsistent
75+
)
76+
}

0 commit comments

Comments
 (0)