blob: c6ec77e91b3d3ba11b4d87c5ccdd9b59421ef01c [file] [log] [blame]
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00001; Test 8-bit atomic min/max operations.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT1
5; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT2
6
7; Check signed minimum.
8; - CHECK is for the main loop.
9; - CHECK-SHIFT1 makes sure that the negated shift count used by the second
10; RLL is set up correctly. The negation is independent of the NILL and L
11; tested in CHECK.
12; - CHECK-SHIFT2 makes sure that %b is shifted into the high part of the word
13; before being used, and that the low bits are set to 1. This sequence is
14; independent of the other loop prologue instructions.
15define i8 @f1(i8 *%src, i8 %b) {
16; CHECK: f1:
17; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
18; CHECK: nill %r2, 65532
19; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
20; CHECK: [[LOOP:\.[^:]*]]:
21; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
22; CHECK: cr [[ROT]], %r3
23; CHECK: j{{g?}}le [[KEEP:\..*]]
24; CHECK: risbg [[ROT]], %r3, 32, 39, 0
25; CHECK: [[KEEP]]:
26; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
27; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
28; CHECK: j{{g?}}lh [[LOOP]]
29; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
30; CHECK: br %r14
31;
32; CHECK-SHIFT1: f1:
33; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
34; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
35; CHECK-SHIFT1: rll
36; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
37; CHECK-SHIFT1: rll
38; CHECK-SHIFT1: br %r14
39;
40; CHECK-SHIFT2: f1:
41; CHECK-SHIFT2: sll %r3, 24
42; CHECK-SHIFT2: rll
43; CHECK-SHIFT2: cr {{%r[0-9]+}}, %r3
44; CHECK-SHIFT2: rll
45; CHECK-SHIFT2: rll
46; CHECK-SHIFT2: br %r14
47 %res = atomicrmw min i8 *%src, i8 %b seq_cst
48 ret i8 %res
49}
50
51; Check signed maximum.
52define i8 @f2(i8 *%src, i8 %b) {
53; CHECK: f2:
54; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
55; CHECK: nill %r2, 65532
56; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
57; CHECK: [[LOOP:\.[^:]*]]:
58; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
59; CHECK: cr [[ROT]], %r3
60; CHECK: j{{g?}}he [[KEEP:\..*]]
61; CHECK: risbg [[ROT]], %r3, 32, 39, 0
62; CHECK: [[KEEP]]:
63; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
64; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
65; CHECK: j{{g?}}lh [[LOOP]]
66; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
67; CHECK: br %r14
68;
69; CHECK-SHIFT1: f2:
70; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
71; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
72; CHECK-SHIFT1: rll
73; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
74; CHECK-SHIFT1: rll
75; CHECK-SHIFT1: br %r14
76;
77; CHECK-SHIFT2: f2:
78; CHECK-SHIFT2: sll %r3, 24
79; CHECK-SHIFT2: rll
80; CHECK-SHIFT2: cr {{%r[0-9]+}}, %r3
81; CHECK-SHIFT2: rll
82; CHECK-SHIFT2: rll
83; CHECK-SHIFT2: br %r14
84 %res = atomicrmw max i8 *%src, i8 %b seq_cst
85 ret i8 %res
86}
87
88; Check unsigned minimum.
89define i8 @f3(i8 *%src, i8 %b) {
90; CHECK: f3:
91; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
92; CHECK: nill %r2, 65532
93; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
94; CHECK: [[LOOP:\.[^:]*]]:
95; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
96; CHECK: clr [[ROT]], %r3
97; CHECK: j{{g?}}le [[KEEP:\..*]]
98; CHECK: risbg [[ROT]], %r3, 32, 39, 0
99; CHECK: [[KEEP]]:
100; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
101; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
102; CHECK: j{{g?}}lh [[LOOP]]
103; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
104; CHECK: br %r14
105;
106; CHECK-SHIFT1: f3:
107; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
108; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
109; CHECK-SHIFT1: rll
110; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
111; CHECK-SHIFT1: rll
112; CHECK-SHIFT1: br %r14
113;
114; CHECK-SHIFT2: f3:
115; CHECK-SHIFT2: sll %r3, 24
116; CHECK-SHIFT2: rll
117; CHECK-SHIFT2: clr {{%r[0-9]+}}, %r3
118; CHECK-SHIFT2: rll
119; CHECK-SHIFT2: rll
120; CHECK-SHIFT2: br %r14
121 %res = atomicrmw umin i8 *%src, i8 %b seq_cst
122 ret i8 %res
123}
124
125; Check unsigned maximum.
126define i8 @f4(i8 *%src, i8 %b) {
127; CHECK: f4:
128; CHECK: sllg [[SHIFT:%r[1-9]+]], %r2, 3
129; CHECK: nill %r2, 65532
130; CHECK: l [[OLD:%r[0-9]+]], 0(%r2)
131; CHECK: [[LOOP:\.[^:]*]]:
132; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
133; CHECK: clr [[ROT]], %r3
134; CHECK: j{{g?}}he [[KEEP:\..*]]
135; CHECK: risbg [[ROT]], %r3, 32, 39, 0
136; CHECK: [[KEEP]]:
137; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
138; CHECK: cs [[OLD]], [[NEW]], 0(%r2)
139; CHECK: j{{g?}}lh [[LOOP]]
140; CHECK: rll %r2, [[OLD]], 8([[SHIFT]])
141; CHECK: br %r14
142;
143; CHECK-SHIFT1: f4:
144; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
145; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
146; CHECK-SHIFT1: rll
147; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
148; CHECK-SHIFT1: rll
149; CHECK-SHIFT1: br %r14
150;
151; CHECK-SHIFT2: f4:
152; CHECK-SHIFT2: sll %r3, 24
153; CHECK-SHIFT2: rll
154; CHECK-SHIFT2: clr {{%r[0-9]+}}, %r3
155; CHECK-SHIFT2: rll
156; CHECK-SHIFT2: rll
157; CHECK-SHIFT2: br %r14
158 %res = atomicrmw umax i8 *%src, i8 %b seq_cst
159 ret i8 %res
160}
161
162; Check the lowest useful signed minimum value. We need to load 0x81000000
163; into the source register.
164define i8 @f5(i8 *%src) {
165; CHECK: f5:
166; CHECK: llilh [[SRC2:%r[0-9]+]], 33024
167; CHECK: cr [[ROT:%r[0-9]+]], [[SRC2]]
168; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0
169; CHECK: br %r14
170;
171; CHECK-SHIFT1: f5:
172; CHECK-SHIFT1: br %r14
173; CHECK-SHIFT2: f5:
174; CHECK-SHIFT2: br %r14
175 %res = atomicrmw min i8 *%src, i8 -127 seq_cst
176 ret i8 %res
177}
178
179; Check the highest useful signed maximum value. We need to load 0x7e000000
180; into the source register.
181define i8 @f6(i8 *%src) {
182; CHECK: f6:
183; CHECK: llilh [[SRC2:%r[0-9]+]], 32256
184; CHECK: cr [[ROT:%r[0-9]+]], [[SRC2]]
185; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0
186; CHECK: br %r14
187;
188; CHECK-SHIFT1: f6:
189; CHECK-SHIFT1: br %r14
190; CHECK-SHIFT2: f6:
191; CHECK-SHIFT2: br %r14
192 %res = atomicrmw max i8 *%src, i8 126 seq_cst
193 ret i8 %res
194}
195
196; Check the lowest useful unsigned minimum value. We need to load 0x01000000
197; into the source register.
198define i8 @f7(i8 *%src) {
199; CHECK: f7:
200; CHECK: llilh [[SRC2:%r[0-9]+]], 256
201; CHECK: clr [[ROT:%r[0-9]+]], [[SRC2]]
202; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0
203; CHECK: br %r14
204;
205; CHECK-SHIFT1: f7:
206; CHECK-SHIFT1: br %r14
207; CHECK-SHIFT2: f7:
208; CHECK-SHIFT2: br %r14
209 %res = atomicrmw umin i8 *%src, i8 1 seq_cst
210 ret i8 %res
211}
212
213; Check the highest useful unsigned maximum value. We need to load 0xfe000000
214; into the source register.
215define i8 @f8(i8 *%src) {
216; CHECK: f8:
217; CHECK: llilh [[SRC2:%r[0-9]+]], 65024
218; CHECK: clr [[ROT:%r[0-9]+]], [[SRC2]]
219; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0
220; CHECK: br %r14
221;
222; CHECK-SHIFT1: f8:
223; CHECK-SHIFT1: br %r14
224; CHECK-SHIFT2: f8:
225; CHECK-SHIFT2: br %r14
226 %res = atomicrmw umax i8 *%src, i8 254 seq_cst
227 ret i8 %res
228}