xref: /llvm-project/llvm/test/CodeGen/RISCV/select-cc.ll (revision 0cb7636a462a8d4209e2b6344304eb43f02853eb)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -disable-block-placement -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefixes=RV32I %s
4; RUN: llc -mtriple=riscv64 -disable-block-placement -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefixes=RV64I %s
6; RUN: llc -mtriple=riscv64 -mattr=+xmipscmove -verify-machineinstrs < %s \
7; RUN:   | FileCheck -check-prefix=RV64I-CCMOV %s
8
9define signext i32 @foo(i32 signext %a, ptr %b) nounwind {
10; RV32I-LABEL: foo:
11; RV32I:       # %bb.0:
12; RV32I-NEXT:    lw a2, 0(a1)
13; RV32I-NEXT:    beq a0, a2, .LBB0_2
14; RV32I-NEXT:  # %bb.1:
15; RV32I-NEXT:    mv a0, a2
16; RV32I-NEXT:  .LBB0_2:
17; RV32I-NEXT:    lw a2, 0(a1)
18; RV32I-NEXT:    bne a0, a2, .LBB0_4
19; RV32I-NEXT:  # %bb.3:
20; RV32I-NEXT:    mv a0, a2
21; RV32I-NEXT:  .LBB0_4:
22; RV32I-NEXT:    lw a2, 0(a1)
23; RV32I-NEXT:    bltu a2, a0, .LBB0_6
24; RV32I-NEXT:  # %bb.5:
25; RV32I-NEXT:    mv a0, a2
26; RV32I-NEXT:  .LBB0_6:
27; RV32I-NEXT:    lw a2, 0(a1)
28; RV32I-NEXT:    bgeu a0, a2, .LBB0_8
29; RV32I-NEXT:  # %bb.7:
30; RV32I-NEXT:    mv a0, a2
31; RV32I-NEXT:  .LBB0_8:
32; RV32I-NEXT:    lw a2, 0(a1)
33; RV32I-NEXT:    bltu a0, a2, .LBB0_10
34; RV32I-NEXT:  # %bb.9:
35; RV32I-NEXT:    mv a0, a2
36; RV32I-NEXT:  .LBB0_10:
37; RV32I-NEXT:    lw a2, 0(a1)
38; RV32I-NEXT:    bgeu a2, a0, .LBB0_12
39; RV32I-NEXT:  # %bb.11:
40; RV32I-NEXT:    mv a0, a2
41; RV32I-NEXT:  .LBB0_12:
42; RV32I-NEXT:    lw a2, 0(a1)
43; RV32I-NEXT:    blt a2, a0, .LBB0_14
44; RV32I-NEXT:  # %bb.13:
45; RV32I-NEXT:    mv a0, a2
46; RV32I-NEXT:  .LBB0_14:
47; RV32I-NEXT:    lw a2, 0(a1)
48; RV32I-NEXT:    bge a0, a2, .LBB0_16
49; RV32I-NEXT:  # %bb.15:
50; RV32I-NEXT:    mv a0, a2
51; RV32I-NEXT:  .LBB0_16:
52; RV32I-NEXT:    lw a2, 0(a1)
53; RV32I-NEXT:    blt a0, a2, .LBB0_18
54; RV32I-NEXT:  # %bb.17:
55; RV32I-NEXT:    mv a0, a2
56; RV32I-NEXT:  .LBB0_18:
57; RV32I-NEXT:    lw a2, 0(a1)
58; RV32I-NEXT:    bge a2, a0, .LBB0_20
59; RV32I-NEXT:  # %bb.19:
60; RV32I-NEXT:    mv a0, a2
61; RV32I-NEXT:  .LBB0_20:
62; RV32I-NEXT:    lw a2, 0(a1)
63; RV32I-NEXT:    blez a2, .LBB0_22
64; RV32I-NEXT:  # %bb.21:
65; RV32I-NEXT:    mv a0, a2
66; RV32I-NEXT:  .LBB0_22:
67; RV32I-NEXT:    lw a3, 0(a1)
68; RV32I-NEXT:    bgez a2, .LBB0_24
69; RV32I-NEXT:  # %bb.23:
70; RV32I-NEXT:    mv a0, a3
71; RV32I-NEXT:  .LBB0_24:
72; RV32I-NEXT:    lw a3, 0(a1)
73; RV32I-NEXT:    li a4, 1024
74; RV32I-NEXT:    blt a4, a3, .LBB0_26
75; RV32I-NEXT:  # %bb.25:
76; RV32I-NEXT:    mv a0, a3
77; RV32I-NEXT:  .LBB0_26:
78; RV32I-NEXT:    lw a1, 0(a1)
79; RV32I-NEXT:    li a3, 2046
80; RV32I-NEXT:    bltu a3, a2, .LBB0_28
81; RV32I-NEXT:  # %bb.27:
82; RV32I-NEXT:    mv a0, a1
83; RV32I-NEXT:  .LBB0_28:
84; RV32I-NEXT:    ret
85;
86; RV64I-LABEL: foo:
87; RV64I:       # %bb.0:
88; RV64I-NEXT:    lw a2, 0(a1)
89; RV64I-NEXT:    beq a0, a2, .LBB0_2
90; RV64I-NEXT:  # %bb.1:
91; RV64I-NEXT:    mv a0, a2
92; RV64I-NEXT:  .LBB0_2:
93; RV64I-NEXT:    lw a2, 0(a1)
94; RV64I-NEXT:    bne a0, a2, .LBB0_4
95; RV64I-NEXT:  # %bb.3:
96; RV64I-NEXT:    mv a0, a2
97; RV64I-NEXT:  .LBB0_4:
98; RV64I-NEXT:    lw a2, 0(a1)
99; RV64I-NEXT:    bltu a2, a0, .LBB0_6
100; RV64I-NEXT:  # %bb.5:
101; RV64I-NEXT:    mv a0, a2
102; RV64I-NEXT:  .LBB0_6:
103; RV64I-NEXT:    lw a2, 0(a1)
104; RV64I-NEXT:    bgeu a0, a2, .LBB0_8
105; RV64I-NEXT:  # %bb.7:
106; RV64I-NEXT:    mv a0, a2
107; RV64I-NEXT:  .LBB0_8:
108; RV64I-NEXT:    lw a2, 0(a1)
109; RV64I-NEXT:    bltu a0, a2, .LBB0_10
110; RV64I-NEXT:  # %bb.9:
111; RV64I-NEXT:    mv a0, a2
112; RV64I-NEXT:  .LBB0_10:
113; RV64I-NEXT:    lw a2, 0(a1)
114; RV64I-NEXT:    bgeu a2, a0, .LBB0_12
115; RV64I-NEXT:  # %bb.11:
116; RV64I-NEXT:    mv a0, a2
117; RV64I-NEXT:  .LBB0_12:
118; RV64I-NEXT:    lw a2, 0(a1)
119; RV64I-NEXT:    blt a2, a0, .LBB0_14
120; RV64I-NEXT:  # %bb.13:
121; RV64I-NEXT:    mv a0, a2
122; RV64I-NEXT:  .LBB0_14:
123; RV64I-NEXT:    lw a2, 0(a1)
124; RV64I-NEXT:    bge a0, a2, .LBB0_16
125; RV64I-NEXT:  # %bb.15:
126; RV64I-NEXT:    mv a0, a2
127; RV64I-NEXT:  .LBB0_16:
128; RV64I-NEXT:    lw a2, 0(a1)
129; RV64I-NEXT:    blt a0, a2, .LBB0_18
130; RV64I-NEXT:  # %bb.17:
131; RV64I-NEXT:    mv a0, a2
132; RV64I-NEXT:  .LBB0_18:
133; RV64I-NEXT:    lw a2, 0(a1)
134; RV64I-NEXT:    bge a2, a0, .LBB0_20
135; RV64I-NEXT:  # %bb.19:
136; RV64I-NEXT:    mv a0, a2
137; RV64I-NEXT:  .LBB0_20:
138; RV64I-NEXT:    lw a2, 0(a1)
139; RV64I-NEXT:    blez a2, .LBB0_22
140; RV64I-NEXT:  # %bb.21:
141; RV64I-NEXT:    mv a0, a2
142; RV64I-NEXT:  .LBB0_22:
143; RV64I-NEXT:    lw a3, 0(a1)
144; RV64I-NEXT:    bgez a2, .LBB0_24
145; RV64I-NEXT:  # %bb.23:
146; RV64I-NEXT:    mv a0, a3
147; RV64I-NEXT:  .LBB0_24:
148; RV64I-NEXT:    lw a3, 0(a1)
149; RV64I-NEXT:    li a4, 1024
150; RV64I-NEXT:    blt a4, a3, .LBB0_26
151; RV64I-NEXT:  # %bb.25:
152; RV64I-NEXT:    mv a0, a3
153; RV64I-NEXT:  .LBB0_26:
154; RV64I-NEXT:    lw a1, 0(a1)
155; RV64I-NEXT:    li a3, 2046
156; RV64I-NEXT:    bltu a3, a2, .LBB0_28
157; RV64I-NEXT:  # %bb.27:
158; RV64I-NEXT:    mv a0, a1
159; RV64I-NEXT:  .LBB0_28:
160; RV64I-NEXT:    ret
161;
162; RV64I-CCMOV-LABEL: foo:
163; RV64I-CCMOV:       # %bb.0:
164; RV64I-CCMOV-NEXT:    lw a2, 0(a1)
165; RV64I-CCMOV-NEXT:    lw a3, 0(a1)
166; RV64I-CCMOV-NEXT:    lw a4, 0(a1)
167; RV64I-CCMOV-NEXT:    lw a5, 0(a1)
168; RV64I-CCMOV-NEXT:    xor a6, a0, a2
169; RV64I-CCMOV-NEXT:    mips.ccmov a0, a6, a2, a0
170; RV64I-CCMOV-NEXT:    xor a2, a0, a3
171; RV64I-CCMOV-NEXT:    mips.ccmov a0, a2, a0, a3
172; RV64I-CCMOV-NEXT:    lw a2, 0(a1)
173; RV64I-CCMOV-NEXT:    sltu a3, a4, a0
174; RV64I-CCMOV-NEXT:    mips.ccmov a0, a3, a0, a4
175; RV64I-CCMOV-NEXT:    lw a3, 0(a1)
176; RV64I-CCMOV-NEXT:    sltu a4, a0, a5
177; RV64I-CCMOV-NEXT:    mips.ccmov a0, a4, a5, a0
178; RV64I-CCMOV-NEXT:    lw a4, 0(a1)
179; RV64I-CCMOV-NEXT:    sltu a5, a0, a2
180; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a0, a2
181; RV64I-CCMOV-NEXT:    lw a2, 0(a1)
182; RV64I-CCMOV-NEXT:    sltu a5, a3, a0
183; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a3, a0
184; RV64I-CCMOV-NEXT:    lw a3, 0(a1)
185; RV64I-CCMOV-NEXT:    sext.w a5, a0
186; RV64I-CCMOV-NEXT:    slt a5, a4, a5
187; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a0, a4
188; RV64I-CCMOV-NEXT:    lw a4, 0(a1)
189; RV64I-CCMOV-NEXT:    sext.w a5, a0
190; RV64I-CCMOV-NEXT:    slt a5, a5, a2
191; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a2, a0
192; RV64I-CCMOV-NEXT:    lw a2, 0(a1)
193; RV64I-CCMOV-NEXT:    sext.w a5, a0
194; RV64I-CCMOV-NEXT:    slt a5, a5, a3
195; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a0, a3
196; RV64I-CCMOV-NEXT:    lw a3, 0(a1)
197; RV64I-CCMOV-NEXT:    sext.w a5, a0
198; RV64I-CCMOV-NEXT:    slt a5, a4, a5
199; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a4, a0
200; RV64I-CCMOV-NEXT:    lw a4, 0(a1)
201; RV64I-CCMOV-NEXT:    slti a5, a2, 1
202; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a0, a2
203; RV64I-CCMOV-NEXT:    slti a5, a2, 0
204; RV64I-CCMOV-NEXT:    mips.ccmov a0, a5, a3, a0
205; RV64I-CCMOV-NEXT:    lw a1, 0(a1)
206; RV64I-CCMOV-NEXT:    slti a3, a4, 1025
207; RV64I-CCMOV-NEXT:    mips.ccmov a0, a3, a4, a0
208; RV64I-CCMOV-NEXT:    sltiu a2, a2, 2047
209; RV64I-CCMOV-NEXT:    mips.ccmov a0, a2, a1, a0
210; RV64I-CCMOV-NEXT:    sext.w a0, a0
211; RV64I-CCMOV-NEXT:    ret
212  %val1 = load volatile i32, ptr %b
213  %tst1 = icmp eq i32 %a, %val1
214  %val2 = select i1 %tst1, i32 %a, i32 %val1
215
216  %val3 = load volatile i32, ptr %b
217  %tst2 = icmp ne i32 %val2, %val3
218  %val4 = select i1 %tst2, i32 %val2, i32 %val3
219
220  %val5 = load volatile i32, ptr %b
221  %tst3 = icmp ugt i32 %val4, %val5
222  %val6 = select i1 %tst3, i32 %val4, i32 %val5
223
224  %val7 = load volatile i32, ptr %b
225  %tst4 = icmp uge i32 %val6, %val7
226  %val8 = select i1 %tst4, i32 %val6, i32 %val7
227
228  %val9 = load volatile i32, ptr %b
229  %tst5 = icmp ult i32 %val8, %val9
230  %val10 = select i1 %tst5, i32 %val8, i32 %val9
231
232  %val11 = load volatile i32, ptr %b
233  %tst6 = icmp ule i32 %val10, %val11
234  %val12 = select i1 %tst6, i32 %val10, i32 %val11
235
236  %val13 = load volatile i32, ptr %b
237  %tst7 = icmp sgt i32 %val12, %val13
238  %val14 = select i1 %tst7, i32 %val12, i32 %val13
239
240  %val15 = load volatile i32, ptr %b
241  %tst8 = icmp sge i32 %val14, %val15
242  %val16 = select i1 %tst8, i32 %val14, i32 %val15
243
244  %val17 = load volatile i32, ptr %b
245  %tst9 = icmp slt i32 %val16, %val17
246  %val18 = select i1 %tst9, i32 %val16, i32 %val17
247
248  %val19 = load volatile i32, ptr %b
249  %tst10 = icmp sle i32 %val18, %val19
250  %val20 = select i1 %tst10, i32 %val18, i32 %val19
251
252  %val21 = load volatile i32, ptr %b
253  %tst11 = icmp slt i32 %val21, 1
254  %val22 = select i1 %tst11, i32 %val20, i32 %val21
255
256  %val23 = load volatile i32, ptr %b
257  %tst12 = icmp sgt i32 %val21, -1
258  %val24 = select i1 %tst12, i32 %val22, i32 %val23
259
260  %val25 = load volatile i32, ptr %b
261  %tst13 = icmp sgt i32 %val25, 1024
262  %val26 = select i1 %tst13, i32 %val24, i32 %val25
263
264  %val27 = load volatile i32, ptr %b
265  %tst14 = icmp ugt i32 %val21, 2046
266  %val28 = select i1 %tst14, i32 %val26, i32 %val27
267  ret i32 %val28
268}
269
270; Test that we can ComputeNumSignBits across basic blocks when the live out is
271; RISCVISD::SELECT_CC. There should be no slli+srai or sext.h in the output.
272define signext i16 @numsignbits(i16 signext %0, i16 signext %1, i16 signext %2, i16 signext %3) nounwind {
273; RV32I-LABEL: numsignbits:
274; RV32I:       # %bb.0:
275; RV32I-NEXT:    addi sp, sp, -16
276; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
277; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
278; RV32I-NEXT:    mv s0, a3
279; RV32I-NEXT:    beqz a0, .LBB1_2
280; RV32I-NEXT:  # %bb.1:
281; RV32I-NEXT:    mv s0, a2
282; RV32I-NEXT:  .LBB1_2:
283; RV32I-NEXT:    beqz a1, .LBB1_4
284; RV32I-NEXT:  # %bb.3:
285; RV32I-NEXT:    mv a0, s0
286; RV32I-NEXT:    call bar
287; RV32I-NEXT:  .LBB1_4:
288; RV32I-NEXT:    mv a0, s0
289; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
290; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
291; RV32I-NEXT:    addi sp, sp, 16
292; RV32I-NEXT:    ret
293;
294; RV64I-LABEL: numsignbits:
295; RV64I:       # %bb.0:
296; RV64I-NEXT:    addi sp, sp, -16
297; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
298; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
299; RV64I-NEXT:    mv s0, a3
300; RV64I-NEXT:    beqz a0, .LBB1_2
301; RV64I-NEXT:  # %bb.1:
302; RV64I-NEXT:    mv s0, a2
303; RV64I-NEXT:  .LBB1_2:
304; RV64I-NEXT:    beqz a1, .LBB1_4
305; RV64I-NEXT:  # %bb.3:
306; RV64I-NEXT:    mv a0, s0
307; RV64I-NEXT:    call bar
308; RV64I-NEXT:  .LBB1_4:
309; RV64I-NEXT:    mv a0, s0
310; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
311; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
312; RV64I-NEXT:    addi sp, sp, 16
313; RV64I-NEXT:    ret
314;
315; RV64I-CCMOV-LABEL: numsignbits:
316; RV64I-CCMOV:       # %bb.0:
317; RV64I-CCMOV-NEXT:    addi sp, sp, -16
318; RV64I-CCMOV-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
319; RV64I-CCMOV-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
320; RV64I-CCMOV-NEXT:    mips.ccmov s0, a0, a2, a3
321; RV64I-CCMOV-NEXT:    beqz a1, .LBB1_2
322; RV64I-CCMOV-NEXT:  # %bb.1:
323; RV64I-CCMOV-NEXT:    mv a0, s0
324; RV64I-CCMOV-NEXT:    call bar
325; RV64I-CCMOV-NEXT:  .LBB1_2:
326; RV64I-CCMOV-NEXT:    mv a0, s0
327; RV64I-CCMOV-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
328; RV64I-CCMOV-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
329; RV64I-CCMOV-NEXT:    addi sp, sp, 16
330; RV64I-CCMOV-NEXT:    ret
331  %5 = icmp eq i16 %0, 0
332  %6 = select i1 %5, i16 %3, i16 %2
333  %7 = icmp eq i16 %1, 0
334  br i1 %7, label %9, label %8
335
3368:                                                ; preds = %4
337  tail call void @bar(i16 signext %6)
338  br label %9
339
3409:                                                ; preds = %8, %4
341  ret i16 %6
342}
343
344declare void @bar(i16 signext)
345
346define i32 @select_sge_int16min(i32 signext %x, i32 signext %y, i32 signext %z) {
347; RV32I-LABEL: select_sge_int16min:
348; RV32I:       # %bb.0:
349; RV32I-NEXT:    lui a3, 1048560
350; RV32I-NEXT:    addi a3, a3, -1
351; RV32I-NEXT:    blt a3, a0, .LBB2_2
352; RV32I-NEXT:  # %bb.1:
353; RV32I-NEXT:    mv a1, a2
354; RV32I-NEXT:  .LBB2_2:
355; RV32I-NEXT:    mv a0, a1
356; RV32I-NEXT:    ret
357;
358; RV64I-LABEL: select_sge_int16min:
359; RV64I:       # %bb.0:
360; RV64I-NEXT:    lui a3, 1048560
361; RV64I-NEXT:    addiw a3, a3, -1
362; RV64I-NEXT:    blt a3, a0, .LBB2_2
363; RV64I-NEXT:  # %bb.1:
364; RV64I-NEXT:    mv a1, a2
365; RV64I-NEXT:  .LBB2_2:
366; RV64I-NEXT:    mv a0, a1
367; RV64I-NEXT:    ret
368;
369; RV64I-CCMOV-LABEL: select_sge_int16min:
370; RV64I-CCMOV:       # %bb.0:
371; RV64I-CCMOV-NEXT:    lui a3, 1048560
372; RV64I-CCMOV-NEXT:    addiw a3, a3, -1
373; RV64I-CCMOV-NEXT:    slt a0, a3, a0
374; RV64I-CCMOV-NEXT:    mips.ccmov a0, a0, a1, a2
375; RV64I-CCMOV-NEXT:    ret
376  %a = icmp sge i32 %x, -65536
377  %b = select i1 %a, i32 %y, i32 %z
378  ret i32 %b
379}
380
381define i64 @select_sge_int32min(i64 %x, i64 %y, i64 %z) {
382; RV32I-LABEL: select_sge_int32min:
383; RV32I:       # %bb.0:
384; RV32I-NEXT:    li a6, -1
385; RV32I-NEXT:    bne a1, a6, .LBB3_2
386; RV32I-NEXT:  # %bb.1:
387; RV32I-NEXT:    slti a0, a0, 0
388; RV32I-NEXT:    j .LBB3_3
389; RV32I-NEXT:  .LBB3_2:
390; RV32I-NEXT:    slti a0, a1, 0
391; RV32I-NEXT:    xori a0, a0, 1
392; RV32I-NEXT:  .LBB3_3:
393; RV32I-NEXT:    bnez a0, .LBB3_5
394; RV32I-NEXT:  # %bb.4:
395; RV32I-NEXT:    mv a2, a4
396; RV32I-NEXT:    mv a3, a5
397; RV32I-NEXT:  .LBB3_5:
398; RV32I-NEXT:    mv a0, a2
399; RV32I-NEXT:    mv a1, a3
400; RV32I-NEXT:    ret
401;
402; RV64I-LABEL: select_sge_int32min:
403; RV64I:       # %bb.0:
404; RV64I-NEXT:    lui a3, 524288
405; RV64I-NEXT:    addi a3, a3, -1
406; RV64I-NEXT:    blt a3, a0, .LBB3_2
407; RV64I-NEXT:  # %bb.1:
408; RV64I-NEXT:    mv a1, a2
409; RV64I-NEXT:  .LBB3_2:
410; RV64I-NEXT:    mv a0, a1
411; RV64I-NEXT:    ret
412;
413; RV64I-CCMOV-LABEL: select_sge_int32min:
414; RV64I-CCMOV:       # %bb.0:
415; RV64I-CCMOV-NEXT:    lui a3, 524288
416; RV64I-CCMOV-NEXT:    addi a3, a3, -1
417; RV64I-CCMOV-NEXT:    slt a0, a3, a0
418; RV64I-CCMOV-NEXT:    mips.ccmov a0, a0, a1, a2
419; RV64I-CCMOV-NEXT:    ret
420  %a = icmp sge i64 %x, -2147483648
421  %b = select i1 %a, i64 %y, i64 %z
422  ret i64 %b
423}
424