1 ; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,32-CMOV
2 ; RUN: llc -march=mips -mcpu=mips32 -regalloc=basic -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,32-CMOV
3 ; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,32-CMOV
4 ; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,32-CMP
5 ; RUN: llc -march=mips64el -mcpu=mips4 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,64-CMOV
6 ; RUN: llc -march=mips64el -mcpu=mips64 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,64-CMOV
7 ; RUN: llc -march=mips64el -mcpu=mips64r6 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,64-CMP
9 @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4
10 @i3 = common global ptr null, align 4
14 ; 32-CMOV-DAG: lw $[[R0:[0-9]+]], %got(i3)
15 ; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1)
16 ; 32-CMOV-DAG: movn $[[R0]], $[[R1]], $4
17 ; 32-CMOV-DAG: lw $2, 0($[[R0]])
19 ; 32-CMP-DAG: lw $[[R0:[0-9]+]], %got(i3)
20 ; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1)
21 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $4
22 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $4
23 ; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]]
24 ; 32-CMP-DAG: lw $2, 0($[[T2]])
26 ; 64-CMOV-DAG: ldr $[[R0:[0-9]+]]
27 ; 64-CMOV-DAG: ld $[[R1:[0-9]+]], %got_disp(i1)
28 ; 64-CMOV-DAG: movn $[[R0]], $[[R1]], $4
30 ; 64-CMP-DAG: ld $[[R0:[0-9]+]], %got_disp(i3)(
31 ; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(i1)
32 ; FIXME: This sll works around an implementation detail in the code generator
33 ; (setcc's result is i32 so bits 32-63 are undefined). It's not really
35 ; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0
36 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $[[CC]]
37 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $[[CC]]
38 ; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]]
39 ; 64-CMP-DAG: ld $2, 0($[[T2]])
41 define ptr @cmov1(i32 signext %s) nounwind readonly {
43 %tobool = icmp ne i32 %s, 0
44 %tmp1 = load ptr, ptr @i3, align 4
45 %cond = select i1 %tobool, ptr @i1, ptr %tmp1
49 @c = global i32 1, align 4
50 @d = global i32 0, align 4
54 ; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d)
55 ; 32-CMOV-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c)
56 ; 32-CMOV-DAG: movn $[[R1]], $[[R0]], $4
57 ; 32-CMOV-DAG: lw $2, 0($[[R0]])
59 ; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d)
60 ; 32-CMP-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c)
61 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $4
62 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $4
63 ; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]]
64 ; 32-CMP-DAG: lw $2, 0($[[T2]])
66 ; 64-CMOV: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d)
67 ; 64-CMOV: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c)
68 ; 64-CMOV: movn $[[R1]], $[[R0]], $4
70 ; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d)
71 ; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c)
72 ; FIXME: This sll works around an implementation detail in the code generator
73 ; (setcc's result is i32 so bits 32-63 are undefined). It's not really
75 ; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0
76 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $[[CC]]
77 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $[[CC]]
78 ; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]]
79 ; 64-CMP-DAG: lw $2, 0($[[T2]])
81 define i32 @cmov2(i32 signext %s) nounwind readonly {
83 %tobool = icmp ne i32 %s, 0
84 %tmp1 = load i32, ptr @c, align 4
85 %tmp2 = load i32, ptr @d, align 4
86 %cond = select i1 %tobool, i32 %tmp1, i32 %tmp2
92 ; We won't check the result register since we can't know if the move is first
93 ; or last. We do know it will be either one of two registers so we can at least
96 ; 32-CMOV: xori $[[R0:[0-9]+]], $4, 234
97 ; 32-CMOV: movz ${{[26]}}, $5, $[[R0]]
99 ; 32-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234
100 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]]
101 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]]
102 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
104 ; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234
105 ; 64-CMOV: movz ${{[26]}}, $5, $[[R0]]
107 ; 64-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234
108 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]]
109 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]]
110 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
112 define i32 @cmov3(i32 signext %a, i32 signext %b, i32 signext %c) nounwind readnone {
114 %cmp = icmp eq i32 %a, 234
115 %cond = select i1 %cmp, i32 %b, i32 %c
119 ; ALL-LABEL: cmov3_ne:
121 ; We won't check the result register since we can't know if the move is first
122 ; or last. We do know it will be either one of two registers so we can at least
125 ; FIXME: Use xori instead of addiu+xor.
126 ; 32-CMOV: addiu $[[R0:[0-9]+]], $zero, 234
127 ; 32-CMOV: xor $[[R1:[0-9]+]], $4, $[[R0]]
128 ; 32-CMOV: movn ${{[26]}}, $5, $[[R1]]
130 ; 32-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234
131 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]]
132 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]]
133 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
135 ; FIXME: Use xori instead of addiu+xor.
136 ; 64-CMOV: addiu $[[R0:[0-9]+]], $zero, 234
137 ; 64-CMOV: xor $[[R1:[0-9]+]], $4, $[[R0]]
138 ; 64-CMOV: movn ${{[26]}}, $5, $[[R1]]
140 ; 64-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234
141 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]]
142 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]]
143 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
145 define i32 @cmov3_ne(i32 signext %a, i32 signext %b, i32 signext %c) nounwind readnone {
147 %cmp = icmp ne i32 %a, 234
148 %cond = select i1 %cmp, i32 %b, i32 %c
154 ; We won't check the result register since we can't know if the move is first
155 ; or last. We do know it will be one of two registers so we can at least check
158 ; 32-CMOV-DAG: xori $[[R0:[0-9]+]], $4, 234
159 ; 32-CMOV-DAG: lw $[[R1:2]], 16($sp)
160 ; 32-CMOV-DAG: lw $[[R2:3]], 20($sp)
161 ; 32-CMOV-DAG: movz $[[R1]], $6, $[[R0]]
162 ; 32-CMOV-DAG: movz $[[R2]], $7, $[[R0]]
164 ; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234
165 ; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp)
166 ; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp)
167 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $6, $[[R0]]
168 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $7, $[[R0]]
169 ; 32-CMP-DAG: selnez $[[T2:[0-9]+]], $[[R1]], $[[R0]]
170 ; 32-CMP-DAG: selnez $[[T3:[0-9]+]], $[[R2]], $[[R0]]
171 ; 32-CMP-DAG: or $2, $[[T0]], $[[T2]]
172 ; 32-CMP-DAG: or $3, $[[T1]], $[[T3]]
174 ; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234
175 ; 64-CMOV: movz ${{[26]}}, $5, $[[R0]]
177 ; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234
178 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[R0]]
179 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[R0]]
180 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
182 define i64 @cmov4(i32 signext %a, i64 %b, i64 %c) nounwind readnone {
184 %cmp = icmp eq i32 %a, 234
185 %cond = select i1 %cmp, i64 %b, i64 %c
189 ; ALL-LABEL: cmov4_ne:
191 ; We won't check the result register since we can't know if the move is first
192 ; or last. We do know it will be one of two registers so we can at least check
195 ; FIXME: Use xori instead of addiu+xor.
196 ; 32-CMOV-DAG: addiu $[[R0:[0-9]+]], $zero, 234
197 ; 32-CMOV-DAG: xor $[[R1:[0-9]+]], $4, $[[R0]]
198 ; 32-CMOV-DAG: lw $[[R2:2]], 16($sp)
199 ; 32-CMOV-DAG: lw $[[R3:3]], 20($sp)
200 ; 32-CMOV-DAG: movn $[[R2]], $6, $[[R1]]
201 ; 32-CMOV-DAG: movn $[[R3]], $7, $[[R1]]
203 ; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234
204 ; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp)
205 ; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp)
206 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $6, $[[R0]]
207 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $7, $[[R0]]
208 ; 32-CMP-DAG: seleqz $[[T2:[0-9]+]], $[[R1]], $[[R0]]
209 ; 32-CMP-DAG: seleqz $[[T3:[0-9]+]], $[[R2]], $[[R0]]
210 ; 32-CMP-DAG: or $2, $[[T0]], $[[T2]]
211 ; 32-CMP-DAG: or $3, $[[T1]], $[[T3]]
213 ; FIXME: Use xori instead of addiu+xor.
214 ; 64-CMOV: addiu $[[R0:[0-9]+]], $zero, 234
215 ; 64-CMOV: xor $[[R1:[0-9]+]], $4, $[[R0]]
216 ; 64-CMOV: movn ${{[26]}}, $5, $[[R1]]
218 ; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234
219 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[R0]]
220 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[R0]]
221 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
223 define i64 @cmov4_ne(i32 signext %a, i64 %b, i64 %c) nounwind readnone {
225 %cmp = icmp ne i32 %a, 234
226 %cond = select i1 %cmp, i64 %b, i64 %c
230 ; slti and conditional move.
232 ; Check that, pattern
233 ; (select (setgt a, N), t, f)
235 ; (movz t, (setlt a, N + 1), f)
236 ; if N + 1 fits in 16-bit.
240 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
241 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
242 ; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767
243 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
245 ; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
246 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
247 ; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767
248 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
249 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
250 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
251 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
253 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
254 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
255 ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767
256 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
258 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
259 ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
260 ; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767
261 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
262 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
263 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
264 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
266 define i32 @slti0(i32 signext %a) {
268 %cmp = icmp sgt i32 %a, 32766
269 %cond = select i1 %cmp, i32 3, i32 5
275 ; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
276 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
277 ; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
278 ; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
279 ; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
281 ; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7
282 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
283 ; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767
284 ; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4
285 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
286 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
287 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
288 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
290 ; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
291 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
292 ; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
293 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
294 ; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
296 ; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7
297 ; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5
298 ; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
299 ; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
300 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
301 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
302 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
303 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
305 define i32 @slti1(i32 signext %a) {
307 %cmp = icmp sgt i32 %a, 32767
308 %cond = select i1 %cmp, i32 7, i32 5
314 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
315 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
316 ; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768
317 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
319 ; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
320 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
321 ; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768
322 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
323 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
324 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
325 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
327 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
328 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
329 ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768
330 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
332 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
333 ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
334 ; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768
335 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
336 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
337 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
338 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
340 define i32 @slti2(i32 signext %a) {
342 %cmp = icmp sgt i32 %a, -32769
343 %cond = select i1 %cmp, i32 3, i32 5
349 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
350 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
351 ; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
352 ; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
353 ; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
354 ; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
356 ; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
357 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
358 ; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535
359 ; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766
360 ; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4
361 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
362 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
363 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
364 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
366 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
367 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
368 ; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
369 ; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
370 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
371 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
373 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
374 ; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5
375 ; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535
376 ; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766
377 ; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[IMM]], $4
378 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
379 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
380 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
381 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
383 define i32 @slti3(i32 signext %a) {
385 %cmp = icmp sgt i32 %a, -32770
386 %cond = select i1 %cmp, i32 3, i32 5
392 ; ALL-LABEL: slti64_0:
394 ; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4
395 ; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766
396 ; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5
397 ; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4
398 ; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5
399 ; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4
400 ; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]]
401 ; 32-CMOV-DAG: addiu $2, $zero, 0
403 ; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4
404 ; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766
405 ; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5
406 ; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4
407 ; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4
408 ; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]]
409 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
410 ; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4
411 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]]
412 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]]
413 ; 32-CMP-DAG: or $3, $[[T1]], $[[T0]]
414 ; 32-CMP-DAG: addiu $2, $zero, 0
416 ; 64-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5
417 ; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4
418 ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767
419 ; 64-CMOV-DAG: movz $[[I4]], $[[I5]], $[[R0]]
421 ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
422 ; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4
423 ; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767
424 ; FIXME: We can do better than this by adding/subtracting the result of slti
425 ; to/from one of the constants.
426 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R0]]
427 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]]
428 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
430 define i64 @slti64_0(i64 %a) {
432 %cmp = icmp sgt i64 %a, 32766
433 %conv = select i1 %cmp, i64 5, i64 4
437 ; ALL-LABEL: slti64_1:
439 ; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4
440 ; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767
441 ; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5
442 ; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4
443 ; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5
444 ; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4
445 ; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]]
446 ; 32-CMOV-DAG: addiu $2, $zero, 0
448 ; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4
449 ; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767
450 ; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5
451 ; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4
452 ; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4
453 ; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]]
454 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
455 ; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4
456 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]]
457 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]]
458 ; 32-CMP-DAG: or $3, $[[T1]], $[[T0]]
459 ; 32-CMP-DAG: addiu $2, $zero, 0
461 ; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
462 ; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4
463 ; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767
464 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
465 ; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]]
467 ; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
468 ; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4
469 ; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767
470 ; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
471 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
472 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]]
473 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]]
474 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
476 define i64 @slti64_1(i64 %a) {
478 %cmp = icmp sgt i64 %a, 32767
479 %conv = select i1 %cmp, i64 5, i64 4
483 ; ALL-LABEL: slti64_2:
485 ; FIXME: The 32-bit versions of this test are too complicated to reasonably
486 ; match at the moment. They do show some missing optimizations though
488 ; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c)
490 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
491 ; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4
492 ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768
493 ; 64-CMOV-DAG: movz $[[I4]], $[[I3]], $[[R0]]
495 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
496 ; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4
497 ; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768
498 ; FIXME: We can do better than this by adding/subtracting the result of slti
499 ; to/from one of the constants.
500 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
501 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]]
502 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
504 define i64 @slti64_2(i64 %a) {
506 %cmp = icmp sgt i64 %a, -32769
507 %conv = select i1 %cmp, i64 3, i64 4
511 ; ALL-LABEL: slti64_3:
513 ; FIXME: The 32-bit versions of this test are too complicated to reasonably
514 ; match at the moment. They do show some missing optimizations though
516 ; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c)
518 ; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
519 ; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4
522 ; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
523 ; 64-CMOV-DAG: ori $[[R2:[0-9]+]], $[[R1]], 32766
524 ; 64-CMOV-DAG: slt $[[R3:[0-9]+]], $[[R2]], $4
525 ; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R3]]
527 ; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
528 ; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4
530 ; 64-CMP-DAG: lui $[[R1:[0-9]+]], 65535
531 ; 64-CMP-DAG: ori $[[R2:[0-9]+]], $[[R1]], 32766
532 ; 64-CMP-DAG: slt $[[R3:[0-9]+]], $[[R2]], $4
533 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
534 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R3]]
535 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R3]]
536 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
538 define i64 @slti64_3(i64 %a) {
540 %cmp = icmp sgt i64 %a, -32770
541 %conv = select i1 %cmp, i64 5, i64 4
545 ; sltiu instructions.
549 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
550 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
551 ; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767
552 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
554 ; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
555 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
556 ; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767
557 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
558 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
559 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
560 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
562 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
563 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
564 ; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767
565 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
567 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
568 ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
569 ; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767
570 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
571 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
572 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
573 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
575 define i32 @sltiu0(i32 signext %a) {
577 %cmp = icmp ugt i32 %a, 32766
578 %cond = select i1 %cmp, i32 3, i32 5
584 ; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
585 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
586 ; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
587 ; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
588 ; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
590 ; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7
591 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
592 ; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767
593 ; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4
594 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
595 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
596 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
597 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
599 ; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
600 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
601 ; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
602 ; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
603 ; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
605 ; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7
606 ; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5
607 ; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
608 ; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
609 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
610 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
611 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
612 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
614 define i32 @sltiu1(i32 signext %a) {
616 %cmp = icmp ugt i32 %a, 32767
617 %cond = select i1 %cmp, i32 7, i32 5
623 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
624 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
625 ; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
626 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
628 ; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
629 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
630 ; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
631 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
632 ; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
633 ; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
634 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
636 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
637 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
638 ; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
639 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
641 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
642 ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
643 ; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
644 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
645 ; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
646 ; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
647 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
649 define i32 @sltiu2(i32 signext %a) {
651 %cmp = icmp ugt i32 %a, -32769
652 %cond = select i1 %cmp, i32 3, i32 5
658 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
659 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
660 ; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
661 ; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
662 ; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
663 ; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
665 ; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
666 ; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5
667 ; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535
668 ; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766
669 ; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4
670 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
671 ; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
672 ; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
673 ; 32-CMP-DAG: or $2, $[[T0]], $[[T1]]
675 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
676 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
677 ; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
678 ; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
679 ; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
680 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
682 ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3
683 ; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5
684 ; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535
685 ; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766
686 ; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[IMM]], $4
687 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
688 ; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
689 ; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
690 ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]]
692 define i32 @sltiu3(i32 signext %a) {
694 %cmp = icmp ugt i32 %a, -32770
695 %cond = select i1 %cmp, i32 3, i32 5
700 ; (select (setxx a, N), x, x-1) or
701 ; (select (setxx a, N), x-1, x)
702 ; doesn't generate conditional moves
703 ; for constant operands whose difference is |1|
705 define i32 @slti4(i32 signext %a) nounwind readnone {
706 %1 = icmp slt i32 %a, 7
707 %2 = select i1 %1, i32 4, i32 3
713 ; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
714 ; 32-CMOV-DAG: addiu $2, [[R1]], 3
717 ; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7
718 ; 32-CMP-DAG: addiu $2, [[R1]], 3
722 ; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
723 ; 64-CMOV-DAG: addiu $2, [[R1]], 3
726 ; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7
727 ; 64-CMP-DAG: addiu $2, [[R1]], 3
731 define i32 @slti5(i32 signext %a) nounwind readnone {
732 %1 = icmp slt i32 %a, 7
733 %2 = select i1 %1, i32 -3, i32 -4
739 ; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
740 ; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
743 ; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7
744 ; 32-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
748 ; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
749 ; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
752 ; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7
753 ; 64-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
757 define i32 @slti6(i32 signext %a) nounwind readnone {
758 %1 = icmp slt i32 %a, 7
759 %2 = select i1 %1, i32 3, i32 4
765 ; ALL-DAG: addiu [[R1:\$[0-9]+]], $zero, 6
766 ; ALL-DAG: slt [[R1]], [[R1]], $4
767 ; ALL-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3