61f398314de12ed5655a8522facd0d225489f6c1
[oota-llvm.git] / test / CodeGen / Mips / cmov.ll
1 ; RUN: llc -march=mips     -mcpu=mips32                 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV
2 ; RUN: llc -march=mips     -mcpu=mips32 -regalloc=basic < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV
3 ; RUN: llc -march=mips     -mcpu=mips32r2               < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV
4 ; RUN: llc -march=mips     -mcpu=mips32r6               < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP
5 ; RUN: llc -march=mips64el -mcpu=mips4                  < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV
6 ; RUN: llc -march=mips64el -mcpu=mips64                 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV
7 ; RUN: llc -march=mips64el -mcpu=mips64r6               < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP
8
9 @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4
10 @i3 = common global i32* null, align 4
11
12 ; ALL-LABEL: cmov1:
13
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]])
18
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:   seleqz $[[T0:[0-9]+]], $[[R1]], $4
22 ; 32-CMP-DAG:   selnez $[[T1:[0-9]+]], $[[R0]], $4
23 ; 32-CMP-DAG:   or $[[T2:[0-9]+]], $[[T1]], $[[T0]]
24 ; 32-CMP-DAG:   lw $2, 0($[[T2]])
25
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
29
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
34 ;        needed.
35 ; 64-CMP-DAG:   sll $[[CC:[0-9]+]], $4, 0
36 ; 64-CMP-DAG:   seleqz $[[T0:[0-9]+]], $[[R1]], $[[CC]]
37 ; 64-CMP-DAG:   selnez $[[T1:[0-9]+]], $[[R0]], $[[CC]]
38 ; 64-CMP-DAG:   or $[[T2:[0-9]+]], $[[T1]], $[[T0]]
39 ; 64-CMP-DAG:   ld $2, 0($[[T2]])
40
41 define i32* @cmov1(i32 %s) nounwind readonly {
42 entry:
43   %tobool = icmp ne i32 %s, 0
44   %tmp1 = load i32** @i3, align 4
45   %cond = select i1 %tobool, i32* getelementptr inbounds ([3 x i32]* @i1, i32 0, i32 0), i32* %tmp1
46   ret i32* %cond
47 }
48
49 @c = global i32 1, align 4
50 @d = global i32 0, align 4
51
52 ; ALL-LABEL: cmov2:
53
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]])
58
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:   seleqz $[[T0:[0-9]+]], $[[R0]], $4
62 ; 32-CMP-DAG:   selnez $[[T1:[0-9]+]], $[[R1]], $4
63 ; 32-CMP-DAG:   or $[[T2:[0-9]+]], $[[T1]], $[[T0]]
64 ; 32-CMP-DAG:   lw $2, 0($[[T2]])
65
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
69
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
74 ;        needed.
75 ; 64-CMP-DAG:   sll $[[CC:[0-9]+]], $4, 0
76 ; 64-CMP-DAG:   seleqz $[[T0:[0-9]+]], $[[R0]], $[[CC]]
77 ; 64-CMP-DAG:   selnez $[[T1:[0-9]+]], $[[R1]], $[[CC]]
78 ; 64-CMP-DAG:   or $[[T2:[0-9]+]], $[[T1]], $[[T0]]
79 ; 64-CMP-DAG:   lw $2, 0($[[T2]])
80
81 define i32 @cmov2(i32 %s) nounwind readonly {
82 entry:
83   %tobool = icmp ne i32 %s, 0
84   %tmp1 = load i32* @c, align 4
85   %tmp2 = load i32* @d, align 4
86   %cond = select i1 %tobool, i32 %tmp1, i32 %tmp2
87   ret i32 %cond
88 }
89
90 ; ALL-LABEL: cmov3:
91
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
94 ; check that.
95
96 ; 32-CMOV:      xori $[[R0:[0-9]+]], $4, 234
97 ; 32-CMOV:      movz ${{[26]}}, $5, $[[R0]]
98
99 ; 32-CMP-DAG:   xori $[[CC:[0-9]+]], $4, 234
100 ; 32-CMP-DAG:   selnez $[[T0:[0-9]+]], $5, $[[CC]]
101 ; 32-CMP-DAG:   seleqz $[[T1:[0-9]+]], $6, $[[CC]]
102 ; 32-CMP-DAG:   or $2, $[[T0]], $[[T1]]
103
104 ; 64-CMOV:      xori $[[R0:[0-9]+]], $4, 234
105 ; 64-CMOV:      movz ${{[26]}}, $5, $[[R0]]
106
107 ; 64-CMP-DAG:   xori $[[CC:[0-9]+]], $4, 234
108 ; 64-CMP-DAG:   selnez $[[T0:[0-9]+]], $5, $[[CC]]
109 ; 64-CMP-DAG:   seleqz $[[T1:[0-9]+]], $6, $[[CC]]
110 ; 64-CMP-DAG:   or $2, $[[T0]], $[[T1]]
111
112 define i32 @cmov3(i32 %a, i32 %b, i32 %c) nounwind readnone {
113 entry:
114   %cmp = icmp eq i32 %a, 234
115   %cond = select i1 %cmp, i32 %b, i32 %c
116   ret i32 %cond
117 }
118
119 ; ALL-LABEL: cmov4:
120
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 one of two registers so we can at least check
123 ; that.
124
125 ; 32-CMOV-DAG: xori $[[R0:[0-9]+]], $4, 234
126 ; 32-CMOV-DAG: lw $[[R1:2]], 16($sp)
127 ; 32-CMOV-DAG: lw $[[R2:3]], 20($sp)
128 ; 32-CMOV-DAG: movz $[[R1]], $6, $[[R0]]
129 ; 32-CMOV-DAG: movz $[[R2]], $7, $[[R0]]
130
131 ; 32-CMP-DAG:  xori $[[R0:[0-9]+]], $4, 234
132 ; 32-CMP-DAG:  lw $[[R1:[0-9]+]], 16($sp)
133 ; 32-CMP-DAG:  lw $[[R2:[0-9]+]], 20($sp)
134 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $6, $[[R0]]
135 ; 32-CMP-DAG:  selnez $[[T1:[0-9]+]], $7, $[[R0]]
136 ; 32-CMP-DAG:  seleqz $[[T2:[0-9]+]], $[[R1]], $[[R0]]
137 ; 32-CMP-DAG:  seleqz $[[T3:[0-9]+]], $[[R2]], $[[R0]]
138 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T2]]
139 ; 32-CMP-DAG:  or $3, $[[T1]], $[[T3]]
140
141 ; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234
142 ; 64-CMOV: movz ${{[26]}}, $5, $[[R0]]
143
144 ; 64-CMP-DAG:  xori $[[R0:[0-9]+]], $4, 234
145 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $5, $[[R0]]
146 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $6, $[[R0]]
147 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
148
149 define i64 @cmov4(i32 %a, i64 %b, i64 %c) nounwind readnone {
150 entry:
151   %cmp = icmp eq i32 %a, 234
152   %cond = select i1 %cmp, i64 %b, i64 %c
153   ret i64 %cond
154 }
155
156 ; slti and conditional move.
157 ;
158 ; Check that, pattern
159 ;  (select (setgt a, N), t, f)
160 ; turns into
161 ;  (movz t, (setlt a, N + 1), f)
162 ; if N + 1 fits in 16-bit.
163
164 ; ALL-LABEL: slti0:
165
166 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
167 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
168 ; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767
169 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
170
171 ; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
172 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
173 ; 32-CMP-DAG:  slti $[[R0:[0-9]+]], $4, 32767
174 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
175 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
176 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
177 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
178
179 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
180 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
181 ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767
182 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
183
184 ; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
185 ; 64-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
186 ; 64-CMP-DAG:  slti $[[R0:[0-9]+]], $4, 32767
187 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
188 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
189 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
190 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
191
192 define i32 @slti0(i32 %a) {
193 entry:
194   %cmp = icmp sgt i32 %a, 32766
195   %cond = select i1 %cmp, i32 3, i32 5
196   ret i32 %cond
197 }
198
199 ; ALL-LABEL: slti1:
200
201 ; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
202 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
203 ; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
204 ; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
205 ; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
206
207 ; 32-CMP-DAG:  addiu $[[I7:[0-9]+]], $zero, 7
208 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
209 ; 32-CMP-DAG:  addiu $[[I32767:[0-9]+]], $zero, 32767
210 ; 32-CMP-DAG:  slt $[[R0:[0-9]+]], $[[I32767]], $4
211 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
212 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
213 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
214 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
215
216 ; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
217 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
218 ; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
219 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
220 ; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
221
222 ; 64-CMP-DAG:  addiu $[[I7:[0-9]+]], $zero, 7
223 ; 64-CMP-DAG:  addiu $[[I5:2]], $zero, 5
224 ; 64-CMP-DAG:  addiu $[[R1:[0-9]+]], $zero, 32767
225 ; 64-CMP-DAG:  slt $[[R0:[0-9]+]], $[[R1]], $4
226 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
227 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
228 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
229 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
230
231 define i32 @slti1(i32 %a) {
232 entry:
233   %cmp = icmp sgt i32 %a, 32767
234   %cond = select i1 %cmp, i32 7, i32 5
235   ret i32 %cond
236 }
237
238 ; ALL-LABEL: slti2:
239
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, -32768
243 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
244
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, -32768
248 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
249 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
250 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
251 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
252
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, -32768
256 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
257
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, -32768
261 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
262 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
263 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
264 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
265
266 define i32 @slti2(i32 %a) {
267 entry:
268   %cmp = icmp sgt i32 %a, -32769
269   %cond = select i1 %cmp, i32 3, i32 5
270   ret i32 %cond
271 }
272
273 ; ALL-LABEL: slti3:
274
275 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
276 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
277 ; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
278 ; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
279 ; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
280 ; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
281
282 ; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
283 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
284 ; 32-CMP-DAG:  lui $[[IMM:[0-9]+]], 65535
285 ; 32-CMP-DAG:  ori $[[IMM]], $[[IMM]], 32766
286 ; 32-CMP-DAG:  slt $[[R0:[0-9]+]], $[[I32767]], $4
287 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
288 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
289 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
290 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
291
292 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
293 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
294 ; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
295 ; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
296 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
297 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
298
299 ; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
300 ; 64-CMP-DAG:  addiu $[[I5:2]], $zero, 5
301 ; 64-CMP-DAG:  lui $[[IMM:[0-9]+]], 65535
302 ; 64-CMP-DAG:  ori $[[IMM]], $[[IMM]], 32766
303 ; 64-CMP-DAG:  slt $[[R0:[0-9]+]], $[[IMM]], $4
304 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
305 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
306 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
307 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
308
309 define i32 @slti3(i32 %a) {
310 entry:
311   %cmp = icmp sgt i32 %a, -32770
312   %cond = select i1 %cmp, i32 3, i32 5
313   ret i32 %cond
314 }
315
316 ; 64-bit patterns.
317
318 ; ALL-LABEL: slti64_0:
319
320 ; 32-CMOV-DAG:  slt $[[CC:[0-9]+]], $zero, $4
321 ; 32-CMOV-DAG:  addiu $[[I32766:[0-9]+]], $zero, 32766
322 ; 32-CMOV-DAG:  sltu $[[R1:[0-9]+]], $[[I32766]], $5
323 ; 32-CMOV-DAG:  movz $[[CC:[0-9]+]], $[[R1]], $4
324 ; 32-CMOV-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
325 ; 32-CMOV-DAG:  addiu $[[I4:3]], $zero, 4
326 ; 32-CMOV-DAG:  movn $[[I4]], $[[I5]], $[[CC]]
327 ; 32-CMOV-DAG:  addiu $2, $zero, 0
328
329 ; 32-CMP-DAG:   slt $[[CC0:[0-9]+]], $zero, $4
330 ; 32-CMP-DAG:   addiu $[[I32766:[0-9]+]], $zero, 32766
331 ; 32-CMP-DAG:   sltu $[[CC1:[0-9]+]], $[[I32766]], $5
332 ; 32-CMP-DAG:   seleqz $[[CC2:[0-9]+]], $[[CC0]], $4
333 ; 32-CMP-DAG:   selnez $[[CC3:[0-9]+]], $[[CC1]], $4
334 ; 32-CMP:       or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]]
335 ; 32-CMP-DAG:   addiu $[[I5:[0-9]+]], $zero, 5
336 ; 32-CMP-DAG:   addiu $[[I4:[0-9]+]], $zero, 4
337 ; 32-CMP-DAG:   seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]]
338 ; 32-CMP-DAG:   selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]]
339 ; 32-CMP-DAG:   or $3, $[[T1]], $[[T0]]
340 ; 32-CMP-DAG:   addiu $2, $zero, 0
341
342 ; 64-CMOV-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
343 ; 64-CMOV-DAG:  addiu $[[I4:2]], $zero, 4
344 ; 64-CMOV-DAG:  slti $[[R0:[0-9]+]], $4, 32767
345 ; 64-CMOV-DAG:  movz $[[I4]], $[[I5]], $[[R0]]
346
347 ; 64-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
348 ; 64-CMP-DAG:  addiu $[[I4:[0-9]+]], $zero, 4
349 ; 64-CMP-DAG:  slti $[[R0:[0-9]+]], $4, 32767
350 ; FIXME: We can do better than this by adding/subtracting the result of slti
351 ;        to/from one of the constants.
352 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]]
353 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]]
354 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
355
356 define i64 @slti64_0(i64 %a) {
357 entry:
358   %cmp = icmp sgt i64 %a, 32766
359   %conv = select i1 %cmp, i64 5, i64 4
360   ret i64 %conv
361 }
362
363 ; ALL-LABEL: slti64_1:
364
365 ; 32-CMOV-DAG:  slt $[[CC:[0-9]+]], $zero, $4
366 ; 32-CMOV-DAG:  addiu $[[I32766:[0-9]+]], $zero, 32767
367 ; 32-CMOV-DAG:  sltu $[[R1:[0-9]+]], $[[I32766]], $5
368 ; 32-CMOV-DAG:  movz $[[CC:[0-9]+]], $[[R1]], $4
369 ; 32-CMOV-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
370 ; 32-CMOV-DAG:  addiu $[[I4:3]], $zero, 4
371 ; 32-CMOV-DAG:  movn $[[I4]], $[[I5]], $[[CC]]
372 ; 32-CMOV-DAG:  addiu $2, $zero, 0
373
374 ; 32-CMP-DAG:   slt $[[CC0:[0-9]+]], $zero, $4
375 ; 32-CMP-DAG:   addiu $[[I32766:[0-9]+]], $zero, 32767
376 ; 32-CMP-DAG:   sltu $[[CC1:[0-9]+]], $[[I32766]], $5
377 ; 32-CMP-DAG:   seleqz $[[CC2:[0-9]+]], $[[CC0]], $4
378 ; 32-CMP-DAG:   selnez $[[CC3:[0-9]+]], $[[CC1]], $4
379 ; 32-CMP:       or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]]
380 ; 32-CMP-DAG:   addiu $[[I5:[0-9]+]], $zero, 5
381 ; 32-CMP-DAG:   addiu $[[I4:[0-9]+]], $zero, 4
382 ; 32-CMP-DAG:   seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]]
383 ; 32-CMP-DAG:   selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]]
384 ; 32-CMP-DAG:   or $3, $[[T1]], $[[T0]]
385 ; 32-CMP-DAG:   addiu $2, $zero, 0
386
387 ; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
388 ; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4
389 ; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767
390 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
391 ; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]]
392
393 ; 64-CMP-DAG:  daddiu $[[I5:[0-9]+]], $zero, 5
394 ; 64-CMP-DAG:  daddiu $[[I4:2]], $zero, 4
395 ; 64-CMP-DAG:  daddiu $[[R1:[0-9]+]], $zero, 32767
396 ; 64-CMP-DAG:  slt $[[R0:[0-9]+]], $[[R1]], $4
397 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
398 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]]
399 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]]
400 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
401
402 define i64 @slti64_1(i64 %a) {
403 entry:
404   %cmp = icmp sgt i64 %a, 32767
405   %conv = select i1 %cmp, i64 5, i64 4
406   ret i64 %conv
407 }
408
409 ; ALL-LABEL: slti64_2:
410
411 ; FIXME: The 32-bit versions of this test are too complicated to reasonably
412 ;        match at the moment. They do show some missing optimizations though
413 ;        such as:
414 ;           (movz $a, $b, (neg $c)) -> (movn $a, $b, $c)
415
416 ; 64-CMOV-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
417 ; 64-CMOV-DAG:  addiu $[[I4:2]], $zero, 4
418 ; 64-CMOV-DAG:  slti $[[R0:[0-9]+]], $4, -32768
419 ; 64-CMOV-DAG:  movz $[[I4]], $[[I3]], $[[R0]]
420
421 ; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
422 ; 64-CMP-DAG:  addiu $[[I4:[0-9]+]], $zero, 4
423 ; 64-CMP-DAG:  slti $[[R0:[0-9]+]], $4, -32768
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:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
427 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]]
428 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
429
430 define i64 @slti64_2(i64 %a) {
431 entry:
432   %cmp = icmp sgt i64 %a, -32769
433   %conv = select i1 %cmp, i64 3, i64 4
434   ret i64 %conv
435 }
436
437 ; ALL-LABEL: slti64_3:
438
439 ; FIXME: The 32-bit versions of this test are too complicated to reasonably
440 ;        match at the moment. They do show some missing optimizations though
441 ;        such as:
442 ;           (movz $a, $b, (neg $c)) -> (movn $a, $b, $c)
443
444 ; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
445 ; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4
446 ; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766
447 ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
448 ; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]]
449
450 ; 64-CMP-DAG:  daddiu $[[I5:[0-9]+]], $zero, 5
451 ; 64-CMP-DAG:  daddiu $[[I4:2]], $zero, 4
452 ; 64-CMP-DAG:  daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766
453 ; 64-CMP-DAG:  slt $[[R0:[0-9]+]], $[[R1]], $4
454 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
455 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]]
456 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]]
457 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
458
459 define i64 @slti64_3(i64 %a) {
460 entry:
461   %cmp = icmp sgt i64 %a, -32770
462   %conv = select i1 %cmp, i64 5, i64 4
463   ret i64 %conv
464 }
465
466 ; sltiu instructions.
467
468 ; ALL-LABEL: sltiu0:
469
470 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
471 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
472 ; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767
473 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
474
475 ; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
476 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
477 ; 32-CMP-DAG:  sltiu $[[R0:[0-9]+]], $4, 32767
478 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
479 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
480 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
481 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
482
483 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
484 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
485 ; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767
486 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
487
488 ; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
489 ; 64-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
490 ; 64-CMP-DAG:  sltiu $[[R0:[0-9]+]], $4, 32767
491 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
492 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
493 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
494 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
495
496 define i32 @sltiu0(i32 %a) {
497 entry:
498   %cmp = icmp ugt i32 %a, 32766
499   %cond = select i1 %cmp, i32 3, i32 5
500   ret i32 %cond
501 }
502
503 ; ALL-LABEL: sltiu1:
504
505 ; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
506 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
507 ; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
508 ; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
509 ; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
510
511 ; 32-CMP-DAG:  addiu $[[I7:[0-9]+]], $zero, 7
512 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
513 ; 32-CMP-DAG:  addiu $[[I32767:[0-9]+]], $zero, 32767
514 ; 32-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[I32767]], $4
515 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
516 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
517 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
518 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
519
520 ; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
521 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
522 ; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
523 ; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
524 ; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
525
526 ; 64-CMP-DAG:  addiu $[[I7:[0-9]+]], $zero, 7
527 ; 64-CMP-DAG:  addiu $[[I5:2]], $zero, 5
528 ; 64-CMP-DAG:  addiu $[[R1:[0-9]+]], $zero, 32767
529 ; 64-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[R1]], $4
530 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
531 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
532 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
533 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
534
535 define i32 @sltiu1(i32 %a) {
536 entry:
537   %cmp = icmp ugt i32 %a, 32767
538   %cond = select i1 %cmp, i32 7, i32 5
539   ret i32 %cond
540 }
541
542 ; ALL-LABEL: sltiu2:
543
544 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
545 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
546 ; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
547 ; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
548
549 ; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
550 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
551 ; 32-CMP-DAG:  sltiu $[[R0:[0-9]+]], $4, -32768
552 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
553 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
554 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
555 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
556
557 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
558 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
559 ; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
560 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
561
562 ; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
563 ; 64-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
564 ; 64-CMP-DAG:  sltiu $[[R0:[0-9]+]], $4, -32768
565 ; FIXME: We can do better than this by using selccz to choose between +0 and +2
566 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
567 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
568 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
569
570 define i32 @sltiu2(i32 %a) {
571 entry:
572   %cmp = icmp ugt i32 %a, -32769
573   %cond = select i1 %cmp, i32 3, i32 5
574   ret i32 %cond
575 }
576
577 ; ALL-LABEL: sltiu3:
578
579 ; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
580 ; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
581 ; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
582 ; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
583 ; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
584 ; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
585
586 ; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
587 ; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
588 ; 32-CMP-DAG:  lui $[[IMM:[0-9]+]], 65535
589 ; 32-CMP-DAG:  ori $[[IMM]], $[[IMM]], 32766
590 ; 32-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[I32767]], $4
591 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
592 ; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
593 ; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
594 ; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
595
596 ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
597 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
598 ; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
599 ; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
600 ; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
601 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
602
603 ; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
604 ; 64-CMP-DAG:  addiu $[[I5:2]], $zero, 5
605 ; 64-CMP-DAG:  lui $[[IMM:[0-9]+]], 65535
606 ; 64-CMP-DAG:  ori $[[IMM]], $[[IMM]], 32766
607 ; 64-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[IMM]], $4
608 ; FIXME: We can do better than this by using selccz to choose between -0 and -2
609 ; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
610 ; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
611 ; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
612
613 define i32 @sltiu3(i32 %a) {
614 entry:
615   %cmp = icmp ugt i32 %a, -32770
616   %cond = select i1 %cmp, i32 3, i32 5
617   ret i32 %cond
618 }
619
620 ; Check if
621 ;  (select (setxx a, N), x, x-1) or
622 ;  (select (setxx a, N), x-1, x)
623 ; doesn't generate conditional moves
624 ; for constant operands whose difference is |1|
625
626 define i32 @slti4(i32 %a) nounwind readnone {
627   %1 = icmp slt i32 %a, 7
628   %2 = select i1 %1, i32 4, i32 3
629   ret i32 %2
630 }
631
632 ; ALL-LABEL: slti4:
633
634 ; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
635 ; 32-CMOV-DAG: addiu $2, [[R1]], 3
636 ; 32-CMOV-NOT: movn
637
638 ; 32-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
639 ; 32-CMP-DAG:  addiu $2, [[R1]], 3
640 ; 32-CMP-NOT:  seleqz
641 ; 32-CMP-NOT:  selnez
642
643 ; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
644 ; 64-CMOV-DAG: addiu $2, [[R1]], 3
645 ; 64-CMOV-NOT: movn
646
647 ; 64-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
648 ; 64-CMP-DAG:  addiu $2, [[R1]], 3
649 ; 64-CMP-NOT:  seleqz
650 ; 64-CMP-NOT:  selnez
651
652 define i32 @slti5(i32 %a) nounwind readnone {
653   %1 = icmp slt i32 %a, 7
654   %2 = select i1 %1, i32 -3, i32 -4
655   ret i32 %2
656 }
657
658 ; ALL-LABEL: slti5:
659
660 ; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
661 ; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
662 ; 32-CMOV-NOT: movn
663
664 ; 32-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
665 ; 32-CMP-DAG:  addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
666 ; 32-CMP-NOT:  seleqz
667 ; 32-CMP-NOT:  selnez
668
669 ; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
670 ; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
671 ; 64-CMOV-NOT: movn
672
673 ; 64-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
674 ; 64-CMP-DAG:  addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
675 ; 64-CMP-NOT:  seleqz
676 ; 64-CMP-NOT:  selnez
677
678 define i32 @slti6(i32 %a) nounwind readnone {
679   %1 = icmp slt i32 %a, 7
680   %2 = select i1 %1, i32 3, i32 4
681   ret i32 %2
682 }
683
684 ; ALL-LABEL: slti6:
685
686 ; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
687 ; 32-CMOV-DAG: xori [[R1]], [[R1]], 1
688 ; 32-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3
689 ; 32-CMOV-NOT: movn
690
691 ; 32-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
692 ; 32-CMP-DAG:  xori [[R1]], [[R1]], 1
693 ; 32-CMP-DAG:  addiu [[R2:\$[0-9]+]], [[R1]], 3
694 ; 32-CMP-NOT:  seleqz
695 ; 32-CMP-NOT:  selnez
696
697 ; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
698 ; 64-CMOV-DAG: xori [[R1]], [[R1]], 1
699 ; 64-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3
700 ; 64-CMOV-NOT: movn
701
702 ; 64-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
703 ; 64-CMP-DAG:  xori [[R1]], [[R1]], 1
704 ; 64-CMP-DAG:  addiu [[R2:\$[0-9]+]], [[R1]], 3
705 ; 64-CMP-NOT:  seleqz
706 ; 64-CMP-NOT:  selnez