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=+f -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefix=RV32IF %s
6; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \
7; RUN:   | FileCheck -check-prefix=RV32IBT %s
8; RUN: llc -mtriple=riscv32 -mattr=+f,+experimental-zbt -verify-machineinstrs < %s \
9; RUN:   | FileCheck -check-prefix=RV32IFBT %s
10; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
11; RUN:   | FileCheck -check-prefix=RV64I %s
12; RUN: llc -mtriple=riscv64 -mattr=+f,+d -verify-machineinstrs < %s \
13; RUN:   | FileCheck -check-prefix=RV64IFD %s
14; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \
15; RUN:   | FileCheck -check-prefix=RV64IBT %s
16; RUN: llc -mtriple=riscv64 -mattr=+f,+d,+experimental-zbt -verify-machineinstrs < %s \
17; RUN:   | FileCheck -check-prefix=RV64IFDBT %s
18
19;; This tests how good we are at materialising constants using `select`. The aim
20;; is that we do so without a branch if possible (at the moment our lowering of
21;; select always introduces a branch).
22;;
23;; Currently the hook `convertSelectOfConstantsToMath` only is useful when the
24;; constants are either 1 away from each other, or one is a power of two and
25;; the other is zero.
26
27define signext i32 @select_const_int_easy(i1 zeroext %a) nounwind {
28; RV32I-LABEL: select_const_int_easy:
29; RV32I:       # %bb.0:
30; RV32I-NEXT:    ret
31;
32; RV32IF-LABEL: select_const_int_easy:
33; RV32IF:       # %bb.0:
34; RV32IF-NEXT:    ret
35;
36; RV32IBT-LABEL: select_const_int_easy:
37; RV32IBT:       # %bb.0:
38; RV32IBT-NEXT:    ret
39;
40; RV32IFBT-LABEL: select_const_int_easy:
41; RV32IFBT:       # %bb.0:
42; RV32IFBT-NEXT:    ret
43;
44; RV64I-LABEL: select_const_int_easy:
45; RV64I:       # %bb.0:
46; RV64I-NEXT:    ret
47;
48; RV64IFD-LABEL: select_const_int_easy:
49; RV64IFD:       # %bb.0:
50; RV64IFD-NEXT:    ret
51;
52; RV64IBT-LABEL: select_const_int_easy:
53; RV64IBT:       # %bb.0:
54; RV64IBT-NEXT:    ret
55;
56; RV64IFDBT-LABEL: select_const_int_easy:
57; RV64IFDBT:       # %bb.0:
58; RV64IFDBT-NEXT:    ret
59  %1 = select i1 %a, i32 1, i32 0
60  ret i32 %1
61}
62
63define signext i32 @select_const_int_one_away(i1 zeroext %a) nounwind {
64; RV32I-LABEL: select_const_int_one_away:
65; RV32I:       # %bb.0:
66; RV32I-NEXT:    li a1, 4
67; RV32I-NEXT:    sub a0, a1, a0
68; RV32I-NEXT:    ret
69;
70; RV32IF-LABEL: select_const_int_one_away:
71; RV32IF:       # %bb.0:
72; RV32IF-NEXT:    li a1, 4
73; RV32IF-NEXT:    sub a0, a1, a0
74; RV32IF-NEXT:    ret
75;
76; RV32IBT-LABEL: select_const_int_one_away:
77; RV32IBT:       # %bb.0:
78; RV32IBT-NEXT:    li a1, 4
79; RV32IBT-NEXT:    sub a0, a1, a0
80; RV32IBT-NEXT:    ret
81;
82; RV32IFBT-LABEL: select_const_int_one_away:
83; RV32IFBT:       # %bb.0:
84; RV32IFBT-NEXT:    li a1, 4
85; RV32IFBT-NEXT:    sub a0, a1, a0
86; RV32IFBT-NEXT:    ret
87;
88; RV64I-LABEL: select_const_int_one_away:
89; RV64I:       # %bb.0:
90; RV64I-NEXT:    li a1, 4
91; RV64I-NEXT:    sub a0, a1, a0
92; RV64I-NEXT:    ret
93;
94; RV64IFD-LABEL: select_const_int_one_away:
95; RV64IFD:       # %bb.0:
96; RV64IFD-NEXT:    li a1, 4
97; RV64IFD-NEXT:    sub a0, a1, a0
98; RV64IFD-NEXT:    ret
99;
100; RV64IBT-LABEL: select_const_int_one_away:
101; RV64IBT:       # %bb.0:
102; RV64IBT-NEXT:    li a1, 4
103; RV64IBT-NEXT:    sub a0, a1, a0
104; RV64IBT-NEXT:    ret
105;
106; RV64IFDBT-LABEL: select_const_int_one_away:
107; RV64IFDBT:       # %bb.0:
108; RV64IFDBT-NEXT:    li a1, 4
109; RV64IFDBT-NEXT:    sub a0, a1, a0
110; RV64IFDBT-NEXT:    ret
111  %1 = select i1 %a, i32 3, i32 4
112  ret i32 %1
113}
114
115define signext i32 @select_const_int_pow2_zero(i1 zeroext %a) nounwind {
116; RV32I-LABEL: select_const_int_pow2_zero:
117; RV32I:       # %bb.0:
118; RV32I-NEXT:    slli a0, a0, 2
119; RV32I-NEXT:    ret
120;
121; RV32IF-LABEL: select_const_int_pow2_zero:
122; RV32IF:       # %bb.0:
123; RV32IF-NEXT:    slli a0, a0, 2
124; RV32IF-NEXT:    ret
125;
126; RV32IBT-LABEL: select_const_int_pow2_zero:
127; RV32IBT:       # %bb.0:
128; RV32IBT-NEXT:    slli a0, a0, 2
129; RV32IBT-NEXT:    ret
130;
131; RV32IFBT-LABEL: select_const_int_pow2_zero:
132; RV32IFBT:       # %bb.0:
133; RV32IFBT-NEXT:    slli a0, a0, 2
134; RV32IFBT-NEXT:    ret
135;
136; RV64I-LABEL: select_const_int_pow2_zero:
137; RV64I:       # %bb.0:
138; RV64I-NEXT:    slli a0, a0, 2
139; RV64I-NEXT:    ret
140;
141; RV64IFD-LABEL: select_const_int_pow2_zero:
142; RV64IFD:       # %bb.0:
143; RV64IFD-NEXT:    slli a0, a0, 2
144; RV64IFD-NEXT:    ret
145;
146; RV64IBT-LABEL: select_const_int_pow2_zero:
147; RV64IBT:       # %bb.0:
148; RV64IBT-NEXT:    slli a0, a0, 2
149; RV64IBT-NEXT:    ret
150;
151; RV64IFDBT-LABEL: select_const_int_pow2_zero:
152; RV64IFDBT:       # %bb.0:
153; RV64IFDBT-NEXT:    slli a0, a0, 2
154; RV64IFDBT-NEXT:    ret
155  %1 = select i1 %a, i32 4, i32 0
156  ret i32 %1
157}
158
159define signext i32 @select_const_int_harder(i1 zeroext %a) nounwind {
160; RV32I-LABEL: select_const_int_harder:
161; RV32I:       # %bb.0:
162; RV32I-NEXT:    mv a1, a0
163; RV32I-NEXT:    li a0, 6
164; RV32I-NEXT:    bnez a1, .LBB3_2
165; RV32I-NEXT:  # %bb.1:
166; RV32I-NEXT:    li a0, 38
167; RV32I-NEXT:  .LBB3_2:
168; RV32I-NEXT:    ret
169;
170; RV32IF-LABEL: select_const_int_harder:
171; RV32IF:       # %bb.0:
172; RV32IF-NEXT:    mv a1, a0
173; RV32IF-NEXT:    li a0, 6
174; RV32IF-NEXT:    bnez a1, .LBB3_2
175; RV32IF-NEXT:  # %bb.1:
176; RV32IF-NEXT:    li a0, 38
177; RV32IF-NEXT:  .LBB3_2:
178; RV32IF-NEXT:    ret
179;
180; RV32IBT-LABEL: select_const_int_harder:
181; RV32IBT:       # %bb.0:
182; RV32IBT-NEXT:    li a1, 38
183; RV32IBT-NEXT:    li a2, 6
184; RV32IBT-NEXT:    cmov a0, a0, a2, a1
185; RV32IBT-NEXT:    ret
186;
187; RV32IFBT-LABEL: select_const_int_harder:
188; RV32IFBT:       # %bb.0:
189; RV32IFBT-NEXT:    li a1, 38
190; RV32IFBT-NEXT:    li a2, 6
191; RV32IFBT-NEXT:    cmov a0, a0, a2, a1
192; RV32IFBT-NEXT:    ret
193;
194; RV64I-LABEL: select_const_int_harder:
195; RV64I:       # %bb.0:
196; RV64I-NEXT:    mv a1, a0
197; RV64I-NEXT:    li a0, 6
198; RV64I-NEXT:    bnez a1, .LBB3_2
199; RV64I-NEXT:  # %bb.1:
200; RV64I-NEXT:    li a0, 38
201; RV64I-NEXT:  .LBB3_2:
202; RV64I-NEXT:    ret
203;
204; RV64IFD-LABEL: select_const_int_harder:
205; RV64IFD:       # %bb.0:
206; RV64IFD-NEXT:    mv a1, a0
207; RV64IFD-NEXT:    li a0, 6
208; RV64IFD-NEXT:    bnez a1, .LBB3_2
209; RV64IFD-NEXT:  # %bb.1:
210; RV64IFD-NEXT:    li a0, 38
211; RV64IFD-NEXT:  .LBB3_2:
212; RV64IFD-NEXT:    ret
213;
214; RV64IBT-LABEL: select_const_int_harder:
215; RV64IBT:       # %bb.0:
216; RV64IBT-NEXT:    li a1, 38
217; RV64IBT-NEXT:    li a2, 6
218; RV64IBT-NEXT:    cmov a0, a0, a2, a1
219; RV64IBT-NEXT:    ret
220;
221; RV64IFDBT-LABEL: select_const_int_harder:
222; RV64IFDBT:       # %bb.0:
223; RV64IFDBT-NEXT:    li a1, 38
224; RV64IFDBT-NEXT:    li a2, 6
225; RV64IFDBT-NEXT:    cmov a0, a0, a2, a1
226; RV64IFDBT-NEXT:    ret
227  %1 = select i1 %a, i32 6, i32 38
228  ret i32 %1
229}
230
231define float @select_const_fp(i1 zeroext %a) nounwind {
232; RV32I-LABEL: select_const_fp:
233; RV32I:       # %bb.0:
234; RV32I-NEXT:    mv a1, a0
235; RV32I-NEXT:    lui a0, 263168
236; RV32I-NEXT:    bnez a1, .LBB4_2
237; RV32I-NEXT:  # %bb.1:
238; RV32I-NEXT:    lui a0, 264192
239; RV32I-NEXT:  .LBB4_2:
240; RV32I-NEXT:    ret
241;
242; RV32IF-LABEL: select_const_fp:
243; RV32IF:       # %bb.0:
244; RV32IF-NEXT:    bnez a0, .LBB4_2
245; RV32IF-NEXT:  # %bb.1:
246; RV32IF-NEXT:    lui a0, %hi(.LCPI4_0)
247; RV32IF-NEXT:    flw ft0, %lo(.LCPI4_0)(a0)
248; RV32IF-NEXT:    fmv.x.w a0, ft0
249; RV32IF-NEXT:    ret
250; RV32IF-NEXT:  .LBB4_2:
251; RV32IF-NEXT:    lui a0, %hi(.LCPI4_1)
252; RV32IF-NEXT:    flw ft0, %lo(.LCPI4_1)(a0)
253; RV32IF-NEXT:    fmv.x.w a0, ft0
254; RV32IF-NEXT:    ret
255;
256; RV32IBT-LABEL: select_const_fp:
257; RV32IBT:       # %bb.0:
258; RV32IBT-NEXT:    lui a1, 264192
259; RV32IBT-NEXT:    lui a2, 263168
260; RV32IBT-NEXT:    cmov a0, a0, a2, a1
261; RV32IBT-NEXT:    ret
262;
263; RV32IFBT-LABEL: select_const_fp:
264; RV32IFBT:       # %bb.0:
265; RV32IFBT-NEXT:    bnez a0, .LBB4_2
266; RV32IFBT-NEXT:  # %bb.1:
267; RV32IFBT-NEXT:    lui a0, %hi(.LCPI4_0)
268; RV32IFBT-NEXT:    flw ft0, %lo(.LCPI4_0)(a0)
269; RV32IFBT-NEXT:    fmv.x.w a0, ft0
270; RV32IFBT-NEXT:    ret
271; RV32IFBT-NEXT:  .LBB4_2:
272; RV32IFBT-NEXT:    lui a0, %hi(.LCPI4_1)
273; RV32IFBT-NEXT:    flw ft0, %lo(.LCPI4_1)(a0)
274; RV32IFBT-NEXT:    fmv.x.w a0, ft0
275; RV32IFBT-NEXT:    ret
276;
277; RV64I-LABEL: select_const_fp:
278; RV64I:       # %bb.0:
279; RV64I-NEXT:    mv a1, a0
280; RV64I-NEXT:    lui a0, 263168
281; RV64I-NEXT:    bnez a1, .LBB4_2
282; RV64I-NEXT:  # %bb.1:
283; RV64I-NEXT:    lui a0, 264192
284; RV64I-NEXT:  .LBB4_2:
285; RV64I-NEXT:    ret
286;
287; RV64IFD-LABEL: select_const_fp:
288; RV64IFD:       # %bb.0:
289; RV64IFD-NEXT:    bnez a0, .LBB4_2
290; RV64IFD-NEXT:  # %bb.1:
291; RV64IFD-NEXT:    lui a0, %hi(.LCPI4_0)
292; RV64IFD-NEXT:    flw ft0, %lo(.LCPI4_0)(a0)
293; RV64IFD-NEXT:    fmv.x.w a0, ft0
294; RV64IFD-NEXT:    ret
295; RV64IFD-NEXT:  .LBB4_2:
296; RV64IFD-NEXT:    lui a0, %hi(.LCPI4_1)
297; RV64IFD-NEXT:    flw ft0, %lo(.LCPI4_1)(a0)
298; RV64IFD-NEXT:    fmv.x.w a0, ft0
299; RV64IFD-NEXT:    ret
300;
301; RV64IBT-LABEL: select_const_fp:
302; RV64IBT:       # %bb.0:
303; RV64IBT-NEXT:    lui a1, 264192
304; RV64IBT-NEXT:    lui a2, 263168
305; RV64IBT-NEXT:    cmov a0, a0, a2, a1
306; RV64IBT-NEXT:    ret
307;
308; RV64IFDBT-LABEL: select_const_fp:
309; RV64IFDBT:       # %bb.0:
310; RV64IFDBT-NEXT:    bnez a0, .LBB4_2
311; RV64IFDBT-NEXT:  # %bb.1:
312; RV64IFDBT-NEXT:    lui a0, %hi(.LCPI4_0)
313; RV64IFDBT-NEXT:    flw ft0, %lo(.LCPI4_0)(a0)
314; RV64IFDBT-NEXT:    fmv.x.w a0, ft0
315; RV64IFDBT-NEXT:    ret
316; RV64IFDBT-NEXT:  .LBB4_2:
317; RV64IFDBT-NEXT:    lui a0, %hi(.LCPI4_1)
318; RV64IFDBT-NEXT:    flw ft0, %lo(.LCPI4_1)(a0)
319; RV64IFDBT-NEXT:    fmv.x.w a0, ft0
320; RV64IFDBT-NEXT:    ret
321  %1 = select i1 %a, float 3.0, float 4.0
322  ret float %1
323}
324