1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefix=RV32I
4; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-zbt -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefix=RV32IBT
6; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
7; RUN:   | FileCheck %s -check-prefix=RV64I
8; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-zbt -verify-machineinstrs < %s \
9; RUN:   | FileCheck %s -check-prefix=RV64IBT
10
11; Selects of wide values are split into two selects, which can easily cause
12; unnecessary control flow. Here we check some cases where we can currently
13; emit a sequence of selects with shared control flow.
14
15define i64 @cmovcc64(i32 signext %a, i64 %b, i64 %c) nounwind {
16; RV32I-LABEL: cmovcc64:
17; RV32I:       # %bb.0: # %entry
18; RV32I-NEXT:    addi a5, zero, 123
19; RV32I-NEXT:    beq a0, a5, .LBB0_2
20; RV32I-NEXT:  # %bb.1: # %entry
21; RV32I-NEXT:    mv a1, a3
22; RV32I-NEXT:    mv a2, a4
23; RV32I-NEXT:  .LBB0_2: # %entry
24; RV32I-NEXT:    mv a0, a1
25; RV32I-NEXT:    mv a1, a2
26; RV32I-NEXT:    ret
27;
28; RV32IBT-LABEL: cmovcc64:
29; RV32IBT:       # %bb.0: # %entry
30; RV32IBT-NEXT:    addi a5, zero, 123
31; RV32IBT-NEXT:    beq a0, a5, .LBB0_2
32; RV32IBT-NEXT:  # %bb.1: # %entry
33; RV32IBT-NEXT:    mv a1, a3
34; RV32IBT-NEXT:    mv a2, a4
35; RV32IBT-NEXT:  .LBB0_2: # %entry
36; RV32IBT-NEXT:    mv a0, a1
37; RV32IBT-NEXT:    mv a1, a2
38; RV32IBT-NEXT:    ret
39;
40; RV64I-LABEL: cmovcc64:
41; RV64I:       # %bb.0: # %entry
42; RV64I-NEXT:    addi a3, zero, 123
43; RV64I-NEXT:    beq a0, a3, .LBB0_2
44; RV64I-NEXT:  # %bb.1: # %entry
45; RV64I-NEXT:    mv a1, a2
46; RV64I-NEXT:  .LBB0_2: # %entry
47; RV64I-NEXT:    mv a0, a1
48; RV64I-NEXT:    ret
49;
50; RV64IBT-LABEL: cmovcc64:
51; RV64IBT:       # %bb.0: # %entry
52; RV64IBT-NEXT:    addi a3, zero, 123
53; RV64IBT-NEXT:    beq a0, a3, .LBB0_2
54; RV64IBT-NEXT:  # %bb.1: # %entry
55; RV64IBT-NEXT:    mv a1, a2
56; RV64IBT-NEXT:  .LBB0_2: # %entry
57; RV64IBT-NEXT:    mv a0, a1
58; RV64IBT-NEXT:    ret
59entry:
60  %cmp = icmp eq i32 %a, 123
61  %cond = select i1 %cmp, i64 %b, i64 %c
62  ret i64 %cond
63}
64
65define i128 @cmovcc128(i64 signext %a, i128 %b, i128 %c) nounwind {
66; RV32I-LABEL: cmovcc128:
67; RV32I:       # %bb.0: # %entry
68; RV32I-NEXT:    xori a1, a1, 123
69; RV32I-NEXT:    or a1, a1, a2
70; RV32I-NEXT:    mv a2, a3
71; RV32I-NEXT:    beqz a1, .LBB1_2
72; RV32I-NEXT:  # %bb.1: # %entry
73; RV32I-NEXT:    mv a2, a4
74; RV32I-NEXT:  .LBB1_2: # %entry
75; RV32I-NEXT:    beqz a1, .LBB1_5
76; RV32I-NEXT:  # %bb.3: # %entry
77; RV32I-NEXT:    addi a7, a4, 4
78; RV32I-NEXT:    bnez a1, .LBB1_6
79; RV32I-NEXT:  .LBB1_4:
80; RV32I-NEXT:    addi a5, a3, 8
81; RV32I-NEXT:    j .LBB1_7
82; RV32I-NEXT:  .LBB1_5:
83; RV32I-NEXT:    addi a7, a3, 4
84; RV32I-NEXT:    beqz a1, .LBB1_4
85; RV32I-NEXT:  .LBB1_6: # %entry
86; RV32I-NEXT:    addi a5, a4, 8
87; RV32I-NEXT:  .LBB1_7: # %entry
88; RV32I-NEXT:    lw a6, 0(a2)
89; RV32I-NEXT:    lw a7, 0(a7)
90; RV32I-NEXT:    lw a2, 0(a5)
91; RV32I-NEXT:    beqz a1, .LBB1_9
92; RV32I-NEXT:  # %bb.8: # %entry
93; RV32I-NEXT:    addi a1, a4, 12
94; RV32I-NEXT:    j .LBB1_10
95; RV32I-NEXT:  .LBB1_9:
96; RV32I-NEXT:    addi a1, a3, 12
97; RV32I-NEXT:  .LBB1_10: # %entry
98; RV32I-NEXT:    lw a1, 0(a1)
99; RV32I-NEXT:    sw a1, 12(a0)
100; RV32I-NEXT:    sw a2, 8(a0)
101; RV32I-NEXT:    sw a7, 4(a0)
102; RV32I-NEXT:    sw a6, 0(a0)
103; RV32I-NEXT:    ret
104;
105; RV32IBT-LABEL: cmovcc128:
106; RV32IBT:       # %bb.0: # %entry
107; RV32IBT-NEXT:    addi a6, a3, 12
108; RV32IBT-NEXT:    addi a7, a4, 12
109; RV32IBT-NEXT:    addi t0, a3, 8
110; RV32IBT-NEXT:    addi t1, a4, 8
111; RV32IBT-NEXT:    addi t2, a3, 4
112; RV32IBT-NEXT:    addi a5, a4, 4
113; RV32IBT-NEXT:    xori a1, a1, 123
114; RV32IBT-NEXT:    or a1, a1, a2
115; RV32IBT-NEXT:    cmov a2, a1, a4, a3
116; RV32IBT-NEXT:    cmov a3, a1, a5, t2
117; RV32IBT-NEXT:    cmov a4, a1, t1, t0
118; RV32IBT-NEXT:    cmov a1, a1, a7, a6
119; RV32IBT-NEXT:    lw a1, 0(a1)
120; RV32IBT-NEXT:    lw a4, 0(a4)
121; RV32IBT-NEXT:    lw a3, 0(a3)
122; RV32IBT-NEXT:    lw a2, 0(a2)
123; RV32IBT-NEXT:    sw a1, 12(a0)
124; RV32IBT-NEXT:    sw a4, 8(a0)
125; RV32IBT-NEXT:    sw a3, 4(a0)
126; RV32IBT-NEXT:    sw a2, 0(a0)
127; RV32IBT-NEXT:    ret
128;
129; RV64I-LABEL: cmovcc128:
130; RV64I:       # %bb.0: # %entry
131; RV64I-NEXT:    addi a5, zero, 123
132; RV64I-NEXT:    beq a0, a5, .LBB1_2
133; RV64I-NEXT:  # %bb.1: # %entry
134; RV64I-NEXT:    mv a1, a3
135; RV64I-NEXT:    mv a2, a4
136; RV64I-NEXT:  .LBB1_2: # %entry
137; RV64I-NEXT:    mv a0, a1
138; RV64I-NEXT:    mv a1, a2
139; RV64I-NEXT:    ret
140;
141; RV64IBT-LABEL: cmovcc128:
142; RV64IBT:       # %bb.0: # %entry
143; RV64IBT-NEXT:    addi a5, zero, 123
144; RV64IBT-NEXT:    beq a0, a5, .LBB1_2
145; RV64IBT-NEXT:  # %bb.1: # %entry
146; RV64IBT-NEXT:    mv a1, a3
147; RV64IBT-NEXT:    mv a2, a4
148; RV64IBT-NEXT:  .LBB1_2: # %entry
149; RV64IBT-NEXT:    mv a0, a1
150; RV64IBT-NEXT:    mv a1, a2
151; RV64IBT-NEXT:    ret
152entry:
153  %cmp = icmp eq i64 %a, 123
154  %cond = select i1 %cmp, i128 %b, i128 %c
155  ret i128 %cond
156}
157
158define i64 @cmov64(i1 %a, i64 %b, i64 %c) nounwind {
159; RV32I-LABEL: cmov64:
160; RV32I:       # %bb.0: # %entry
161; RV32I-NEXT:    andi a5, a0, 1
162; RV32I-NEXT:    mv a0, a1
163; RV32I-NEXT:    bnez a5, .LBB2_2
164; RV32I-NEXT:  # %bb.1: # %entry
165; RV32I-NEXT:    mv a0, a3
166; RV32I-NEXT:    mv a2, a4
167; RV32I-NEXT:  .LBB2_2: # %entry
168; RV32I-NEXT:    mv a1, a2
169; RV32I-NEXT:    ret
170;
171; RV32IBT-LABEL: cmov64:
172; RV32IBT:       # %bb.0: # %entry
173; RV32IBT-NEXT:    andi a5, a0, 1
174; RV32IBT-NEXT:    mv a0, a1
175; RV32IBT-NEXT:    bnez a5, .LBB2_2
176; RV32IBT-NEXT:  # %bb.1: # %entry
177; RV32IBT-NEXT:    mv a0, a3
178; RV32IBT-NEXT:    mv a2, a4
179; RV32IBT-NEXT:  .LBB2_2: # %entry
180; RV32IBT-NEXT:    mv a1, a2
181; RV32IBT-NEXT:    ret
182;
183; RV64I-LABEL: cmov64:
184; RV64I:       # %bb.0: # %entry
185; RV64I-NEXT:    andi a3, a0, 1
186; RV64I-NEXT:    mv a0, a1
187; RV64I-NEXT:    bnez a3, .LBB2_2
188; RV64I-NEXT:  # %bb.1: # %entry
189; RV64I-NEXT:    mv a0, a2
190; RV64I-NEXT:  .LBB2_2: # %entry
191; RV64I-NEXT:    ret
192;
193; RV64IBT-LABEL: cmov64:
194; RV64IBT:       # %bb.0: # %entry
195; RV64IBT-NEXT:    andi a3, a0, 1
196; RV64IBT-NEXT:    mv a0, a1
197; RV64IBT-NEXT:    bnez a3, .LBB2_2
198; RV64IBT-NEXT:  # %bb.1: # %entry
199; RV64IBT-NEXT:    mv a0, a2
200; RV64IBT-NEXT:  .LBB2_2: # %entry
201; RV64IBT-NEXT:    ret
202entry:
203  %cond = select i1 %a, i64 %b, i64 %c
204  ret i64 %cond
205}
206
207define i128 @cmov128(i1 %a, i128 %b, i128 %c) nounwind {
208; RV32I-LABEL: cmov128:
209; RV32I:       # %bb.0: # %entry
210; RV32I-NEXT:    andi a1, a1, 1
211; RV32I-NEXT:    mv a4, a2
212; RV32I-NEXT:    bnez a1, .LBB3_2
213; RV32I-NEXT:  # %bb.1: # %entry
214; RV32I-NEXT:    mv a4, a3
215; RV32I-NEXT:  .LBB3_2: # %entry
216; RV32I-NEXT:    bnez a1, .LBB3_5
217; RV32I-NEXT:  # %bb.3: # %entry
218; RV32I-NEXT:    addi a7, a3, 4
219; RV32I-NEXT:    beqz a1, .LBB3_6
220; RV32I-NEXT:  .LBB3_4:
221; RV32I-NEXT:    addi a5, a2, 8
222; RV32I-NEXT:    j .LBB3_7
223; RV32I-NEXT:  .LBB3_5:
224; RV32I-NEXT:    addi a7, a2, 4
225; RV32I-NEXT:    bnez a1, .LBB3_4
226; RV32I-NEXT:  .LBB3_6: # %entry
227; RV32I-NEXT:    addi a5, a3, 8
228; RV32I-NEXT:  .LBB3_7: # %entry
229; RV32I-NEXT:    lw a6, 0(a4)
230; RV32I-NEXT:    lw a7, 0(a7)
231; RV32I-NEXT:    lw a4, 0(a5)
232; RV32I-NEXT:    bnez a1, .LBB3_9
233; RV32I-NEXT:  # %bb.8: # %entry
234; RV32I-NEXT:    addi a1, a3, 12
235; RV32I-NEXT:    j .LBB3_10
236; RV32I-NEXT:  .LBB3_9:
237; RV32I-NEXT:    addi a1, a2, 12
238; RV32I-NEXT:  .LBB3_10: # %entry
239; RV32I-NEXT:    lw a1, 0(a1)
240; RV32I-NEXT:    sw a1, 12(a0)
241; RV32I-NEXT:    sw a4, 8(a0)
242; RV32I-NEXT:    sw a7, 4(a0)
243; RV32I-NEXT:    sw a6, 0(a0)
244; RV32I-NEXT:    ret
245;
246; RV32IBT-LABEL: cmov128:
247; RV32IBT:       # %bb.0: # %entry
248; RV32IBT-NEXT:    andi a1, a1, 1
249; RV32IBT-NEXT:    mv a4, a2
250; RV32IBT-NEXT:    bnez a1, .LBB3_2
251; RV32IBT-NEXT:  # %bb.1: # %entry
252; RV32IBT-NEXT:    mv a4, a3
253; RV32IBT-NEXT:  .LBB3_2: # %entry
254; RV32IBT-NEXT:    bnez a1, .LBB3_5
255; RV32IBT-NEXT:  # %bb.3: # %entry
256; RV32IBT-NEXT:    addi a7, a3, 4
257; RV32IBT-NEXT:    beqz a1, .LBB3_6
258; RV32IBT-NEXT:  .LBB3_4:
259; RV32IBT-NEXT:    addi a5, a2, 8
260; RV32IBT-NEXT:    j .LBB3_7
261; RV32IBT-NEXT:  .LBB3_5:
262; RV32IBT-NEXT:    addi a7, a2, 4
263; RV32IBT-NEXT:    bnez a1, .LBB3_4
264; RV32IBT-NEXT:  .LBB3_6: # %entry
265; RV32IBT-NEXT:    addi a5, a3, 8
266; RV32IBT-NEXT:  .LBB3_7: # %entry
267; RV32IBT-NEXT:    lw a6, 0(a4)
268; RV32IBT-NEXT:    lw a7, 0(a7)
269; RV32IBT-NEXT:    lw a4, 0(a5)
270; RV32IBT-NEXT:    bnez a1, .LBB3_9
271; RV32IBT-NEXT:  # %bb.8: # %entry
272; RV32IBT-NEXT:    addi a1, a3, 12
273; RV32IBT-NEXT:    j .LBB3_10
274; RV32IBT-NEXT:  .LBB3_9:
275; RV32IBT-NEXT:    addi a1, a2, 12
276; RV32IBT-NEXT:  .LBB3_10: # %entry
277; RV32IBT-NEXT:    lw a1, 0(a1)
278; RV32IBT-NEXT:    sw a1, 12(a0)
279; RV32IBT-NEXT:    sw a4, 8(a0)
280; RV32IBT-NEXT:    sw a7, 4(a0)
281; RV32IBT-NEXT:    sw a6, 0(a0)
282; RV32IBT-NEXT:    ret
283;
284; RV64I-LABEL: cmov128:
285; RV64I:       # %bb.0: # %entry
286; RV64I-NEXT:    andi a5, a0, 1
287; RV64I-NEXT:    mv a0, a1
288; RV64I-NEXT:    bnez a5, .LBB3_2
289; RV64I-NEXT:  # %bb.1: # %entry
290; RV64I-NEXT:    mv a0, a3
291; RV64I-NEXT:    mv a2, a4
292; RV64I-NEXT:  .LBB3_2: # %entry
293; RV64I-NEXT:    mv a1, a2
294; RV64I-NEXT:    ret
295;
296; RV64IBT-LABEL: cmov128:
297; RV64IBT:       # %bb.0: # %entry
298; RV64IBT-NEXT:    andi a5, a0, 1
299; RV64IBT-NEXT:    mv a0, a1
300; RV64IBT-NEXT:    bnez a5, .LBB3_2
301; RV64IBT-NEXT:  # %bb.1: # %entry
302; RV64IBT-NEXT:    mv a0, a3
303; RV64IBT-NEXT:    mv a2, a4
304; RV64IBT-NEXT:  .LBB3_2: # %entry
305; RV64IBT-NEXT:    mv a1, a2
306; RV64IBT-NEXT:    ret
307entry:
308  %cond = select i1 %a, i128 %b, i128 %c
309  ret i128 %cond
310}
311
312define float @cmovfloat(i1 %a, float %b, float %c, float %d, float %e) nounwind {
313; RV32I-LABEL: cmovfloat:
314; RV32I:       # %bb.0: # %entry
315; RV32I-NEXT:    andi a0, a0, 1
316; RV32I-NEXT:    bnez a0, .LBB4_2
317; RV32I-NEXT:  # %bb.1: # %entry
318; RV32I-NEXT:    fmv.w.x ft0, a4
319; RV32I-NEXT:    fmv.w.x ft1, a2
320; RV32I-NEXT:    j .LBB4_3
321; RV32I-NEXT:  .LBB4_2:
322; RV32I-NEXT:    fmv.w.x ft0, a3
323; RV32I-NEXT:    fmv.w.x ft1, a1
324; RV32I-NEXT:  .LBB4_3: # %entry
325; RV32I-NEXT:    fadd.s ft0, ft1, ft0
326; RV32I-NEXT:    fmv.x.w a0, ft0
327; RV32I-NEXT:    ret
328;
329; RV32IBT-LABEL: cmovfloat:
330; RV32IBT:       # %bb.0: # %entry
331; RV32IBT-NEXT:    andi a0, a0, 1
332; RV32IBT-NEXT:    bnez a0, .LBB4_2
333; RV32IBT-NEXT:  # %bb.1: # %entry
334; RV32IBT-NEXT:    fmv.w.x ft0, a4
335; RV32IBT-NEXT:    fmv.w.x ft1, a2
336; RV32IBT-NEXT:    j .LBB4_3
337; RV32IBT-NEXT:  .LBB4_2:
338; RV32IBT-NEXT:    fmv.w.x ft0, a3
339; RV32IBT-NEXT:    fmv.w.x ft1, a1
340; RV32IBT-NEXT:  .LBB4_3: # %entry
341; RV32IBT-NEXT:    fadd.s ft0, ft1, ft0
342; RV32IBT-NEXT:    fmv.x.w a0, ft0
343; RV32IBT-NEXT:    ret
344;
345; RV64I-LABEL: cmovfloat:
346; RV64I:       # %bb.0: # %entry
347; RV64I-NEXT:    andi a0, a0, 1
348; RV64I-NEXT:    bnez a0, .LBB4_2
349; RV64I-NEXT:  # %bb.1: # %entry
350; RV64I-NEXT:    fmv.w.x ft0, a4
351; RV64I-NEXT:    fmv.w.x ft1, a2
352; RV64I-NEXT:    j .LBB4_3
353; RV64I-NEXT:  .LBB4_2:
354; RV64I-NEXT:    fmv.w.x ft0, a3
355; RV64I-NEXT:    fmv.w.x ft1, a1
356; RV64I-NEXT:  .LBB4_3: # %entry
357; RV64I-NEXT:    fadd.s ft0, ft1, ft0
358; RV64I-NEXT:    fmv.x.w a0, ft0
359; RV64I-NEXT:    ret
360;
361; RV64IBT-LABEL: cmovfloat:
362; RV64IBT:       # %bb.0: # %entry
363; RV64IBT-NEXT:    andi a0, a0, 1
364; RV64IBT-NEXT:    bnez a0, .LBB4_2
365; RV64IBT-NEXT:  # %bb.1: # %entry
366; RV64IBT-NEXT:    fmv.w.x ft0, a4
367; RV64IBT-NEXT:    fmv.w.x ft1, a2
368; RV64IBT-NEXT:    j .LBB4_3
369; RV64IBT-NEXT:  .LBB4_2:
370; RV64IBT-NEXT:    fmv.w.x ft0, a3
371; RV64IBT-NEXT:    fmv.w.x ft1, a1
372; RV64IBT-NEXT:  .LBB4_3: # %entry
373; RV64IBT-NEXT:    fadd.s ft0, ft1, ft0
374; RV64IBT-NEXT:    fmv.x.w a0, ft0
375; RV64IBT-NEXT:    ret
376entry:
377  %cond1 = select i1 %a, float %b, float %c
378  %cond2 = select i1 %a, float %d, float %e
379  %ret = fadd float %cond1, %cond2
380  ret float %ret
381}
382
383define double @cmovdouble(i1 %a, double %b, double %c) nounwind {
384; RV32I-LABEL: cmovdouble:
385; RV32I:       # %bb.0: # %entry
386; RV32I-NEXT:    addi sp, sp, -16
387; RV32I-NEXT:    sw a3, 8(sp)
388; RV32I-NEXT:    sw a4, 12(sp)
389; RV32I-NEXT:    fld ft0, 8(sp)
390; RV32I-NEXT:    sw a1, 8(sp)
391; RV32I-NEXT:    andi a0, a0, 1
392; RV32I-NEXT:    sw a2, 12(sp)
393; RV32I-NEXT:    beqz a0, .LBB5_2
394; RV32I-NEXT:  # %bb.1:
395; RV32I-NEXT:    fld ft0, 8(sp)
396; RV32I-NEXT:  .LBB5_2: # %entry
397; RV32I-NEXT:    fsd ft0, 8(sp)
398; RV32I-NEXT:    lw a0, 8(sp)
399; RV32I-NEXT:    lw a1, 12(sp)
400; RV32I-NEXT:    addi sp, sp, 16
401; RV32I-NEXT:    ret
402;
403; RV32IBT-LABEL: cmovdouble:
404; RV32IBT:       # %bb.0: # %entry
405; RV32IBT-NEXT:    addi sp, sp, -16
406; RV32IBT-NEXT:    sw a3, 8(sp)
407; RV32IBT-NEXT:    sw a4, 12(sp)
408; RV32IBT-NEXT:    fld ft0, 8(sp)
409; RV32IBT-NEXT:    sw a1, 8(sp)
410; RV32IBT-NEXT:    andi a0, a0, 1
411; RV32IBT-NEXT:    sw a2, 12(sp)
412; RV32IBT-NEXT:    beqz a0, .LBB5_2
413; RV32IBT-NEXT:  # %bb.1:
414; RV32IBT-NEXT:    fld ft0, 8(sp)
415; RV32IBT-NEXT:  .LBB5_2: # %entry
416; RV32IBT-NEXT:    fsd ft0, 8(sp)
417; RV32IBT-NEXT:    lw a0, 8(sp)
418; RV32IBT-NEXT:    lw a1, 12(sp)
419; RV32IBT-NEXT:    addi sp, sp, 16
420; RV32IBT-NEXT:    ret
421;
422; RV64I-LABEL: cmovdouble:
423; RV64I:       # %bb.0: # %entry
424; RV64I-NEXT:    andi a0, a0, 1
425; RV64I-NEXT:    bnez a0, .LBB5_2
426; RV64I-NEXT:  # %bb.1: # %entry
427; RV64I-NEXT:    fmv.d.x ft0, a2
428; RV64I-NEXT:    fmv.x.d a0, ft0
429; RV64I-NEXT:    ret
430; RV64I-NEXT:  .LBB5_2:
431; RV64I-NEXT:    fmv.d.x ft0, a1
432; RV64I-NEXT:    fmv.x.d a0, ft0
433; RV64I-NEXT:    ret
434;
435; RV64IBT-LABEL: cmovdouble:
436; RV64IBT:       # %bb.0: # %entry
437; RV64IBT-NEXT:    andi a0, a0, 1
438; RV64IBT-NEXT:    bnez a0, .LBB5_2
439; RV64IBT-NEXT:  # %bb.1: # %entry
440; RV64IBT-NEXT:    fmv.d.x ft0, a2
441; RV64IBT-NEXT:    fmv.x.d a0, ft0
442; RV64IBT-NEXT:    ret
443; RV64IBT-NEXT:  .LBB5_2:
444; RV64IBT-NEXT:    fmv.d.x ft0, a1
445; RV64IBT-NEXT:    fmv.x.d a0, ft0
446; RV64IBT-NEXT:    ret
447entry:
448  %cond = select i1 %a, double %b, double %c
449  ret double %cond
450}
451
452; Check that selects with dependencies on previous ones aren't incorrectly
453; optimized.
454
455define i32 @cmovccdep(i32 signext %a, i32 %b, i32 %c, i32 %d) nounwind {
456; RV32I-LABEL: cmovccdep:
457; RV32I:       # %bb.0: # %entry
458; RV32I-NEXT:    addi a4, zero, 123
459; RV32I-NEXT:    bne a0, a4, .LBB6_3
460; RV32I-NEXT:  # %bb.1: # %entry
461; RV32I-NEXT:    mv a2, a1
462; RV32I-NEXT:    bne a0, a4, .LBB6_4
463; RV32I-NEXT:  .LBB6_2: # %entry
464; RV32I-NEXT:    add a0, a1, a2
465; RV32I-NEXT:    ret
466; RV32I-NEXT:  .LBB6_3: # %entry
467; RV32I-NEXT:    mv a1, a2
468; RV32I-NEXT:    mv a2, a1
469; RV32I-NEXT:    beq a0, a4, .LBB6_2
470; RV32I-NEXT:  .LBB6_4: # %entry
471; RV32I-NEXT:    mv a2, a3
472; RV32I-NEXT:    add a0, a1, a2
473; RV32I-NEXT:    ret
474;
475; RV32IBT-LABEL: cmovccdep:
476; RV32IBT:       # %bb.0: # %entry
477; RV32IBT-NEXT:    addi a4, zero, 123
478; RV32IBT-NEXT:    bne a0, a4, .LBB6_3
479; RV32IBT-NEXT:  # %bb.1: # %entry
480; RV32IBT-NEXT:    mv a2, a1
481; RV32IBT-NEXT:    bne a0, a4, .LBB6_4
482; RV32IBT-NEXT:  .LBB6_2: # %entry
483; RV32IBT-NEXT:    add a0, a1, a2
484; RV32IBT-NEXT:    ret
485; RV32IBT-NEXT:  .LBB6_3: # %entry
486; RV32IBT-NEXT:    mv a1, a2
487; RV32IBT-NEXT:    mv a2, a1
488; RV32IBT-NEXT:    beq a0, a4, .LBB6_2
489; RV32IBT-NEXT:  .LBB6_4: # %entry
490; RV32IBT-NEXT:    mv a2, a3
491; RV32IBT-NEXT:    add a0, a1, a2
492; RV32IBT-NEXT:    ret
493;
494; RV64I-LABEL: cmovccdep:
495; RV64I:       # %bb.0: # %entry
496; RV64I-NEXT:    addi a4, zero, 123
497; RV64I-NEXT:    bne a0, a4, .LBB6_3
498; RV64I-NEXT:  # %bb.1: # %entry
499; RV64I-NEXT:    mv a2, a1
500; RV64I-NEXT:    bne a0, a4, .LBB6_4
501; RV64I-NEXT:  .LBB6_2: # %entry
502; RV64I-NEXT:    addw a0, a1, a2
503; RV64I-NEXT:    ret
504; RV64I-NEXT:  .LBB6_3: # %entry
505; RV64I-NEXT:    mv a1, a2
506; RV64I-NEXT:    mv a2, a1
507; RV64I-NEXT:    beq a0, a4, .LBB6_2
508; RV64I-NEXT:  .LBB6_4: # %entry
509; RV64I-NEXT:    mv a2, a3
510; RV64I-NEXT:    addw a0, a1, a2
511; RV64I-NEXT:    ret
512;
513; RV64IBT-LABEL: cmovccdep:
514; RV64IBT:       # %bb.0: # %entry
515; RV64IBT-NEXT:    addi a4, zero, 123
516; RV64IBT-NEXT:    bne a0, a4, .LBB6_3
517; RV64IBT-NEXT:  # %bb.1: # %entry
518; RV64IBT-NEXT:    mv a2, a1
519; RV64IBT-NEXT:    bne a0, a4, .LBB6_4
520; RV64IBT-NEXT:  .LBB6_2: # %entry
521; RV64IBT-NEXT:    addw a0, a1, a2
522; RV64IBT-NEXT:    ret
523; RV64IBT-NEXT:  .LBB6_3: # %entry
524; RV64IBT-NEXT:    mv a1, a2
525; RV64IBT-NEXT:    mv a2, a1
526; RV64IBT-NEXT:    beq a0, a4, .LBB6_2
527; RV64IBT-NEXT:  .LBB6_4: # %entry
528; RV64IBT-NEXT:    mv a2, a3
529; RV64IBT-NEXT:    addw a0, a1, a2
530; RV64IBT-NEXT:    ret
531entry:
532  %cmp = icmp eq i32 %a, 123
533  %cond1 = select i1 %cmp, i32 %b, i32 %c
534  %cond2 = select i1 %cmp, i32 %cond1, i32 %d
535  %ret = add i32 %cond1, %cond2
536  ret i32 %ret
537}
538
539; Check that selects with different conditions aren't incorrectly optimized.
540
541define i32 @cmovdiffcc(i1 %a, i1 %b, i32 %c, i32 %d, i32 %e, i32 %f) nounwind {
542; RV32I-LABEL: cmovdiffcc:
543; RV32I:       # %bb.0: # %entry
544; RV32I-NEXT:    andi a0, a0, 1
545; RV32I-NEXT:    andi a1, a1, 1
546; RV32I-NEXT:    beqz a0, .LBB7_3
547; RV32I-NEXT:  # %bb.1: # %entry
548; RV32I-NEXT:    beqz a1, .LBB7_4
549; RV32I-NEXT:  .LBB7_2: # %entry
550; RV32I-NEXT:    add a0, a2, a4
551; RV32I-NEXT:    ret
552; RV32I-NEXT:  .LBB7_3: # %entry
553; RV32I-NEXT:    mv a2, a3
554; RV32I-NEXT:    bnez a1, .LBB7_2
555; RV32I-NEXT:  .LBB7_4: # %entry
556; RV32I-NEXT:    mv a4, a5
557; RV32I-NEXT:    add a0, a2, a4
558; RV32I-NEXT:    ret
559;
560; RV32IBT-LABEL: cmovdiffcc:
561; RV32IBT:       # %bb.0: # %entry
562; RV32IBT-NEXT:    andi a0, a0, 1
563; RV32IBT-NEXT:    andi a1, a1, 1
564; RV32IBT-NEXT:    beqz a0, .LBB7_3
565; RV32IBT-NEXT:  # %bb.1: # %entry
566; RV32IBT-NEXT:    beqz a1, .LBB7_4
567; RV32IBT-NEXT:  .LBB7_2: # %entry
568; RV32IBT-NEXT:    add a0, a2, a4
569; RV32IBT-NEXT:    ret
570; RV32IBT-NEXT:  .LBB7_3: # %entry
571; RV32IBT-NEXT:    mv a2, a3
572; RV32IBT-NEXT:    bnez a1, .LBB7_2
573; RV32IBT-NEXT:  .LBB7_4: # %entry
574; RV32IBT-NEXT:    mv a4, a5
575; RV32IBT-NEXT:    add a0, a2, a4
576; RV32IBT-NEXT:    ret
577;
578; RV64I-LABEL: cmovdiffcc:
579; RV64I:       # %bb.0: # %entry
580; RV64I-NEXT:    andi a0, a0, 1
581; RV64I-NEXT:    andi a1, a1, 1
582; RV64I-NEXT:    beqz a0, .LBB7_3
583; RV64I-NEXT:  # %bb.1: # %entry
584; RV64I-NEXT:    beqz a1, .LBB7_4
585; RV64I-NEXT:  .LBB7_2: # %entry
586; RV64I-NEXT:    addw a0, a2, a4
587; RV64I-NEXT:    ret
588; RV64I-NEXT:  .LBB7_3: # %entry
589; RV64I-NEXT:    mv a2, a3
590; RV64I-NEXT:    bnez a1, .LBB7_2
591; RV64I-NEXT:  .LBB7_4: # %entry
592; RV64I-NEXT:    mv a4, a5
593; RV64I-NEXT:    addw a0, a2, a4
594; RV64I-NEXT:    ret
595;
596; RV64IBT-LABEL: cmovdiffcc:
597; RV64IBT:       # %bb.0: # %entry
598; RV64IBT-NEXT:    andi a0, a0, 1
599; RV64IBT-NEXT:    andi a1, a1, 1
600; RV64IBT-NEXT:    beqz a0, .LBB7_3
601; RV64IBT-NEXT:  # %bb.1: # %entry
602; RV64IBT-NEXT:    beqz a1, .LBB7_4
603; RV64IBT-NEXT:  .LBB7_2: # %entry
604; RV64IBT-NEXT:    addw a0, a2, a4
605; RV64IBT-NEXT:    ret
606; RV64IBT-NEXT:  .LBB7_3: # %entry
607; RV64IBT-NEXT:    mv a2, a3
608; RV64IBT-NEXT:    bnez a1, .LBB7_2
609; RV64IBT-NEXT:  .LBB7_4: # %entry
610; RV64IBT-NEXT:    mv a4, a5
611; RV64IBT-NEXT:    addw a0, a2, a4
612; RV64IBT-NEXT:    ret
613entry:
614  %cond1 = select i1 %a, i32 %c, i32 %d
615  %cond2 = select i1 %b, i32 %e, i32 %f
616  %ret = add i32 %cond1, %cond2
617  ret i32 %ret
618}
619