1 ; Test 8-bit atomic min/max operations.
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
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
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.
15 define i16 @f1(i16 *%src, i16 %b) {
17 ; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
18 ; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
19 ; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
20 ; CHECK: [[LOOP:\.[^:]*]]:
21 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
22 ; CHECK: crjle [[ROT]], %r3, [[KEEP:\..*]]
23 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
25 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
26 ; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
28 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
31 ; CHECK-SHIFT1-LABEL: f1:
32 ; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
33 ; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
35 ; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
37 ; CHECK-SHIFT1: br %r14
39 ; CHECK-SHIFT2-LABEL: f1:
40 ; CHECK-SHIFT2: sll %r3, 16
42 ; CHECK-SHIFT2: crjle {{%r[0-9]+}}, %r3
45 ; CHECK-SHIFT2: br %r14
46 %res = atomicrmw min i16 *%src, i16 %b seq_cst
50 ; Check signed maximum.
51 define i16 @f2(i16 *%src, i16 %b) {
53 ; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
54 ; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
55 ; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
56 ; CHECK: [[LOOP:\.[^:]*]]:
57 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
58 ; CHECK: crjhe [[ROT]], %r3, [[KEEP:\..*]]
59 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
61 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
62 ; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
64 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
67 ; CHECK-SHIFT1-LABEL: f2:
68 ; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
69 ; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
71 ; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
73 ; CHECK-SHIFT1: br %r14
75 ; CHECK-SHIFT2-LABEL: f2:
76 ; CHECK-SHIFT2: sll %r3, 16
78 ; CHECK-SHIFT2: crjhe {{%r[0-9]+}}, %r3
81 ; CHECK-SHIFT2: br %r14
82 %res = atomicrmw max i16 *%src, i16 %b seq_cst
86 ; Check unsigned minimum.
87 define i16 @f3(i16 *%src, i16 %b) {
89 ; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
90 ; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
91 ; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
92 ; CHECK: [[LOOP:\.[^:]*]]:
93 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
94 ; CHECK: clr [[ROT]], %r3
95 ; CHECK: jle [[KEEP:\..*]]
96 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
98 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
99 ; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
100 ; CHECK: jlh [[LOOP]]
101 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
104 ; CHECK-SHIFT1-LABEL: f3:
105 ; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
106 ; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
108 ; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
110 ; CHECK-SHIFT1: br %r14
112 ; CHECK-SHIFT2-LABEL: f3:
113 ; CHECK-SHIFT2: sll %r3, 16
115 ; CHECK-SHIFT2: clr {{%r[0-9]+}}, %r3
118 ; CHECK-SHIFT2: br %r14
119 %res = atomicrmw umin i16 *%src, i16 %b seq_cst
123 ; Check unsigned maximum.
124 define i16 @f4(i16 *%src, i16 %b) {
126 ; CHECK-DAG: sllg [[SHIFT:%r[1-9]+]], %r2, 3
127 ; CHECK-DAG: risbg [[BASE:%r[1-9]+]], %r2, 0, 189, 0
128 ; CHECK: l [[OLD:%r[0-9]+]], 0([[BASE]])
129 ; CHECK: [[LOOP:\.[^:]*]]:
130 ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]])
131 ; CHECK: clr [[ROT]], %r3
132 ; CHECK: jhe [[KEEP:\..*]]
133 ; CHECK: risbg [[ROT]], %r3, 32, 47, 0
135 ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}})
136 ; CHECK: cs [[OLD]], [[NEW]], 0([[BASE]])
137 ; CHECK: jlh [[LOOP]]
138 ; CHECK: rll %r2, [[OLD]], 16([[SHIFT]])
141 ; CHECK-SHIFT1-LABEL: f4:
142 ; CHECK-SHIFT1: sllg [[SHIFT:%r[1-9]+]], %r2, 3
143 ; CHECK-SHIFT1: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]
145 ; CHECK-SHIFT1: rll {{%r[0-9]+}}, {{%r[0-9]+}}, 0([[NEGSHIFT]])
147 ; CHECK-SHIFT1: br %r14
149 ; CHECK-SHIFT2-LABEL: f4:
150 ; CHECK-SHIFT2: sll %r3, 16
152 ; CHECK-SHIFT2: clr {{%r[0-9]+}}, %r3
155 ; CHECK-SHIFT2: br %r14
156 %res = atomicrmw umax i16 *%src, i16 %b seq_cst
160 ; Check the lowest useful signed minimum value. We need to load 0x80010000
161 ; into the source register.
162 define i16 @f5(i16 *%src) {
164 ; CHECK: llilh [[SRC2:%r[0-9]+]], 32769
165 ; CHECK: crjle [[ROT:%r[0-9]+]], [[SRC2]]
166 ; CHECK: risbg [[ROT]], [[SRC2]], 32, 47, 0
169 ; CHECK-SHIFT1-LABEL: f5:
170 ; CHECK-SHIFT1: br %r14
171 ; CHECK-SHIFT2-LABEL: f5:
172 ; CHECK-SHIFT2: br %r14
173 %res = atomicrmw min i16 *%src, i16 -32767 seq_cst
177 ; Check the highest useful signed maximum value. We need to load 0x7ffe0000
178 ; into the source register.
179 define i16 @f6(i16 *%src) {
181 ; CHECK: llilh [[SRC2:%r[0-9]+]], 32766
182 ; CHECK: crjhe [[ROT:%r[0-9]+]], [[SRC2]]
183 ; CHECK: risbg [[ROT]], [[SRC2]], 32, 47, 0
186 ; CHECK-SHIFT1-LABEL: f6:
187 ; CHECK-SHIFT1: br %r14
188 ; CHECK-SHIFT2-LABEL: f6:
189 ; CHECK-SHIFT2: br %r14
190 %res = atomicrmw max i16 *%src, i16 32766 seq_cst
194 ; Check the lowest useful unsigned maximum value. We need to load 0x00010000
195 ; into the source register.
196 define i16 @f7(i16 *%src) {
198 ; CHECK: llilh [[SRC2:%r[0-9]+]], 1
199 ; CHECK: clr [[ROT:%r[0-9]+]], [[SRC2]]
200 ; CHECK: risbg [[ROT]], [[SRC2]], 32, 47, 0
203 ; CHECK-SHIFT1-LABEL: f7:
204 ; CHECK-SHIFT1: br %r14
205 ; CHECK-SHIFT2-LABEL: f7:
206 ; CHECK-SHIFT2: br %r14
207 %res = atomicrmw umin i16 *%src, i16 1 seq_cst
211 ; Check the highest useful unsigned maximum value. We need to load 0xfffe0000
212 ; into the source register.
213 define i16 @f8(i16 *%src) {
215 ; CHECK: llilh [[SRC2:%r[0-9]+]], 65534
216 ; CHECK: clr [[ROT:%r[0-9]+]], [[SRC2]]
217 ; CHECK: risbg [[ROT]], [[SRC2]], 32, 47, 0
220 ; CHECK-SHIFT1-LABEL: f8:
221 ; CHECK-SHIFT1: br %r14
222 ; CHECK-SHIFT2-LABEL: f8:
223 ; CHECK-SHIFT2: br %r14
224 %res = atomicrmw umax i16 *%src, i16 65534 seq_cst