1; RUN: opt -basic-aa -dse -enable-dse-memoryssa=false -S < %s | FileCheck %s
2
3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
4target triple = "x86_64-apple-macosx10.7.0"
5
6; Sanity tests for atomic stores.
7; Note that it turns out essentially every transformation DSE does is legal on
8; atomic ops, just some transformations are not allowed across release-acquire pairs.
9
10@x = common global i32 0, align 4
11@y = common global i32 0, align 4
12
13declare void @randomop(i32*)
14
15; DSE across unordered store (allowed)
16define void @test1() {
17; CHECK-LABEL: test1
18; CHECK-NOT: store i32 0
19; CHECK: store i32 1
20  store i32 0, i32* @x
21  store atomic i32 0, i32* @y unordered, align 4
22  store i32 1, i32* @x
23  ret void
24}
25
26; DSE remove unordered store (allowed)
27define void @test4() {
28; CHECK-LABEL: test4
29; CHECK-NOT: store atomic
30; CHECK: store i32 1
31  store atomic i32 0, i32* @x unordered, align 4
32  store i32 1, i32* @x
33  ret void
34}
35
36; DSE unordered store overwriting non-atomic store (allowed)
37define void @test5() {
38; CHECK-LABEL: test5
39; CHECK: store atomic i32 1
40  store i32 0, i32* @x
41  store atomic i32 1, i32* @x unordered, align 4
42  ret void
43}
44
45; DSE no-op unordered atomic store (allowed)
46define void @test6() {
47; CHECK-LABEL: test6
48; CHECK-NOT: store
49; CHECK: ret void
50  %x = load atomic i32, i32* @x unordered, align 4
51  store atomic i32 %x, i32* @x unordered, align 4
52  ret void
53}
54
55; DSE seq_cst store (be conservative; DSE doesn't have infrastructure
56; to reason about atomic operations).
57define void @test7() {
58; CHECK-LABEL: test7
59; CHECK: store atomic
60  %a = alloca i32
61  store atomic i32 0, i32* %a seq_cst, align 4
62  ret void
63}
64
65; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure
66; to reason about atomic operations).
67define i32 @test8() {
68; CHECK-LABEL: test8
69; CHECK: store
70; CHECK: load atomic
71  %a = alloca i32
72  call void @randomop(i32* %a)
73  store i32 0, i32* %a, align 4
74  %x = load atomic i32, i32* @x seq_cst, align 4
75  ret i32 %x
76}
77
78; DSE across monotonic load (allowed as long as the eliminated store isUnordered)
79define i32 @test9() {
80; CHECK-LABEL: test9
81; CHECK-NOT: store i32 0
82; CHECK: store i32 1
83  store i32 0, i32* @x
84  %x = load atomic i32, i32* @y monotonic, align 4
85  store i32 1, i32* @x
86  ret i32 %x
87}
88
89; DSE across monotonic store (allowed as long as the eliminated store isUnordered)
90define void @test10() {
91; CHECK-LABEL: test10
92; CHECK-NOT: store i32 0
93; CHECK: store i32 1
94  store i32 0, i32* @x
95  store atomic i32 42, i32* @y monotonic, align 4
96  store i32 1, i32* @x
97  ret void
98}
99
100; DSE across monotonic load (forbidden since the eliminated store is atomic)
101define i32 @test11() {
102; CHECK-LABEL: test11
103; CHECK: store atomic i32 0
104; CHECK: store atomic i32 1
105  store atomic i32 0, i32* @x monotonic, align 4
106  %x = load atomic i32, i32* @y monotonic, align 4
107  store atomic i32 1, i32* @x monotonic, align 4
108  ret i32 %x
109}
110
111; DSE across monotonic store (forbidden since the eliminated store is atomic)
112define void @test12() {
113; CHECK-LABEL: test12
114; CHECK: store atomic i32 0
115; CHECK: store atomic i32 1
116  store atomic i32 0, i32* @x monotonic, align 4
117  store atomic i32 42, i32* @y monotonic, align 4
118  store atomic i32 1, i32* @x monotonic, align 4
119  ret void
120}
121
122; But DSE is not allowed across a release-acquire pair.
123define i32 @test15() {
124; CHECK-LABEL: test15
125; CHECK: store i32 0
126; CHECK: store i32 1
127  store i32 0, i32* @x
128  store atomic i32 0, i32* @y release, align 4
129  %x = load atomic i32, i32* @y acquire, align 4
130  store i32 1, i32* @x
131  ret i32 %x
132}
133