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
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).
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
27 define signext i32 @select_const_int_easy(i1 zeroext %a) nounwind {
28 ; RV32I-LABEL: select_const_int_easy:
32 ; RV32IF-LABEL: select_const_int_easy:
36 ; RV32IBT-LABEL: select_const_int_easy:
40 ; RV32IFBT-LABEL: select_const_int_easy:
44 ; RV64I-LABEL: select_const_int_easy:
48 ; RV64IFD-LABEL: select_const_int_easy:
52 ; RV64IBT-LABEL: select_const_int_easy:
56 ; RV64IFDBT-LABEL: select_const_int_easy:
59 %1 = select i1 %a, i32 1, i32 0
63 define signext i32 @select_const_int_one_away(i1 zeroext %a) nounwind {
64 ; RV32I-LABEL: select_const_int_one_away:
66 ; RV32I-NEXT: addi a1, zero, 4
67 ; RV32I-NEXT: sub a0, a1, a0
70 ; RV32IF-LABEL: select_const_int_one_away:
72 ; RV32IF-NEXT: addi a1, zero, 4
73 ; RV32IF-NEXT: sub a0, a1, a0
76 ; RV32IBT-LABEL: select_const_int_one_away:
78 ; RV32IBT-NEXT: addi a1, zero, 4
79 ; RV32IBT-NEXT: sub a0, a1, a0
82 ; RV32IFBT-LABEL: select_const_int_one_away:
84 ; RV32IFBT-NEXT: addi a1, zero, 4
85 ; RV32IFBT-NEXT: sub a0, a1, a0
88 ; RV64I-LABEL: select_const_int_one_away:
90 ; RV64I-NEXT: addi a1, zero, 4
91 ; RV64I-NEXT: sub a0, a1, a0
94 ; RV64IFD-LABEL: select_const_int_one_away:
96 ; RV64IFD-NEXT: addi a1, zero, 4
97 ; RV64IFD-NEXT: sub a0, a1, a0
100 ; RV64IBT-LABEL: select_const_int_one_away:
102 ; RV64IBT-NEXT: addi a1, zero, 4
103 ; RV64IBT-NEXT: sub a0, a1, a0
106 ; RV64IFDBT-LABEL: select_const_int_one_away:
107 ; RV64IFDBT: # %bb.0:
108 ; RV64IFDBT-NEXT: addi a1, zero, 4
109 ; RV64IFDBT-NEXT: sub a0, a1, a0
110 ; RV64IFDBT-NEXT: ret
111 %1 = select i1 %a, i32 3, i32 4
115 define signext i32 @select_const_int_pow2_zero(i1 zeroext %a) nounwind {
116 ; RV32I-LABEL: select_const_int_pow2_zero:
118 ; RV32I-NEXT: slli a0, a0, 2
121 ; RV32IF-LABEL: select_const_int_pow2_zero:
123 ; RV32IF-NEXT: slli a0, a0, 2
126 ; RV32IBT-LABEL: select_const_int_pow2_zero:
128 ; RV32IBT-NEXT: slli a0, a0, 2
131 ; RV32IFBT-LABEL: select_const_int_pow2_zero:
133 ; RV32IFBT-NEXT: slli a0, a0, 2
136 ; RV64I-LABEL: select_const_int_pow2_zero:
138 ; RV64I-NEXT: slli a0, a0, 2
141 ; RV64IFD-LABEL: select_const_int_pow2_zero:
143 ; RV64IFD-NEXT: slli a0, a0, 2
146 ; RV64IBT-LABEL: select_const_int_pow2_zero:
148 ; RV64IBT-NEXT: slli a0, a0, 2
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
159 define signext i32 @select_const_int_harder(i1 zeroext %a) nounwind {
160 ; RV32I-LABEL: select_const_int_harder:
162 ; RV32I-NEXT: mv a1, a0
163 ; RV32I-NEXT: addi a0, zero, 6
164 ; RV32I-NEXT: bnez a1, .LBB3_2
165 ; RV32I-NEXT: # %bb.1:
166 ; RV32I-NEXT: addi a0, zero, 38
167 ; RV32I-NEXT: .LBB3_2:
170 ; RV32IF-LABEL: select_const_int_harder:
172 ; RV32IF-NEXT: mv a1, a0
173 ; RV32IF-NEXT: addi a0, zero, 6
174 ; RV32IF-NEXT: bnez a1, .LBB3_2
175 ; RV32IF-NEXT: # %bb.1:
176 ; RV32IF-NEXT: addi a0, zero, 38
177 ; RV32IF-NEXT: .LBB3_2:
180 ; RV32IBT-LABEL: select_const_int_harder:
182 ; RV32IBT-NEXT: addi a1, zero, 38
183 ; RV32IBT-NEXT: addi a2, zero, 6
184 ; RV32IBT-NEXT: cmov a0, a0, a2, a1
187 ; RV32IFBT-LABEL: select_const_int_harder:
189 ; RV32IFBT-NEXT: addi a1, zero, 38
190 ; RV32IFBT-NEXT: addi a2, zero, 6
191 ; RV32IFBT-NEXT: cmov a0, a0, a2, a1
194 ; RV64I-LABEL: select_const_int_harder:
196 ; RV64I-NEXT: mv a1, a0
197 ; RV64I-NEXT: addi a0, zero, 6
198 ; RV64I-NEXT: bnez a1, .LBB3_2
199 ; RV64I-NEXT: # %bb.1:
200 ; RV64I-NEXT: addi a0, zero, 38
201 ; RV64I-NEXT: .LBB3_2:
204 ; RV64IFD-LABEL: select_const_int_harder:
206 ; RV64IFD-NEXT: mv a1, a0
207 ; RV64IFD-NEXT: addi a0, zero, 6
208 ; RV64IFD-NEXT: bnez a1, .LBB3_2
209 ; RV64IFD-NEXT: # %bb.1:
210 ; RV64IFD-NEXT: addi a0, zero, 38
211 ; RV64IFD-NEXT: .LBB3_2:
214 ; RV64IBT-LABEL: select_const_int_harder:
216 ; RV64IBT-NEXT: addi a1, zero, 38
217 ; RV64IBT-NEXT: addi a2, zero, 6
218 ; RV64IBT-NEXT: cmov a0, a0, a2, a1
221 ; RV64IFDBT-LABEL: select_const_int_harder:
222 ; RV64IFDBT: # %bb.0:
223 ; RV64IFDBT-NEXT: addi a1, zero, 38
224 ; RV64IFDBT-NEXT: addi a2, zero, 6
225 ; RV64IFDBT-NEXT: cmov a0, a0, a2, a1
226 ; RV64IFDBT-NEXT: ret
227 %1 = select i1 %a, i32 6, i32 38
231 define float @select_const_fp(i1 zeroext %a) nounwind {
232 ; RV32I-LABEL: select_const_fp:
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:
242 ; RV32IF-LABEL: select_const_fp:
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
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
256 ; RV32IBT-LABEL: select_const_fp:
258 ; RV32IBT-NEXT: lui a1, 264192
259 ; RV32IBT-NEXT: lui a2, 263168
260 ; RV32IBT-NEXT: cmov a0, a0, a2, a1
263 ; RV32IFBT-LABEL: select_const_fp:
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
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
277 ; RV64I-LABEL: select_const_fp:
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:
287 ; RV64IFD-LABEL: select_const_fp:
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
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
301 ; RV64IBT-LABEL: select_const_fp:
303 ; RV64IBT-NEXT: lui a1, 264192
304 ; RV64IBT-NEXT: lui a2, 263168
305 ; RV64IBT-NEXT: cmov a0, a0, a2, a1
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