1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefix=RV32I %s
4; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefix=RV32IBT %s
6; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7; RUN:   | FileCheck -check-prefix=RV64I %s
8; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \
9; RUN:   | FileCheck -check-prefix=RV64IBT %s
10
11;; There are a few different ways to lower (select (or A, B), X, Y). This test
12;; ensures that we do so with as few branches as possible.
13
14define signext i32 @select_of_or(i1 zeroext %a, i1 zeroext %b, i32 signext %c, i32 signext %d) nounwind {
15; RV32I-LABEL: select_of_or:
16; RV32I:       # %bb.0:
17; RV32I-NEXT:    or a1, a0, a1
18; RV32I-NEXT:    mv a0, a2
19; RV32I-NEXT:    bnez a1, .LBB0_2
20; RV32I-NEXT:  # %bb.1:
21; RV32I-NEXT:    mv a0, a3
22; RV32I-NEXT:  .LBB0_2:
23; RV32I-NEXT:    ret
24;
25; RV32IBT-LABEL: select_of_or:
26; RV32IBT:       # %bb.0:
27; RV32IBT-NEXT:    or a0, a0, a1
28; RV32IBT-NEXT:    cmov a0, a0, a2, a3
29; RV32IBT-NEXT:    ret
30;
31; RV64I-LABEL: select_of_or:
32; RV64I:       # %bb.0:
33; RV64I-NEXT:    or a1, a0, a1
34; RV64I-NEXT:    mv a0, a2
35; RV64I-NEXT:    bnez a1, .LBB0_2
36; RV64I-NEXT:  # %bb.1:
37; RV64I-NEXT:    mv a0, a3
38; RV64I-NEXT:  .LBB0_2:
39; RV64I-NEXT:    ret
40;
41; RV64IBT-LABEL: select_of_or:
42; RV64IBT:       # %bb.0:
43; RV64IBT-NEXT:    or a0, a0, a1
44; RV64IBT-NEXT:    cmov a0, a0, a2, a3
45; RV64IBT-NEXT:    ret
46  %1 = or i1 %a, %b
47  %2 = select i1 %1, i32 %c, i32 %d
48  ret i32 %2
49}
50
51declare signext i32 @either() nounwind
52declare signext i32 @neither() nounwind
53
54define signext i32 @if_of_or(i1 zeroext %a, i1 zeroext %b) nounwind {
55; RV32I-LABEL: if_of_or:
56; RV32I:       # %bb.0:
57; RV32I-NEXT:    addi sp, sp, -16
58; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
59; RV32I-NEXT:    or a0, a0, a1
60; RV32I-NEXT:    beqz a0, .LBB1_2
61; RV32I-NEXT:  # %bb.1: # %if.then
62; RV32I-NEXT:    call either@plt
63; RV32I-NEXT:    j .LBB1_3
64; RV32I-NEXT:  .LBB1_2: # %if.else
65; RV32I-NEXT:    call neither@plt
66; RV32I-NEXT:  .LBB1_3: # %if.end
67; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
68; RV32I-NEXT:    addi sp, sp, 16
69; RV32I-NEXT:    ret
70;
71; RV32IBT-LABEL: if_of_or:
72; RV32IBT:       # %bb.0:
73; RV32IBT-NEXT:    addi sp, sp, -16
74; RV32IBT-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
75; RV32IBT-NEXT:    or a0, a0, a1
76; RV32IBT-NEXT:    beqz a0, .LBB1_2
77; RV32IBT-NEXT:  # %bb.1: # %if.then
78; RV32IBT-NEXT:    call either@plt
79; RV32IBT-NEXT:    j .LBB1_3
80; RV32IBT-NEXT:  .LBB1_2: # %if.else
81; RV32IBT-NEXT:    call neither@plt
82; RV32IBT-NEXT:  .LBB1_3: # %if.end
83; RV32IBT-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
84; RV32IBT-NEXT:    addi sp, sp, 16
85; RV32IBT-NEXT:    ret
86;
87; RV64I-LABEL: if_of_or:
88; RV64I:       # %bb.0:
89; RV64I-NEXT:    addi sp, sp, -16
90; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
91; RV64I-NEXT:    or a0, a0, a1
92; RV64I-NEXT:    beqz a0, .LBB1_2
93; RV64I-NEXT:  # %bb.1: # %if.then
94; RV64I-NEXT:    call either@plt
95; RV64I-NEXT:    j .LBB1_3
96; RV64I-NEXT:  .LBB1_2: # %if.else
97; RV64I-NEXT:    call neither@plt
98; RV64I-NEXT:  .LBB1_3: # %if.end
99; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
100; RV64I-NEXT:    addi sp, sp, 16
101; RV64I-NEXT:    ret
102;
103; RV64IBT-LABEL: if_of_or:
104; RV64IBT:       # %bb.0:
105; RV64IBT-NEXT:    addi sp, sp, -16
106; RV64IBT-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
107; RV64IBT-NEXT:    or a0, a0, a1
108; RV64IBT-NEXT:    beqz a0, .LBB1_2
109; RV64IBT-NEXT:  # %bb.1: # %if.then
110; RV64IBT-NEXT:    call either@plt
111; RV64IBT-NEXT:    j .LBB1_3
112; RV64IBT-NEXT:  .LBB1_2: # %if.else
113; RV64IBT-NEXT:    call neither@plt
114; RV64IBT-NEXT:  .LBB1_3: # %if.end
115; RV64IBT-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
116; RV64IBT-NEXT:    addi sp, sp, 16
117; RV64IBT-NEXT:    ret
118  %1 = or i1 %a, %b
119  br i1 %1, label %if.then, label %if.else
120
121if.then:
122  %2 = tail call i32 @either()
123  br label %if.end
124
125if.else:
126  %3 = tail call i32 @neither()
127  br label %if.end
128
129if.end:
130  %4 = phi i32 [%2, %if.then], [%3, %if.else]
131  ret i32 %4
132}
133