ea85a86fa911bc93c8fcc20c6f0bd041021674d5
[oota-llvm.git] / test / Transforms / EarlyCSE / atomics.ll
1 ; RUN: opt < %s -S -early-cse | FileCheck %s
2
3 ; CHECK-LABEL: @test12(
4 define i32 @test12(i1 %B, i32* %P1, i32* %P2) {
5   %load0 = load i32, i32* %P1
6   %1 = load atomic i32, i32* %P2 seq_cst, align 4
7   %load1 = load i32, i32* %P1
8   %sel = select i1 %B, i32 %load0, i32 %load1
9   ret i32 %sel
10   ; CHECK: load i32, i32* %P1
11   ; CHECK: load i32, i32* %P1
12 }
13
14 ; CHECK-LABEL: @test13(
15 ; atomic to non-atomic forwarding is legal
16 define i32 @test13(i1 %B, i32* %P1) {
17   %a = load atomic i32, i32* %P1 seq_cst, align 4
18   %b = load i32, i32* %P1
19   %res = sub i32 %a, %b
20   ret i32 %res
21   ; CHECK: load atomic i32, i32* %P1
22   ; CHECK: ret i32 0
23 }
24
25 ; CHECK-LABEL: @test14(
26 ; atomic to unordered atomic forwarding is legal
27 define i32 @test14(i1 %B, i32* %P1) {
28   %a = load atomic i32, i32* %P1 seq_cst, align 4
29   %b = load atomic i32, i32* %P1 unordered, align 4
30   %res = sub i32 %a, %b
31   ret i32 %res
32   ; CHECK: load atomic i32, i32* %P1 seq_cst
33   ; CHECK-NEXT: ret i32 0
34 }
35
36 ; CHECK-LABEL: @test15(
37 ; implementation restriction: can't forward to stonger
38 ; than unordered
39 define i32 @test15(i1 %B, i32* %P1, i32* %P2) {
40   %a = load atomic i32, i32* %P1 seq_cst, align 4
41   %b = load atomic i32, i32* %P1 seq_cst, align 4
42   %res = sub i32 %a, %b
43   ret i32 %res
44   ; CHECK: load atomic i32, i32* %P1
45   ; CHECK: load atomic i32, i32* %P1
46 }
47
48 ; CHECK-LABEL: @test16(
49 ; forwarding non-atomic to atomic is wrong! (However,
50 ; it would be legal to use the later value in place of the
51 ; former in this particular example.  We just don't
52 ; do that right now.)
53 define i32 @test16(i1 %B, i32* %P1, i32* %P2) {
54   %a = load i32, i32* %P1, align 4
55   %b = load atomic i32, i32* %P1 unordered, align 4
56   %res = sub i32 %a, %b
57   ret i32 %res
58   ; CHECK: load i32, i32* %P1
59   ; CHECK: load atomic i32, i32* %P1
60 }
61
62 ; Can't DSE across a full fence
63 define void @fence_seq_cst_store(i1 %B, i32* %P1, i32* %P2) {
64 ; CHECK-LABEL: @fence_seq_cst_store
65 ; CHECK: store
66 ; CHECK: store atomic
67 ; CHECK: store
68   store i32 0, i32* %P1, align 4
69   store atomic i32 0, i32* %P2 seq_cst, align 4
70   store i32 0, i32* %P1, align 4
71   ret void
72 }
73
74 ; Can't DSE across a full fence
75 define void @fence_seq_cst(i1 %B, i32* %P1, i32* %P2) {
76 ; CHECK-LABEL: @fence_seq_cst
77 ; CHECK: store
78 ; CHECK: fence seq_cst
79 ; CHECK: store
80   store i32 0, i32* %P1, align 4
81   fence seq_cst
82   store i32 0, i32* %P1, align 4
83   ret void
84 }
85
86 ; Can't DSE across a full fence
87 define void @fence_asm_sideeffect(i1 %B, i32* %P1, i32* %P2) {
88 ; CHECK-LABEL: @fence_asm_sideeffect
89 ; CHECK: store
90 ; CHECK: call void asm sideeffect
91 ; CHECK: store
92   store i32 0, i32* %P1, align 4
93   call void asm sideeffect "", ""()
94   store i32 0, i32* %P1, align 4
95   ret void
96 }
97
98 ; Can't DSE across a full fence
99 define void @fence_asm_memory(i1 %B, i32* %P1, i32* %P2) {
100 ; CHECK-LABEL: @fence_asm_memory
101 ; CHECK: store
102 ; CHECK: call void asm
103 ; CHECK: store
104   store i32 0, i32* %P1, align 4
105   call void asm "", "~{memory}"()
106   store i32 0, i32* %P1, align 4
107   ret void
108 }
109
110 ; Can't remove a volatile load
111 define i32 @volatile_load(i1 %B, i32* %P1, i32* %P2) {
112   %a = load i32, i32* %P1, align 4
113   %b = load volatile i32, i32* %P1, align 4
114   %res = sub i32 %a, %b
115   ret i32 %res
116   ; CHECK-LABEL: @volatile_load
117   ; CHECK: load i32, i32* %P1
118   ; CHECK: load volatile i32, i32* %P1
119 }
120
121 ; Can't remove redundant volatile loads
122 define i32 @redundant_volatile_load(i1 %B, i32* %P1, i32* %P2) {
123   %a = load volatile i32, i32* %P1, align 4
124   %b = load volatile i32, i32* %P1, align 4
125   %res = sub i32 %a, %b
126   ret i32 %res
127   ; CHECK-LABEL: @redundant_volatile_load
128   ; CHECK: load volatile i32, i32* %P1
129   ; CHECK: load volatile i32, i32* %P1
130   ; CHECK: sub
131 }
132
133 ; Can't DSE a volatile store
134 define void @volatile_store(i1 %B, i32* %P1, i32* %P2) {
135 ; CHECK-LABEL: @volatile_store
136 ; CHECK: store volatile
137 ; CHECK: store
138   store volatile i32 0, i32* %P1, align 4
139   store i32 3, i32* %P1, align 4
140   ret void
141 }
142
143 ; Can't DSE a redundant volatile store
144 define void @redundant_volatile_store(i1 %B, i32* %P1, i32* %P2) {
145 ; CHECK-LABEL: @redundant_volatile_store
146 ; CHECK: store volatile
147 ; CHECK: store volatile
148   store volatile i32 0, i32* %P1, align 4
149   store volatile i32 0, i32* %P1, align 4
150   ret void
151 }
152
153 ; Can value forward from volatiles
154 define i32 @test20(i1 %B, i32* %P1, i32* %P2) {
155   %a = load volatile i32, i32* %P1, align 4
156   %b = load i32, i32* %P1, align 4
157   %res = sub i32 %a, %b
158   ret i32 %res
159   ; CHECK-LABEL: @test20
160   ; CHECK: load volatile i32, i32* %P1
161   ; CHECK: ret i32 0
162 }
163
164 ; Can DSE a non-volatile store in favor of a volatile one
165 ; currently a missed optimization
166 define void @test21(i1 %B, i32* %P1, i32* %P2) {
167 ; CHECK-LABEL: @test21
168 ; CHECK: store 
169 ; CHECK: store volatile
170   store i32 0, i32* %P1, align 4
171   store volatile i32 3, i32* %P1, align 4
172   ret void
173 }
174
175 ; Can DSE a normal store in favor of a unordered one
176 define void @test22(i1 %B, i32* %P1, i32* %P2) {
177 ; CHECK-LABEL: @test22
178 ; CHECK-NEXT: store atomic
179   store i32 0, i32* %P1, align 4
180   store atomic i32 3, i32* %P1 unordered, align 4
181   ret void
182 }
183
184
185