blob: 050689dcea6c3f5d557df10817b1e948d0c03b04 [file] [log] [blame]
Akira Hatanaka8ddf6532011-09-09 20:45:50 +00001; RUN: llc -march=mipsel < %s | FileCheck %s
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +00002
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +00003@x = common global i32 0, align 4
4
5define i32 @AtomicLoadAdd32(i32 %incr) nounwind {
6entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +00007 %0 = atomicrmw add i32* @x, i32 %incr monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +00008 ret i32 %0
9
10; CHECK: AtomicLoadAdd32:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +000011; CHECK: lw $[[R0:[0-9]+]], %got(x)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000012; CHECK: $[[BB0:[A-Z_0-9]+]]:
13; CHECK: ll $[[R1:[0-9]+]], 0($[[R0]])
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000014; CHECK: addu $[[R2:[0-9]+]], $[[R1]], $4
15; CHECK: sc $[[R2]], 0($[[R0]])
16; CHECK: beq $[[R2]], $zero, $[[BB0]]
17}
18
19define i32 @AtomicLoadNand32(i32 %incr) nounwind {
20entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +000021 %0 = atomicrmw nand i32* @x, i32 %incr monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000022 ret i32 %0
23
24; CHECK: AtomicLoadNand32:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +000025; CHECK: lw $[[R0:[0-9]+]], %got(x)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000026; CHECK: $[[BB0:[A-Z_0-9]+]]:
27; CHECK: ll $[[R1:[0-9]+]], 0($[[R0]])
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +000028; CHECK: and $[[R3:[0-9]+]], $[[R1]], $4
29; CHECK: nor $[[R2:[0-9]+]], $zero, $[[R3]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000030; CHECK: sc $[[R2]], 0($[[R0]])
31; CHECK: beq $[[R2]], $zero, $[[BB0]]
32}
33
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +000034define i32 @AtomicSwap32(i32 %newval) nounwind {
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000035entry:
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +000036 %newval.addr = alloca i32, align 4
37 store i32 %newval, i32* %newval.addr, align 4
38 %tmp = load i32* %newval.addr, align 4
Eli Friedmanad2d46d2011-09-26 20:27:49 +000039 %0 = atomicrmw xchg i32* @x, i32 %tmp monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000040 ret i32 %0
41
42; CHECK: AtomicSwap32:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +000043; CHECK: lw $[[R0:[0-9]+]], %got(x)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000044; CHECK: $[[BB0:[A-Z_0-9]+]]:
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +000045; CHECK: ll ${{[0-9]+}}, 0($[[R0]])
46; CHECK: sc $[[R2:[0-9]+]], 0($[[R0]])
47; CHECK: beq $[[R2]], $zero, $[[BB0]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000048}
49
50define i32 @AtomicCmpSwap32(i32 %oldval, i32 %newval) nounwind {
51entry:
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +000052 %newval.addr = alloca i32, align 4
53 store i32 %newval, i32* %newval.addr, align 4
54 %tmp = load i32* %newval.addr, align 4
Eli Friedmanad2d46d2011-09-26 20:27:49 +000055 %0 = cmpxchg i32* @x, i32 %oldval, i32 %tmp monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000056 ret i32 %0
57
58; CHECK: AtomicCmpSwap32:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +000059; CHECK: lw $[[R0:[0-9]+]], %got(x)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000060; CHECK: $[[BB0:[A-Z_0-9]+]]:
61; CHECK: ll $2, 0($[[R0]])
62; CHECK: bne $2, $4, $[[BB1:[A-Z_0-9]+]]
Akira Hatanaka70564a92011-07-19 18:14:26 +000063; CHECK: sc $[[R2:[0-9]+]], 0($[[R0]])
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000064; CHECK: beq $[[R2]], $zero, $[[BB0]]
65; CHECK: $[[BB1]]:
66}
67
68
69
70@y = common global i8 0, align 1
71
72define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
73entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +000074 %0 = atomicrmw add i8* @y, i8 %incr monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000075 ret i8 %0
76
77; CHECK: AtomicLoadAdd8:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +000078; CHECK: lw $[[R0:[0-9]+]], %got(y)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000079; CHECK: addiu $[[R1:[0-9]+]], $zero, -4
80; CHECK: and $[[R2:[0-9]+]], $[[R0]], $[[R1]]
81; CHECK: andi $[[R3:[0-9]+]], $[[R0]], 3
82; CHECK: sll $[[R4:[0-9]+]], $[[R3]], 3
83; CHECK: ori $[[R5:[0-9]+]], $zero, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +000084; CHECK: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000085; CHECK: nor $[[R7:[0-9]+]], $zero, $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +000086; CHECK: sllv $[[R9:[0-9]+]], $4, $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000087
88; CHECK: $[[BB0:[A-Z_0-9]+]]:
89; CHECK: ll $[[R10:[0-9]+]], 0($[[R2]])
90; CHECK: addu $[[R11:[0-9]+]], $[[R10]], $[[R9]]
91; CHECK: and $[[R12:[0-9]+]], $[[R11]], $[[R6]]
92; CHECK: and $[[R13:[0-9]+]], $[[R10]], $[[R7]]
93; CHECK: or $[[R14:[0-9]+]], $[[R13]], $[[R12]]
94; CHECK: sc $[[R14]], 0($[[R2]])
95; CHECK: beq $[[R14]], $zero, $[[BB0]]
96
97; CHECK: and $[[R15:[0-9]+]], $[[R10]], $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +000098; CHECK: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +000099; CHECK: sll $[[R17:[0-9]+]], $[[R16]], 24
100; CHECK: sra $2, $[[R17]], 24
101}
102
103define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
104entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +0000105 %0 = atomicrmw sub i8* @y, i8 %incr monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000106 ret i8 %0
107
108; CHECK: AtomicLoadSub8:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +0000109; CHECK: lw $[[R0:[0-9]+]], %got(y)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000110; CHECK: addiu $[[R1:[0-9]+]], $zero, -4
111; CHECK: and $[[R2:[0-9]+]], $[[R0]], $[[R1]]
112; CHECK: andi $[[R3:[0-9]+]], $[[R0]], 3
113; CHECK: sll $[[R4:[0-9]+]], $[[R3]], 3
114; CHECK: ori $[[R5:[0-9]+]], $zero, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000115; CHECK: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000116; CHECK: nor $[[R7:[0-9]+]], $zero, $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000117; CHECK: sllv $[[R9:[0-9]+]], $4, $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000118
119; CHECK: $[[BB0:[A-Z_0-9]+]]:
120; CHECK: ll $[[R10:[0-9]+]], 0($[[R2]])
Akira Hatanakaa9211642011-07-18 19:58:59 +0000121; CHECK: subu $[[R11:[0-9]+]], $[[R10]], $[[R9]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000122; CHECK: and $[[R12:[0-9]+]], $[[R11]], $[[R6]]
123; CHECK: and $[[R13:[0-9]+]], $[[R10]], $[[R7]]
124; CHECK: or $[[R14:[0-9]+]], $[[R13]], $[[R12]]
125; CHECK: sc $[[R14]], 0($[[R2]])
126; CHECK: beq $[[R14]], $zero, $[[BB0]]
127
128; CHECK: and $[[R15:[0-9]+]], $[[R10]], $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000129; CHECK: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000130; CHECK: sll $[[R17:[0-9]+]], $[[R16]], 24
131; CHECK: sra $2, $[[R17]], 24
132}
133
134define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
135entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +0000136 %0 = atomicrmw nand i8* @y, i8 %incr monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000137 ret i8 %0
138
139; CHECK: AtomicLoadNand8:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +0000140; CHECK: lw $[[R0:[0-9]+]], %got(y)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000141; CHECK: addiu $[[R1:[0-9]+]], $zero, -4
142; CHECK: and $[[R2:[0-9]+]], $[[R0]], $[[R1]]
143; CHECK: andi $[[R3:[0-9]+]], $[[R0]], 3
144; CHECK: sll $[[R4:[0-9]+]], $[[R3]], 3
145; CHECK: ori $[[R5:[0-9]+]], $zero, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000146; CHECK: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000147; CHECK: nor $[[R7:[0-9]+]], $zero, $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000148; CHECK: sllv $[[R9:[0-9]+]], $4, $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000149
150; CHECK: $[[BB0:[A-Z_0-9]+]]:
151; CHECK: ll $[[R10:[0-9]+]], 0($[[R2]])
152; CHECK: and $[[R18:[0-9]+]], $[[R10]], $[[R9]]
153; CHECK: nor $[[R11:[0-9]+]], $zero, $[[R18]]
154; CHECK: and $[[R12:[0-9]+]], $[[R11]], $[[R6]]
155; CHECK: and $[[R13:[0-9]+]], $[[R10]], $[[R7]]
156; CHECK: or $[[R14:[0-9]+]], $[[R13]], $[[R12]]
157; CHECK: sc $[[R14]], 0($[[R2]])
158; CHECK: beq $[[R14]], $zero, $[[BB0]]
159
160; CHECK: and $[[R15:[0-9]+]], $[[R10]], $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000161; CHECK: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000162; CHECK: sll $[[R17:[0-9]+]], $[[R16]], 24
163; CHECK: sra $2, $[[R17]], 24
164}
165
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +0000166define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000167entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +0000168 %0 = atomicrmw xchg i8* @y, i8 %newval monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000169 ret i8 %0
170
171; CHECK: AtomicSwap8:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +0000172; CHECK: lw $[[R0:[0-9]+]], %got(y)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000173; CHECK: addiu $[[R1:[0-9]+]], $zero, -4
174; CHECK: and $[[R2:[0-9]+]], $[[R0]], $[[R1]]
175; CHECK: andi $[[R3:[0-9]+]], $[[R0]], 3
176; CHECK: sll $[[R4:[0-9]+]], $[[R3]], 3
177; CHECK: ori $[[R5:[0-9]+]], $zero, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000178; CHECK: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000179; CHECK: nor $[[R7:[0-9]+]], $zero, $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000180; CHECK: sllv $[[R9:[0-9]+]], $4, $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000181
182; CHECK: $[[BB0:[A-Z_0-9]+]]:
183; CHECK: ll $[[R10:[0-9]+]], 0($[[R2]])
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000184; CHECK: and $[[R13:[0-9]+]], $[[R10]], $[[R7]]
Akira Hatanaka0d7d0b52011-07-18 18:52:12 +0000185; CHECK: or $[[R14:[0-9]+]], $[[R13]], $[[R9]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000186; CHECK: sc $[[R14]], 0($[[R2]])
187; CHECK: beq $[[R14]], $zero, $[[BB0]]
188
189; CHECK: and $[[R15:[0-9]+]], $[[R10]], $[[R6]]
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000190; CHECK: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000191; CHECK: sll $[[R17:[0-9]+]], $[[R16]], 24
192; CHECK: sra $2, $[[R17]], 24
193}
194
195define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind {
196entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +0000197 %0 = cmpxchg i8* @y, i8 %oldval, i8 %newval monotonic
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000198 ret i8 %0
199
200; CHECK: AtomicCmpSwap8:
Akira Hatanaka1da1cdf2012-05-12 03:25:16 +0000201; CHECK: lw $[[R0:[0-9]+]], %got(y)
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000202; CHECK: addiu $[[R1:[0-9]+]], $zero, -4
203; CHECK: and $[[R2:[0-9]+]], $[[R0]], $[[R1]]
204; CHECK: andi $[[R3:[0-9]+]], $[[R0]], 3
205; CHECK: sll $[[R4:[0-9]+]], $[[R3]], 3
206; CHECK: ori $[[R5:[0-9]+]], $zero, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000207; CHECK: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000208; CHECK: nor $[[R7:[0-9]+]], $zero, $[[R6]]
209; CHECK: andi $[[R8:[0-9]+]], $4, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000210; CHECK: sllv $[[R9:[0-9]+]], $[[R8]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000211; CHECK: andi $[[R10:[0-9]+]], $5, 255
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000212; CHECK: sllv $[[R11:[0-9]+]], $[[R10]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000213
214; CHECK: $[[BB0:[A-Z_0-9]+]]:
215; CHECK: ll $[[R12:[0-9]+]], 0($[[R2]])
216; CHECK: and $[[R13:[0-9]+]], $[[R12]], $[[R6]]
217; CHECK: bne $[[R13]], $[[R9]], $[[BB1:[A-Z_0-9]+]]
218
219; CHECK: and $[[R14:[0-9]+]], $[[R12]], $[[R7]]
220; CHECK: or $[[R15:[0-9]+]], $[[R14]], $[[R11]]
221; CHECK: sc $[[R15]], 0($[[R2]])
222; CHECK: beq $[[R15]], $zero, $[[BB0]]
223
224; CHECK: $[[BB1]]:
Akira Hatanakacc7ecc72011-07-19 20:34:00 +0000225; CHECK: srlv $[[R16:[0-9]+]], $[[R13]], $[[R4]]
Bruno Cardoso Lopes4e694c92011-05-31 02:54:07 +0000226; CHECK: sll $[[R17:[0-9]+]], $[[R16]], 24
227; CHECK: sra $2, $[[R17]], 24
228}
Akira Hatanakadb548262011-07-19 23:30:50 +0000229
230@countsint = common global i32 0, align 4
231
232define i32 @CheckSync(i32 %v) nounwind noinline {
233entry:
Eli Friedmanad2d46d2011-09-26 20:27:49 +0000234 %0 = atomicrmw add i32* @countsint, i32 %v seq_cst
Akira Hatanakadb548262011-07-19 23:30:50 +0000235 ret i32 %0
236
237; CHECK: CheckSync:
238; CHECK: sync 0
239; CHECK: ll
240; CHECK: sc
241; CHECK: beq
242; CHECK: sync 0
243}
244
Akira Hatanaka3011a332012-05-11 23:22:18 +0000245; make sure that this assertion in
246; TwoAddressInstructionPass::TryInstructionTransform does not fail:
247;
248; line 1203: assert(TargetRegisterInfo::isVirtualRegister(regB) &&
249;
250; it failed when MipsDAGToDAGISel::ReplaceUsesWithZeroReg replaced an
251; operand of an atomic instruction with register $zero.
252@a = external global i32
253
254define i32 @zeroreg() nounwind {
255entry:
256 %0 = cmpxchg i32* @a, i32 1, i32 0 seq_cst
257 %1 = icmp eq i32 %0, 1
258 %conv = zext i1 %1 to i32
259 ret i32 %conv
260}