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:   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]])
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:   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]])
40
41define i32* @cmov1(i32 signext %s) nounwind readonly {
42entry:
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:   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]])
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:   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]])
80
81define i32 @cmov2(i32 signext %s) nounwind readonly {
82entry:
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:   seleqz $[[T0:[0-9]+]], $5, $[[CC]]
101; 32-CMP-DAG:   selnez $[[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:   seleqz $[[T0:[0-9]+]], $5, $[[CC]]
109; 64-CMP-DAG:   selnez $[[T1:[0-9]+]], $6, $[[CC]]
110; 64-CMP-DAG:   or $2, $[[T0]], $[[T1]]
111
112define i32 @cmov3(i32 signext %a, i32 signext %b, i32 signext %c) nounwind readnone {
113entry:
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: cmov3_ne:
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 either one of two registers so we can at least
123; check that.
124
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]]
129
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]]
134
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]]
139
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]]
144
145define i32 @cmov3_ne(i32 signext %a, i32 signext %b, i32 signext %c) nounwind readnone {
146entry:
147  %cmp = icmp ne i32 %a, 234
148  %cond = select i1 %cmp, i32 %b, i32 %c
149  ret i32 %cond
150}
151
152; ALL-LABEL: cmov4:
153
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
156; that.
157
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]]
163
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]]
173
174; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234
175; 64-CMOV: movz ${{[26]}}, $5, $[[R0]]
176
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]]
181
182define i64 @cmov4(i32 signext %a, i64 %b, i64 %c) nounwind readnone {
183entry:
184  %cmp = icmp eq i32 %a, 234
185  %cond = select i1 %cmp, i64 %b, i64 %c
186  ret i64 %cond
187}
188
189; ALL-LABEL: cmov4_ne:
190
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
193; that.
194
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]]
202
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]]
212
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]]
217
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]]
222
223define i64 @cmov4_ne(i32 signext %a, i64 %b, i64 %c) nounwind readnone {
224entry:
225  %cmp = icmp ne i32 %a, 234
226  %cond = select i1 %cmp, i64 %b, i64 %c
227  ret i64 %cond
228}
229
230; slti and conditional move.
231;
232; Check that, pattern
233;  (select (setgt a, N), t, f)
234; turns into
235;  (movz t, (setlt a, N + 1), f)
236; if N + 1 fits in 16-bit.
237
238; ALL-LABEL: slti0:
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, 32767
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, 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]]
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, 32767
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, 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]]
265
266define i32 @slti0(i32 signext %a) {
267entry:
268  %cmp = icmp sgt i32 %a, 32766
269  %cond = select i1 %cmp, i32 3, i32 5
270  ret i32 %cond
271}
272
273; ALL-LABEL: slti1:
274
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]]
280
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]]
289
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]]
295
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]]
304
305define i32 @slti1(i32 signext %a) {
306entry:
307  %cmp = icmp sgt i32 %a, 32767
308  %cond = select i1 %cmp, i32 7, i32 5
309  ret i32 %cond
310}
311
312; ALL-LABEL: slti2:
313
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]]
318
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]]
326
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]]
331
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]]
339
340define i32 @slti2(i32 signext %a) {
341entry:
342  %cmp = icmp sgt i32 %a, -32769
343  %cond = select i1 %cmp, i32 3, i32 5
344  ret i32 %cond
345}
346
347; ALL-LABEL: slti3:
348
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]]
355
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]]
365
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]]
372
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]]
382
383define i32 @slti3(i32 signext %a) {
384entry:
385  %cmp = icmp sgt i32 %a, -32770
386  %cond = select i1 %cmp, i32 3, i32 5
387  ret i32 %cond
388}
389
390; 64-bit patterns.
391
392; ALL-LABEL: slti64_0:
393
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
402
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
415
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]]
420
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]]
429
430define i64 @slti64_0(i64 %a) {
431entry:
432  %cmp = icmp sgt i64 %a, 32766
433  %conv = select i1 %cmp, i64 5, i64 4
434  ret i64 %conv
435}
436
437; ALL-LABEL: slti64_1:
438
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
447
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
460
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]]
466
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]]
475
476define i64 @slti64_1(i64 %a) {
477entry:
478  %cmp = icmp sgt i64 %a, 32767
479  %conv = select i1 %cmp, i64 5, i64 4
480  ret i64 %conv
481}
482
483; ALL-LABEL: slti64_2:
484
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
487;        such as:
488;           (movz $a, $b, (neg $c)) -> (movn $a, $b, $c)
489
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]]
494
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]]
503
504define i64 @slti64_2(i64 %a) {
505entry:
506  %cmp = icmp sgt i64 %a, -32769
507  %conv = select i1 %cmp, i64 3, i64 4
508  ret i64 %conv
509}
510
511; ALL-LABEL: slti64_3:
512
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
515;        such as:
516;           (movz $a, $b, (neg $c)) -> (movn $a, $b, $c)
517
518; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5
519; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4
520; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766
521; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4
522; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]]
523
524; 64-CMP-DAG:  daddiu $[[I5:[0-9]+]], $zero, 5
525; 64-CMP-DAG:  daddiu $[[I4:2]], $zero, 4
526; 64-CMP-DAG:  daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766
527; 64-CMP-DAG:  slt $[[R0:[0-9]+]], $[[R1]], $4
528; FIXME: We can do better than this by using selccz to choose between -0 and -2
529; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]]
530; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]]
531; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
532
533define i64 @slti64_3(i64 %a) {
534entry:
535  %cmp = icmp sgt i64 %a, -32770
536  %conv = select i1 %cmp, i64 5, i64 4
537  ret i64 %conv
538}
539
540; sltiu instructions.
541
542; ALL-LABEL: sltiu0:
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, 32767
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, 32767
552; FIXME: We can do better than this by using selccz to choose between +0 and +2
553; 32-CMP-DAG:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
554; 32-CMP-DAG:  selnez $[[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, 32767
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, 32767
565; FIXME: We can do better than this by using selccz to choose between +0 and +2
566; 64-CMP-DAG:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
567; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
568; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
569
570define i32 @sltiu0(i32 signext %a) {
571entry:
572  %cmp = icmp ugt i32 %a, 32766
573  %cond = select i1 %cmp, i32 3, i32 5
574  ret i32 %cond
575}
576
577; ALL-LABEL: sltiu1:
578
579; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
580; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
581; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
582; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
583; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
584
585; 32-CMP-DAG:  addiu $[[I7:[0-9]+]], $zero, 7
586; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
587; 32-CMP-DAG:  addiu $[[I32767:[0-9]+]], $zero, 32767
588; 32-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[I32767]], $4
589; FIXME: We can do better than this by using selccz to choose between -0 and -2
590; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
591; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
592; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
593
594; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7
595; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
596; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767
597; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
598; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]]
599
600; 64-CMP-DAG:  addiu $[[I7:[0-9]+]], $zero, 7
601; 64-CMP-DAG:  addiu $[[I5:2]], $zero, 5
602; 64-CMP-DAG:  addiu $[[R1:[0-9]+]], $zero, 32767
603; 64-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[R1]], $4
604; FIXME: We can do better than this by using selccz to choose between -0 and -2
605; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]]
606; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
607; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
608
609define i32 @sltiu1(i32 signext %a) {
610entry:
611  %cmp = icmp ugt i32 %a, 32767
612  %cond = select i1 %cmp, i32 7, i32 5
613  ret i32 %cond
614}
615
616; ALL-LABEL: sltiu2:
617
618; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
619; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
620; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
621; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
622
623; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
624; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
625; 32-CMP-DAG:  sltiu $[[R0:[0-9]+]], $4, -32768
626; FIXME: We can do better than this by using selccz to choose between +0 and +2
627; 32-CMP-DAG:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
628; 32-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
629; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
630
631; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
632; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
633; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768
634; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]]
635
636; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
637; 64-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
638; 64-CMP-DAG:  sltiu $[[R0:[0-9]+]], $4, -32768
639; FIXME: We can do better than this by using selccz to choose between +0 and +2
640; 64-CMP-DAG:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
641; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
642; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
643
644define i32 @sltiu2(i32 signext %a) {
645entry:
646  %cmp = icmp ugt i32 %a, -32769
647  %cond = select i1 %cmp, i32 3, i32 5
648  ret i32 %cond
649}
650
651; ALL-LABEL: sltiu3:
652
653; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
654; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5
655; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
656; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
657; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
658; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
659
660; 32-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
661; 32-CMP-DAG:  addiu $[[I5:[0-9]+]], $zero, 5
662; 32-CMP-DAG:  lui $[[IMM:[0-9]+]], 65535
663; 32-CMP-DAG:  ori $[[IMM]], $[[IMM]], 32766
664; 32-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[I32767]], $4
665; FIXME: We can do better than this by using selccz to choose between -0 and -2
666; 32-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
667; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
668; 32-CMP-DAG:  or $2, $[[T0]], $[[T1]]
669
670; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3
671; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5
672; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535
673; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766
674; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4
675; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]]
676
677; 64-CMP-DAG:  addiu $[[I3:[0-9]+]], $zero, 3
678; 64-CMP-DAG:  addiu $[[I5:2]], $zero, 5
679; 64-CMP-DAG:  lui $[[IMM:[0-9]+]], 65535
680; 64-CMP-DAG:  ori $[[IMM]], $[[IMM]], 32766
681; 64-CMP-DAG:  sltu $[[R0:[0-9]+]], $[[IMM]], $4
682; FIXME: We can do better than this by using selccz to choose between -0 and -2
683; 64-CMP-DAG:  selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]]
684; 64-CMP-DAG:  seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]]
685; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
686
687define i32 @sltiu3(i32 signext %a) {
688entry:
689  %cmp = icmp ugt i32 %a, -32770
690  %cond = select i1 %cmp, i32 3, i32 5
691  ret i32 %cond
692}
693
694; Check if
695;  (select (setxx a, N), x, x-1) or
696;  (select (setxx a, N), x-1, x)
697; doesn't generate conditional moves
698; for constant operands whose difference is |1|
699
700define i32 @slti4(i32 signext %a) nounwind readnone {
701  %1 = icmp slt i32 %a, 7
702  %2 = select i1 %1, i32 4, i32 3
703  ret i32 %2
704}
705
706; ALL-LABEL: slti4:
707
708; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
709; 32-CMOV-DAG: addiu $2, [[R1]], 3
710; 32-CMOV-NOT: movn
711
712; 32-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
713; 32-CMP-DAG:  addiu $2, [[R1]], 3
714; 32-CMP-NOT:  seleqz
715; 32-CMP-NOT:  selnez
716
717; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
718; 64-CMOV-DAG: addiu $2, [[R1]], 3
719; 64-CMOV-NOT: movn
720
721; 64-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
722; 64-CMP-DAG:  addiu $2, [[R1]], 3
723; 64-CMP-NOT:  seleqz
724; 64-CMP-NOT:  selnez
725
726define i32 @slti5(i32 signext %a) nounwind readnone {
727  %1 = icmp slt i32 %a, 7
728  %2 = select i1 %1, i32 -3, i32 -4
729  ret i32 %2
730}
731
732; ALL-LABEL: slti5:
733
734; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
735; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
736; 32-CMOV-NOT: movn
737
738; 32-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
739; 32-CMP-DAG:  addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
740; 32-CMP-NOT:  seleqz
741; 32-CMP-NOT:  selnez
742
743; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7
744; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
745; 64-CMOV-NOT: movn
746
747; 64-CMP-DAG:  slti [[R1:\$[0-9]+]], $4, 7
748; 64-CMP-DAG:  addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4
749; 64-CMP-NOT:  seleqz
750; 64-CMP-NOT:  selnez
751
752define i32 @slti6(i32 signext %a) nounwind readnone {
753  %1 = icmp slt i32 %a, 7
754  %2 = select i1 %1, i32 3, i32 4
755  ret i32 %2
756}
757
758; ALL-LABEL: slti6:
759
760; ALL-DAG: addiu [[R1:\$[0-9]+]], $zero, 6
761; ALL-DAG: slt [[R1]], [[R1]], $4
762; ALL-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3
763; ALL-NOT: movn
764; ALL-NOT:  seleqz
765; ALL-NOT:  selnez
766