Do not treat atomic.load.sub differently than other atomic binary intrinsics.
[oota-llvm.git] / test / CodeGen / Mips / atomic.ll
1 ; RUN: llc -march=mipsel -mcpu=mips2 < %s | FileCheck %s
2
3
4 declare i32 @llvm.atomic.load.add.i32.p0i32(i32* nocapture, i32) nounwind
5 declare i32 @llvm.atomic.load.nand.i32.p0i32(i32* nocapture, i32) nounwind
6 declare i32 @llvm.atomic.swap.i32.p0i32(i32* nocapture, i32) nounwind
7 declare i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* nocapture, i32, i32) nounwind
8
9 declare i8 @llvm.atomic.load.add.i8.p0i8(i8* nocapture, i8) nounwind
10 declare i8 @llvm.atomic.load.sub.i8.p0i8(i8* nocapture, i8) nounwind
11 declare i8 @llvm.atomic.load.nand.i8.p0i8(i8* nocapture, i8) nounwind
12 declare i8 @llvm.atomic.swap.i8.p0i8(i8* nocapture, i8) nounwind
13 declare i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* nocapture, i8, i8) nounwind
14
15
16 @x = common global i32 0, align 4
17
18 define i32 @AtomicLoadAdd32(i32 %incr) nounwind {
19 entry:
20   %0 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* @x, i32 %incr)
21   ret i32 %0
22
23 ; CHECK:   AtomicLoadAdd32:
24 ; CHECK:   lw      $[[R0:[0-9]+]], %got(x)($gp)
25 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
26 ; CHECK:   ll      $[[R1:[0-9]+]], 0($[[R0]])
27 ; CHECK:   addu    $[[R2:[0-9]+]], $[[R1]], $4
28 ; CHECK:   sc      $[[R2]], 0($[[R0]])
29 ; CHECK:   beq     $[[R2]], $zero, $[[BB0]]
30 }
31
32 define i32 @AtomicLoadNand32(i32 %incr) nounwind {
33 entry:
34   %0 = call i32 @llvm.atomic.load.nand.i32.p0i32(i32* @x, i32 %incr)
35   ret i32 %0
36
37 ; CHECK:   AtomicLoadNand32:
38 ; CHECK:   lw      $[[R0:[0-9]+]], %got(x)($gp)
39 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
40 ; CHECK:   ll      $[[R1:[0-9]+]], 0($[[R0]])
41 ; CHECK:   and     $[[R3:[0-9]+]], $[[R1]], $4
42 ; CHECK:   nor     $[[R2:[0-9]+]], $zero, $[[R3]]
43 ; CHECK:   sc      $[[R2]], 0($[[R0]])
44 ; CHECK:   beq     $[[R2]], $zero, $[[BB0]]
45 }
46
47 define i32 @AtomicSwap32(i32 %newval) nounwind {
48 entry:
49   %newval.addr = alloca i32, align 4
50   store i32 %newval, i32* %newval.addr, align 4
51   %tmp = load i32* %newval.addr, align 4
52   %0 = call i32 @llvm.atomic.swap.i32.p0i32(i32* @x, i32 %tmp)
53   ret i32 %0
54
55 ; CHECK:   AtomicSwap32:
56 ; CHECK:   lw      $[[R0:[0-9]+]], %got(x)($gp)
57 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
58 ; CHECK:   ll      ${{[0-9]+}}, 0($[[R0]])
59 ; CHECK:   sc      $[[R2:[0-9]+]], 0($[[R0]])
60 ; CHECK:   beq     $[[R2]], $zero, $[[BB0]]
61 }
62
63 define i32 @AtomicCmpSwap32(i32 %oldval, i32 %newval) nounwind {
64 entry:
65   %newval.addr = alloca i32, align 4
66   store i32 %newval, i32* %newval.addr, align 4
67   %tmp = load i32* %newval.addr, align 4
68   %0 = call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* @x, i32 %oldval, i32 %tmp)
69   ret i32 %0
70
71 ; CHECK:   AtomicCmpSwap32:
72 ; CHECK:   lw      $[[R0:[0-9]+]], %got(x)($gp)
73 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
74 ; CHECK:   ll      $2, 0($[[R0]])
75 ; CHECK:   bne     $2, $4, $[[BB1:[A-Z_0-9]+]]
76 ; CHECK:   or      $[[R2:[0-9]+]], $zero, $5
77 ; CHECK:   sc      $[[R2]], 0($[[R0]])
78 ; CHECK:   beq     $[[R2]], $zero, $[[BB0]]
79 ; CHECK:   $[[BB1]]:
80 }
81
82
83
84 @y = common global i8 0, align 1
85
86 define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
87 entry:
88   %0 = call i8 @llvm.atomic.load.add.i8.p0i8(i8* @y, i8 %incr)
89   ret i8 %0
90
91 ; CHECK:   AtomicLoadAdd8:
92 ; CHECK:   lw      $[[R0:[0-9]+]], %got(y)($gp)
93 ; CHECK:   addiu   $[[R1:[0-9]+]], $zero, -4
94 ; CHECK:   and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
95 ; CHECK:   andi    $[[R3:[0-9]+]], $[[R0]], 3
96 ; CHECK:   sll     $[[R4:[0-9]+]], $[[R3]], 3
97 ; CHECK:   ori     $[[R5:[0-9]+]], $zero, 255
98 ; CHECK:   sll     $[[R6:[0-9]+]], $[[R5]], $[[R4]]
99 ; CHECK:   nor     $[[R7:[0-9]+]], $zero, $[[R6]]
100 ; CHECK:   andi    $[[R8:[0-9]+]], $4, 255
101 ; CHECK:   sll     $[[R9:[0-9]+]], $[[R8]], $[[R4]]
102
103 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
104 ; CHECK:   ll      $[[R10:[0-9]+]], 0($[[R2]])
105 ; CHECK:   addu    $[[R11:[0-9]+]], $[[R10]], $[[R9]]
106 ; CHECK:   and     $[[R12:[0-9]+]], $[[R11]], $[[R6]]
107 ; CHECK:   and     $[[R13:[0-9]+]], $[[R10]], $[[R7]]
108 ; CHECK:   or      $[[R14:[0-9]+]], $[[R13]], $[[R12]]
109 ; CHECK:   sc      $[[R14]], 0($[[R2]])
110 ; CHECK:   beq     $[[R14]], $zero, $[[BB0]]
111
112 ; CHECK:   and     $[[R15:[0-9]+]], $[[R10]], $[[R6]]
113 ; CHECK:   srl     $[[R16:[0-9]+]], $[[R15]], $[[R4]]
114 ; CHECK:   sll     $[[R17:[0-9]+]], $[[R16]], 24
115 ; CHECK:   sra     $2, $[[R17]], 24
116 }
117
118 define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
119 entry:
120   %0 = call i8 @llvm.atomic.load.sub.i8.p0i8(i8* @y, i8 %incr)
121   ret i8 %0
122
123 ; CHECK:   AtomicLoadSub8:
124 ; CHECK:   lw      $[[R0:[0-9]+]], %got(y)($gp)
125 ; CHECK:   addiu   $[[R1:[0-9]+]], $zero, -4
126 ; CHECK:   and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
127 ; CHECK:   andi    $[[R3:[0-9]+]], $[[R0]], 3
128 ; CHECK:   sll     $[[R4:[0-9]+]], $[[R3]], 3
129 ; CHECK:   ori     $[[R5:[0-9]+]], $zero, 255
130 ; CHECK:   sll     $[[R6:[0-9]+]], $[[R5]], $[[R4]]
131 ; CHECK:   nor     $[[R7:[0-9]+]], $zero, $[[R6]]
132 ; CHECK:   andi    $[[R8:[0-9]+]], $4, 255
133 ; CHECK:   sll     $[[R9:[0-9]+]], $[[R8]], $[[R4]]
134
135 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
136 ; CHECK:   ll      $[[R10:[0-9]+]], 0($[[R2]])
137 ; CHECK:   subu    $[[R11:[0-9]+]], $[[R10]], $[[R9]]
138 ; CHECK:   and     $[[R12:[0-9]+]], $[[R11]], $[[R6]]
139 ; CHECK:   and     $[[R13:[0-9]+]], $[[R10]], $[[R7]]
140 ; CHECK:   or      $[[R14:[0-9]+]], $[[R13]], $[[R12]]
141 ; CHECK:   sc      $[[R14]], 0($[[R2]])
142 ; CHECK:   beq     $[[R14]], $zero, $[[BB0]]
143
144 ; CHECK:   and     $[[R15:[0-9]+]], $[[R10]], $[[R6]]
145 ; CHECK:   srl     $[[R16:[0-9]+]], $[[R15]], $[[R4]]
146 ; CHECK:   sll     $[[R17:[0-9]+]], $[[R16]], 24
147 ; CHECK:   sra     $2, $[[R17]], 24
148 }
149
150 define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
151 entry:
152   %0 = call i8 @llvm.atomic.load.nand.i8.p0i8(i8* @y, i8 %incr)
153   ret i8 %0
154
155 ; CHECK:   AtomicLoadNand8:
156 ; CHECK:   lw      $[[R0:[0-9]+]], %got(y)($gp)
157 ; CHECK:   addiu   $[[R1:[0-9]+]], $zero, -4
158 ; CHECK:   and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
159 ; CHECK:   andi    $[[R3:[0-9]+]], $[[R0]], 3
160 ; CHECK:   sll     $[[R4:[0-9]+]], $[[R3]], 3
161 ; CHECK:   ori     $[[R5:[0-9]+]], $zero, 255
162 ; CHECK:   sll     $[[R6:[0-9]+]], $[[R5]], $[[R4]]
163 ; CHECK:   nor     $[[R7:[0-9]+]], $zero, $[[R6]]
164 ; CHECK:   andi    $[[R8:[0-9]+]], $4, 255
165 ; CHECK:   sll     $[[R9:[0-9]+]], $[[R8]], $[[R4]]
166
167 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
168 ; CHECK:   ll      $[[R10:[0-9]+]], 0($[[R2]])
169 ; CHECK:   and     $[[R18:[0-9]+]], $[[R10]], $[[R9]]
170 ; CHECK:   nor     $[[R11:[0-9]+]], $zero, $[[R18]]
171 ; CHECK:   and     $[[R12:[0-9]+]], $[[R11]], $[[R6]]
172 ; CHECK:   and     $[[R13:[0-9]+]], $[[R10]], $[[R7]]
173 ; CHECK:   or      $[[R14:[0-9]+]], $[[R13]], $[[R12]]
174 ; CHECK:   sc      $[[R14]], 0($[[R2]])
175 ; CHECK:   beq     $[[R14]], $zero, $[[BB0]]
176
177 ; CHECK:   and     $[[R15:[0-9]+]], $[[R10]], $[[R6]]
178 ; CHECK:   srl     $[[R16:[0-9]+]], $[[R15]], $[[R4]]
179 ; CHECK:   sll     $[[R17:[0-9]+]], $[[R16]], 24
180 ; CHECK:   sra     $2, $[[R17]], 24
181 }
182
183 define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
184 entry:
185   %0 = call i8 @llvm.atomic.swap.i8.p0i8(i8* @y, i8 %newval)
186   ret i8 %0
187
188 ; CHECK:   AtomicSwap8:
189 ; CHECK:   lw      $[[R0:[0-9]+]], %got(y)($gp)
190 ; CHECK:   addiu   $[[R1:[0-9]+]], $zero, -4
191 ; CHECK:   and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
192 ; CHECK:   andi    $[[R3:[0-9]+]], $[[R0]], 3
193 ; CHECK:   sll     $[[R4:[0-9]+]], $[[R3]], 3
194 ; CHECK:   ori     $[[R5:[0-9]+]], $zero, 255
195 ; CHECK:   sll     $[[R6:[0-9]+]], $[[R5]], $[[R4]]
196 ; CHECK:   nor     $[[R7:[0-9]+]], $zero, $[[R6]]
197 ; CHECK:   andi    $[[R8:[0-9]+]], $4, 255
198 ; CHECK:   sll     $[[R9:[0-9]+]], $[[R8]], $[[R4]]
199
200 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
201 ; CHECK:   ll      $[[R10:[0-9]+]], 0($[[R2]])
202 ; CHECK:   and     $[[R13:[0-9]+]], $[[R10]], $[[R7]]
203 ; CHECK:   or      $[[R14:[0-9]+]], $[[R13]], $[[R9]]
204 ; CHECK:   sc      $[[R14]], 0($[[R2]])
205 ; CHECK:   beq     $[[R14]], $zero, $[[BB0]]
206
207 ; CHECK:   and     $[[R15:[0-9]+]], $[[R10]], $[[R6]]
208 ; CHECK:   srl     $[[R16:[0-9]+]], $[[R15]], $[[R4]]
209 ; CHECK:   sll     $[[R17:[0-9]+]], $[[R16]], 24
210 ; CHECK:   sra     $2, $[[R17]], 24
211 }
212
213 define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind {
214 entry:
215   %0 = call i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* @y, i8 %oldval, i8 %newval)
216   ret i8 %0
217
218 ; CHECK:   AtomicCmpSwap8:
219 ; CHECK:   lw      $[[R0:[0-9]+]], %got(y)($gp)
220 ; CHECK:   addiu   $[[R1:[0-9]+]], $zero, -4
221 ; CHECK:   and     $[[R2:[0-9]+]], $[[R0]], $[[R1]]
222 ; CHECK:   andi    $[[R3:[0-9]+]], $[[R0]], 3
223 ; CHECK:   sll     $[[R4:[0-9]+]], $[[R3]], 3
224 ; CHECK:   ori     $[[R5:[0-9]+]], $zero, 255
225 ; CHECK:   sll     $[[R6:[0-9]+]], $[[R5]], $[[R4]]
226 ; CHECK:   nor     $[[R7:[0-9]+]], $zero, $[[R6]]
227 ; CHECK:   andi    $[[R8:[0-9]+]], $4, 255
228 ; CHECK:   sll     $[[R9:[0-9]+]], $[[R8]], $[[R4]]
229 ; CHECK:   andi    $[[R10:[0-9]+]], $5, 255
230 ; CHECK:   sll     $[[R11:[0-9]+]], $[[R10]], $[[R4]]
231
232 ; CHECK:   $[[BB0:[A-Z_0-9]+]]:
233 ; CHECK:   ll      $[[R12:[0-9]+]], 0($[[R2]])
234 ; CHECK:   and     $[[R13:[0-9]+]], $[[R12]], $[[R6]]
235 ; CHECK:   bne     $[[R13]], $[[R9]], $[[BB1:[A-Z_0-9]+]]
236
237 ; CHECK:   and     $[[R14:[0-9]+]], $[[R12]], $[[R7]]
238 ; CHECK:   or      $[[R15:[0-9]+]], $[[R14]], $[[R11]]
239 ; CHECK:   sc      $[[R15]], 0($[[R2]])
240 ; CHECK:   beq     $[[R15]], $zero, $[[BB0]]
241
242 ; CHECK:   $[[BB1]]:
243 ; CHECK:   srl     $[[R16:[0-9]+]], $[[R13]], $[[R4]]
244 ; CHECK:   sll     $[[R17:[0-9]+]], $[[R16]], 24
245 ; CHECK:   sra     $2, $[[R17]], 24
246 }