blob: 4d2cb37f25872cdc118229a4e44aeeca598d19ff [file] [log] [blame]
Eli Friedman9a468152011-08-17 22:22:24 +00001; RUN: opt -basicaa -dse -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
Robin Morisset163ef042014-08-29 20:32:58 +00008; atomic ops, just some transformations are not allowed across release-acquire pairs.
Eli Friedman9a468152011-08-17 22:22:24 +00009
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)
Robin Morisset163ef042014-08-29 20:32:58 +000016define void @test1() {
17; CHECK-LABEL: test1
Eli Friedman9a468152011-08-17 22:22:24 +000018; CHECK-NOT: store i32 0
19; CHECK: store i32 1
Eli Friedman9a468152011-08-17 22:22:24 +000020 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
Robin Morisset163ef042014-08-29 20:32:58 +000026; DSE across seq_cst load (allowed)
27define i32 @test2() {
28; CHECK-LABEL: test2
29; CHECK-NOT: store i32 0
Eli Friedman9a468152011-08-17 22:22:24 +000030; CHECK: store i32 1
Eli Friedman9a468152011-08-17 22:22:24 +000031 store i32 0, i32* @x
David Blaikiea79ac142015-02-27 21:17:42 +000032 %x = load atomic i32, i32* @y seq_cst, align 4
Eli Friedman9a468152011-08-17 22:22:24 +000033 store i32 1, i32* @x
34 ret i32 %x
35}
36
Robin Morisset163ef042014-08-29 20:32:58 +000037; DSE across seq_cst store (allowed)
38define void @test3() {
39; CHECK-LABEL: test3
40; CHECK-NOT: store i32 0
Eli Friedman9a468152011-08-17 22:22:24 +000041; CHECK: store atomic i32 2
Eli Friedman9a468152011-08-17 22:22:24 +000042 store i32 0, i32* @x
43 store atomic i32 2, i32* @y seq_cst, align 4
44 store i32 1, i32* @x
45 ret void
46}
47
48; DSE remove unordered store (allowed)
Robin Morisset163ef042014-08-29 20:32:58 +000049define void @test4() {
50; CHECK-LABEL: test4
Eli Friedman9a468152011-08-17 22:22:24 +000051; CHECK-NOT: store atomic
52; CHECK: store i32 1
Eli Friedman9a468152011-08-17 22:22:24 +000053 store atomic i32 0, i32* @x unordered, align 4
54 store i32 1, i32* @x
55 ret void
56}
57
58; DSE unordered store overwriting non-atomic store (allowed)
Robin Morisset163ef042014-08-29 20:32:58 +000059define void @test5() {
60; CHECK-LABEL: test5
Eli Friedman9a468152011-08-17 22:22:24 +000061; CHECK: store atomic i32 1
Eli Friedman9a468152011-08-17 22:22:24 +000062 store i32 0, i32* @x
63 store atomic i32 1, i32* @x unordered, align 4
64 ret void
65}
66
67; DSE no-op unordered atomic store (allowed)
Robin Morisset163ef042014-08-29 20:32:58 +000068define void @test6() {
69; CHECK-LABEL: test6
Eli Friedman9a468152011-08-17 22:22:24 +000070; CHECK-NOT: store
71; CHECK: ret void
David Blaikiea79ac142015-02-27 21:17:42 +000072 %x = load atomic i32, i32* @x unordered, align 4
Eli Friedman9a468152011-08-17 22:22:24 +000073 store atomic i32 %x, i32* @x unordered, align 4
74 ret void
75}
76
77; DSE seq_cst store (be conservative; DSE doesn't have infrastructure
78; to reason about atomic operations).
Robin Morisset163ef042014-08-29 20:32:58 +000079define void @test7() {
80; CHECK-LABEL: test7
81; CHECK: store atomic
Eli Friedman9a468152011-08-17 22:22:24 +000082 %a = alloca i32
83 store atomic i32 0, i32* %a seq_cst, align 4
84 ret void
85}
86
87; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure
88; to reason about atomic operations).
Robin Morisset163ef042014-08-29 20:32:58 +000089define i32 @test8() {
90; CHECK-LABEL: test8
Eli Friedman9a468152011-08-17 22:22:24 +000091; CHECK: store
Robin Morisset163ef042014-08-29 20:32:58 +000092; CHECK: load atomic
Eli Friedman9a468152011-08-17 22:22:24 +000093 %a = alloca i32
94 call void @randomop(i32* %a)
95 store i32 0, i32* %a, align 4
David Blaikiea79ac142015-02-27 21:17:42 +000096 %x = load atomic i32, i32* @x seq_cst, align 4
Eli Friedman9a468152011-08-17 22:22:24 +000097 ret i32 %x
98}
99
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000100; DSE across monotonic load (allowed as long as the eliminated store isUnordered)
Robin Morisset163ef042014-08-29 20:32:58 +0000101define i32 @test9() {
102; CHECK-LABEL: test9
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000103; CHECK-NOT: store i32 0
104; CHECK: store i32 1
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000105 store i32 0, i32* @x
David Blaikiea79ac142015-02-27 21:17:42 +0000106 %x = load atomic i32, i32* @y monotonic, align 4
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000107 store i32 1, i32* @x
108 ret i32 %x
109}
110
111; DSE across monotonic store (allowed as long as the eliminated store isUnordered)
Robin Morisset163ef042014-08-29 20:32:58 +0000112define void @test10() {
113; CHECK-LABEL: test10
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000114; CHECK-NOT: store i32 0
115; CHECK: store i32 1
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000116 store i32 0, i32* @x
117 store atomic i32 42, i32* @y monotonic, align 4
118 store i32 1, i32* @x
119 ret void
120}
121
122; DSE across monotonic load (forbidden since the eliminated store is atomic)
Robin Morisset163ef042014-08-29 20:32:58 +0000123define i32 @test11() {
124; CHECK-LABEL: test11
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000125; CHECK: store atomic i32 0
126; CHECK: store atomic i32 1
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000127 store atomic i32 0, i32* @x monotonic, align 4
David Blaikiea79ac142015-02-27 21:17:42 +0000128 %x = load atomic i32, i32* @y monotonic, align 4
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000129 store atomic i32 1, i32* @x monotonic, align 4
130 ret i32 %x
131}
132
133; DSE across monotonic store (forbidden since the eliminated store is atomic)
Robin Morisset163ef042014-08-29 20:32:58 +0000134define void @test12() {
135; CHECK-LABEL: test12
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000136; CHECK: store atomic i32 0
137; CHECK: store atomic i32 1
Robin Morisset4ffe8aa2014-08-18 22:18:11 +0000138 store atomic i32 0, i32* @x monotonic, align 4
139 store atomic i32 42, i32* @y monotonic, align 4
140 store atomic i32 1, i32* @x monotonic, align 4
141 ret void
142}
Robin Morisset163ef042014-08-29 20:32:58 +0000143
144; DSE is allowed across a pair of an atomic read and then write.
145define i32 @test13() {
146; CHECK-LABEL: test13
147; CHECK-NOT: store i32 0
148; CHECK: store i32 1
149 store i32 0, i32* @x
David Blaikiea79ac142015-02-27 21:17:42 +0000150 %x = load atomic i32, i32* @y seq_cst, align 4
Robin Morisset163ef042014-08-29 20:32:58 +0000151 store atomic i32 %x, i32* @y seq_cst, align 4
152 store i32 1, i32* @x
153 ret i32 %x
154}
155
156; Same if it is acquire-release instead of seq_cst/seq_cst
157define i32 @test14() {
158; CHECK-LABEL: test14
159; CHECK-NOT: store i32 0
160; CHECK: store i32 1
161 store i32 0, i32* @x
David Blaikiea79ac142015-02-27 21:17:42 +0000162 %x = load atomic i32, i32* @y acquire, align 4
Robin Morisset163ef042014-08-29 20:32:58 +0000163 store atomic i32 %x, i32* @y release, align 4
164 store i32 1, i32* @x
165 ret i32 %x
166}
167
168; But DSE is not allowed across a release-acquire pair.
169define i32 @test15() {
170; CHECK-LABEL: test15
171; CHECK: store i32 0
172; CHECK: store i32 1
173 store i32 0, i32* @x
174 store atomic i32 0, i32* @y release, align 4
David Blaikiea79ac142015-02-27 21:17:42 +0000175 %x = load atomic i32, i32* @y acquire, align 4
Robin Morisset163ef042014-08-29 20:32:58 +0000176 store i32 1, i32* @x
177 ret i32 %x
178}