• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 %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 %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 %a, i32 %b, i32 %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: 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:  seleqz $[[T0:[0-9]+]], $6, $[[R0]]
135; 32-CMP-DAG:  seleqz $[[T1:[0-9]+]], $7, $[[R0]]
136; 32-CMP-DAG:  selnez $[[T2:[0-9]+]], $[[R1]], $[[R0]]
137; 32-CMP-DAG:  selnez $[[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:  seleqz $[[T0:[0-9]+]], $5, $[[R0]]
146; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $6, $[[R0]]
147; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
148
149define i64 @cmov4(i32 %a, i64 %b, i64 %c) nounwind readnone {
150entry:
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:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
176; 32-CMP-DAG:  selnez $[[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:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
189; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
190; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
191
192define i32 @slti0(i32 %a) {
193entry:
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
231define i32 @slti1(i32 %a) {
232entry:
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:  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, -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:  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 @slti2(i32 %a) {
267entry:
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
309define i32 @slti3(i32 %a) {
310entry:
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:   selnez $[[CC2:[0-9]+]], $[[CC0]], $4
333; 32-CMP-DAG:   seleqz $[[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:  seleqz $[[T0:[0-9]+]], $[[I5]], $[[R0]]
353; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]]
354; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
355
356define i64 @slti64_0(i64 %a) {
357entry:
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:   selnez $[[CC2:[0-9]+]], $[[CC0]], $4
378; 32-CMP-DAG:   seleqz $[[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
402define i64 @slti64_1(i64 %a) {
403entry:
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:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
427; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]]
428; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
429
430define i64 @slti64_2(i64 %a) {
431entry:
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
459define i64 @slti64_3(i64 %a) {
460entry:
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:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
480; 32-CMP-DAG:  selnez $[[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:  seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]]
493; 64-CMP-DAG:  selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]]
494; 64-CMP-DAG:  or $2, $[[T0]], $[[T1]]
495
496define i32 @sltiu0(i32 %a) {
497entry:
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
535define i32 @sltiu1(i32 %a) {
536entry:
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:  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, -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:  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 @sltiu2(i32 %a) {
571entry:
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
613define i32 @sltiu3(i32 %a) {
614entry:
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
626define 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
652define 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
678define 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
707