LLVM 24.0.0git
RISCVISelLowering.cpp
Go to the documentation of this file.
1//===-- RISCVISelLowering.cpp - RISC-V DAG Lowering Implementation -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that RISC-V uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "RISCVISelLowering.h"
16#include "RISCV.h"
19#include "RISCVRegisterInfo.h"
21#include "RISCVSubtarget.h"
22#include "llvm/ADT/SmallSet.h"
24#include "llvm/ADT/Statistic.h"
40#include "llvm/IR/IRBuilder.h"
43#include "llvm/IR/IntrinsicsRISCV.h"
47#include "llvm/Support/Debug.h"
53#include <optional>
54
55using namespace llvm;
56
57#define DEBUG_TYPE "riscv-lower"
58
59STATISTIC(NumTailCalls, "Number of tail calls");
60
62 DEBUG_TYPE "-ext-max-web-size", cl::Hidden,
63 cl::desc("Give the maximum size (in number of nodes) of the web of "
64 "instructions that we will consider for VW expansion"),
65 cl::init(18));
66
67static cl::opt<bool>
68 AllowSplatInVW_W(DEBUG_TYPE "-form-vw-w-with-splat", cl::Hidden,
69 cl::desc("Allow the formation of VW_W operations (e.g., "
70 "VWADD_W) with splat constants"),
71 cl::init(false));
72
74 DEBUG_TYPE "-fp-repeated-divisors", cl::Hidden,
75 cl::desc("Set the minimum number of repetitions of a divisor to allow "
76 "transformation to multiplications by the reciprocal"),
77 cl::init(2));
78
79static cl::opt<int>
81 cl::desc("Give the maximum number of instructions that we will "
82 "use for creating a floating-point immediate value"),
83 cl::init(3));
84
85static cl::opt<bool>
86 ReassocShlAddiAdd("reassoc-shl-addi-add", cl::Hidden,
87 cl::desc("Swap add and addi in cases where the add may "
88 "be combined with a shift"),
89 cl::init(true));
90
92 "riscv-br-merging-base-cost", cl::init(2),
94 "Sets the cost threshold for when multiple conditionals will be merged "
95 "into one branch versus be split in multiple branches. Merging "
96 "conditionals saves branches at the cost of additional instructions. "
97 "This value sets the instruction cost limit, below which conditionals "
98 "will be merged, and above which conditionals will be split. Set to -1 "
99 "to never merge branches."),
100 cl::Hidden);
101
103 "riscv-br-merging-likely-bias", cl::init(0),
104 cl::desc(
105 "Increases 'riscv-br-merging-base-cost' in cases that it is "
106 "likely that all conditionals will be executed. For example for "
107 "merging the conditionals (a == b && c > d), if its known that "
108 "a == b is likely, then it is likely that if the conditionals are "
109 "split both sides will be executed, so it may be desirable to "
110 "increase the instruction cost threshold. Set to -1 to never merge "
111 "likely branches."),
112 cl::Hidden);
113
115 "riscv-br-merging-unlikely-bias", cl::init(-1),
116 cl::desc(
117 "Decreases 'riscv-br-merging-base-cost' in cases that it is unlikely "
118 "that all conditionals will be executed. For example for merging "
119 "the conditionals (a == b && c > d), if its known that a == b is "
120 "unlikely, then it is unlikely that if the conditionals are split "
121 "both sides will be executed, so it may be desirable to decrease "
122 "the instruction cost threshold. Set to -1 to never merge unlikely "
123 "branches."),
124 cl::Hidden);
125
126// TODO: Support more ops
133
135 const RISCVSubtarget &STI)
136 : TargetLowering(TM, STI), Subtarget(STI) {
137
138 RISCVABI::ABI ABI = Subtarget.getTargetABI();
139 assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
140
141 if ((ABI == RISCVABI::ABI_ILP32F || ABI == RISCVABI::ABI_LP64F) &&
142 !Subtarget.hasStdExtF()) {
143 errs() << "Hard-float 'f' ABI can't be used for a target that "
144 "doesn't support the F instruction set extension (ignoring "
145 "target-abi)\n";
146 ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
147 } else if ((ABI == RISCVABI::ABI_ILP32D || ABI == RISCVABI::ABI_LP64D) &&
148 !Subtarget.hasStdExtD()) {
149 errs() << "Hard-float 'd' ABI can't be used for a target that "
150 "doesn't support the D instruction set extension (ignoring "
151 "target-abi)\n";
152 ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
153 }
154
155 switch (ABI) {
156 default:
157 reportFatalUsageError("Don't know how to lower this ABI");
166 break;
167 }
168
169 MVT XLenVT = Subtarget.getXLenVT();
170
171 // Set up the register classes.
172 addRegisterClass(XLenVT, &RISCV::GPRRegClass);
173
174 if (Subtarget.hasStdExtZfhmin())
175 addRegisterClass(MVT::f16, &RISCV::FPR16RegClass);
176 if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
177 addRegisterClass(MVT::bf16, &RISCV::FPR16RegClass);
178 if (Subtarget.hasStdExtF())
179 addRegisterClass(MVT::f32, &RISCV::FPR32RegClass);
180 if (Subtarget.hasStdExtD())
181 addRegisterClass(MVT::f64, &RISCV::FPR64RegClass);
182 if (Subtarget.hasStdExtZhinxmin())
183 addRegisterClass(MVT::f16, &RISCV::GPRF16RegClass);
184 if (Subtarget.hasStdExtZfinx())
185 addRegisterClass(MVT::f32, &RISCV::GPRF32RegClass);
186 if (Subtarget.hasStdExtZdinx()) {
187 if (Subtarget.is64Bit())
188 addRegisterClass(MVT::f64, &RISCV::GPRRegClass);
189 else
190 addRegisterClass(MVT::f64, &RISCV::GPRPairRegClass);
191 }
192
193 static const MVT::SimpleValueType BoolVecVTs[] = {
194 MVT::nxv1i1, MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1,
195 MVT::nxv16i1, MVT::nxv32i1, MVT::nxv64i1};
196 static const MVT::SimpleValueType IntVecVTs[] = {
197 MVT::nxv1i8, MVT::nxv2i8, MVT::nxv4i8, MVT::nxv8i8, MVT::nxv16i8,
198 MVT::nxv32i8, MVT::nxv64i8, MVT::nxv1i16, MVT::nxv2i16, MVT::nxv4i16,
199 MVT::nxv8i16, MVT::nxv16i16, MVT::nxv32i16, MVT::nxv1i32, MVT::nxv2i32,
200 MVT::nxv4i32, MVT::nxv8i32, MVT::nxv16i32, MVT::nxv1i64, MVT::nxv2i64,
201 MVT::nxv4i64, MVT::nxv8i64};
202 static const MVT::SimpleValueType F16VecVTs[] = {
203 MVT::nxv1f16, MVT::nxv2f16, MVT::nxv4f16,
204 MVT::nxv8f16, MVT::nxv16f16, MVT::nxv32f16};
205 static const MVT::SimpleValueType BF16VecVTs[] = {
206 MVT::nxv1bf16, MVT::nxv2bf16, MVT::nxv4bf16,
207 MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
208 static const MVT::SimpleValueType F32VecVTs[] = {
209 MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
210 static const MVT::SimpleValueType F64VecVTs[] = {
211 MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
212 static const MVT::SimpleValueType VecTupleVTs[] = {
213 MVT::riscv_nxv1i8x2, MVT::riscv_nxv1i8x3, MVT::riscv_nxv1i8x4,
214 MVT::riscv_nxv1i8x5, MVT::riscv_nxv1i8x6, MVT::riscv_nxv1i8x7,
215 MVT::riscv_nxv1i8x8, MVT::riscv_nxv2i8x2, MVT::riscv_nxv2i8x3,
216 MVT::riscv_nxv2i8x4, MVT::riscv_nxv2i8x5, MVT::riscv_nxv2i8x6,
217 MVT::riscv_nxv2i8x7, MVT::riscv_nxv2i8x8, MVT::riscv_nxv4i8x2,
218 MVT::riscv_nxv4i8x3, MVT::riscv_nxv4i8x4, MVT::riscv_nxv4i8x5,
219 MVT::riscv_nxv4i8x6, MVT::riscv_nxv4i8x7, MVT::riscv_nxv4i8x8,
220 MVT::riscv_nxv8i8x2, MVT::riscv_nxv8i8x3, MVT::riscv_nxv8i8x4,
221 MVT::riscv_nxv8i8x5, MVT::riscv_nxv8i8x6, MVT::riscv_nxv8i8x7,
222 MVT::riscv_nxv8i8x8, MVT::riscv_nxv16i8x2, MVT::riscv_nxv16i8x3,
223 MVT::riscv_nxv16i8x4, MVT::riscv_nxv32i8x2};
224
225 if (Subtarget.hasVInstructions()) {
226 auto addRegClassForRVV = [this](MVT VT) {
227 // Disable the smallest fractional LMUL types if ELEN is less than
228 // RVVBitsPerBlock.
229 unsigned MinElts = RISCV::RVVBitsPerBlock / Subtarget.getELen();
230 if (VT.getVectorMinNumElements() < MinElts)
231 return;
232
233 unsigned Size = VT.getSizeInBits().getKnownMinValue();
234 const TargetRegisterClass *RC;
236 RC = &RISCV::VRRegClass;
237 else if (Size == 2 * RISCV::RVVBitsPerBlock)
238 RC = &RISCV::VRM2RegClass;
239 else if (Size == 4 * RISCV::RVVBitsPerBlock)
240 RC = &RISCV::VRM4RegClass;
241 else if (Size == 8 * RISCV::RVVBitsPerBlock)
242 RC = &RISCV::VRM8RegClass;
243 else
244 llvm_unreachable("Unexpected size");
245
246 addRegisterClass(VT, RC);
247 };
248
249 for (MVT VT : BoolVecVTs)
250 addRegClassForRVV(VT);
251 for (MVT VT : IntVecVTs) {
252 if (VT.getVectorElementType() == MVT::i64 &&
253 !Subtarget.hasVInstructionsI64())
254 continue;
255 addRegClassForRVV(VT);
256 }
257
258 if (Subtarget.hasVInstructionsF16Minimal() ||
259 Subtarget.hasVendorXAndesVPackFPH())
260 for (MVT VT : F16VecVTs)
261 addRegClassForRVV(VT);
262
263 if (Subtarget.hasVInstructionsBF16Minimal() ||
264 Subtarget.hasVendorXAndesVBFHCvt())
265 for (MVT VT : BF16VecVTs)
266 addRegClassForRVV(VT);
267
268 if (Subtarget.hasVInstructionsF32())
269 for (MVT VT : F32VecVTs)
270 addRegClassForRVV(VT);
271
272 if (Subtarget.hasVInstructionsF64())
273 for (MVT VT : F64VecVTs)
274 addRegClassForRVV(VT);
275
276 if (Subtarget.useRVVForFixedLengthVectors()) {
277 auto addRegClassForFixedVectors = [this](MVT VT) {
278 MVT ContainerVT = getContainerForFixedLengthVector(VT);
279 unsigned RCID = getRegClassIDForVecVT(ContainerVT);
280 const RISCVRegisterInfo &TRI = *Subtarget.getRegisterInfo();
281 addRegisterClass(VT, TRI.getRegClass(RCID));
282 };
284 if (useRVVForFixedLengthVectorVT(VT))
285 addRegClassForFixedVectors(VT);
286
288 if (useRVVForFixedLengthVectorVT(VT))
289 addRegClassForFixedVectors(VT);
290 }
291
292 addRegisterClass(MVT::riscv_nxv1i8x2, &RISCV::VRN2M1RegClass);
293 addRegisterClass(MVT::riscv_nxv1i8x3, &RISCV::VRN3M1RegClass);
294 addRegisterClass(MVT::riscv_nxv1i8x4, &RISCV::VRN4M1RegClass);
295 addRegisterClass(MVT::riscv_nxv1i8x5, &RISCV::VRN5M1RegClass);
296 addRegisterClass(MVT::riscv_nxv1i8x6, &RISCV::VRN6M1RegClass);
297 addRegisterClass(MVT::riscv_nxv1i8x7, &RISCV::VRN7M1RegClass);
298 addRegisterClass(MVT::riscv_nxv1i8x8, &RISCV::VRN8M1RegClass);
299 addRegisterClass(MVT::riscv_nxv2i8x2, &RISCV::VRN2M1RegClass);
300 addRegisterClass(MVT::riscv_nxv2i8x3, &RISCV::VRN3M1RegClass);
301 addRegisterClass(MVT::riscv_nxv2i8x4, &RISCV::VRN4M1RegClass);
302 addRegisterClass(MVT::riscv_nxv2i8x5, &RISCV::VRN5M1RegClass);
303 addRegisterClass(MVT::riscv_nxv2i8x6, &RISCV::VRN6M1RegClass);
304 addRegisterClass(MVT::riscv_nxv2i8x7, &RISCV::VRN7M1RegClass);
305 addRegisterClass(MVT::riscv_nxv2i8x8, &RISCV::VRN8M1RegClass);
306 addRegisterClass(MVT::riscv_nxv4i8x2, &RISCV::VRN2M1RegClass);
307 addRegisterClass(MVT::riscv_nxv4i8x3, &RISCV::VRN3M1RegClass);
308 addRegisterClass(MVT::riscv_nxv4i8x4, &RISCV::VRN4M1RegClass);
309 addRegisterClass(MVT::riscv_nxv4i8x5, &RISCV::VRN5M1RegClass);
310 addRegisterClass(MVT::riscv_nxv4i8x6, &RISCV::VRN6M1RegClass);
311 addRegisterClass(MVT::riscv_nxv4i8x7, &RISCV::VRN7M1RegClass);
312 addRegisterClass(MVT::riscv_nxv4i8x8, &RISCV::VRN8M1RegClass);
313 addRegisterClass(MVT::riscv_nxv8i8x2, &RISCV::VRN2M1RegClass);
314 addRegisterClass(MVT::riscv_nxv8i8x3, &RISCV::VRN3M1RegClass);
315 addRegisterClass(MVT::riscv_nxv8i8x4, &RISCV::VRN4M1RegClass);
316 addRegisterClass(MVT::riscv_nxv8i8x5, &RISCV::VRN5M1RegClass);
317 addRegisterClass(MVT::riscv_nxv8i8x6, &RISCV::VRN6M1RegClass);
318 addRegisterClass(MVT::riscv_nxv8i8x7, &RISCV::VRN7M1RegClass);
319 addRegisterClass(MVT::riscv_nxv8i8x8, &RISCV::VRN8M1RegClass);
320 addRegisterClass(MVT::riscv_nxv16i8x2, &RISCV::VRN2M2RegClass);
321 addRegisterClass(MVT::riscv_nxv16i8x3, &RISCV::VRN3M2RegClass);
322 addRegisterClass(MVT::riscv_nxv16i8x4, &RISCV::VRN4M2RegClass);
323 addRegisterClass(MVT::riscv_nxv32i8x2, &RISCV::VRN2M4RegClass);
324 }
325
326 // fixed vector is stored in GPRs for P extension packed operations
327 if (Subtarget.hasStdExtP()) {
328 if (Subtarget.is64Bit()) {
329 addRegisterClass(MVT::v2i32, &RISCV::GPRRegClass);
330 addRegisterClass(MVT::v4i16, &RISCV::GPRRegClass);
331 addRegisterClass(MVT::v8i8, &RISCV::GPRRegClass);
332 } else {
333 addRegisterClass(MVT::v2i16, &RISCV::GPRRegClass);
334 addRegisterClass(MVT::v4i8, &RISCV::GPRRegClass);
335
336 addRegisterClass(MVT::v2i32, &RISCV::GPRPairRegClass);
337 addRegisterClass(MVT::v4i16, &RISCV::GPRPairRegClass);
338 addRegisterClass(MVT::v8i8, &RISCV::GPRPairRegClass);
339 }
340 }
341
342 // Compute derived properties from the register classes.
344
346
348 MVT::i1, Promote);
349 // DAGCombiner can call isLoadExtLegal for types that aren't legal.
351 MVT::i1, Promote);
352
353 // TODO: add all necessary setOperationAction calls.
355
360
365 if (!(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
368 }
369
371
374
375 if (!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
376 !Subtarget.hasVendorXAndesPerf())
378
380
381 if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
382 !Subtarget.hasVendorXqcibm() && !Subtarget.hasVendorXAndesPerf() &&
383 !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
384 setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16}, Expand);
385
386 if (Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit()) {
389 }
390
391 if (Subtarget.is64Bit()) {
393
396 MVT::i32, Custom);
399 } else if (Subtarget.hasStdExtP()) {
400 // Custom legalize i64 ADD/SUB/SHL/SRL/SRA for RV32+P.
403 }
404 if (!Subtarget.hasStdExtZmmul()) {
406 } else if (Subtarget.is64Bit()) {
409 } else {
411 }
412
413 if (!Subtarget.hasStdExtM()) {
415 Expand);
416 } else if (Subtarget.is64Bit()) {
418 {MVT::i8, MVT::i16, MVT::i32}, Custom);
419 }
420
422
423 // On RV32, the P extension has a WMUL(U) instruction we can use for
424 // (S/U)MUL_LOHI.
425 // FIXME: Does P imply Zmmul?
426 if (!Subtarget.hasStdExtP() || !Subtarget.hasStdExtZmmul() ||
427 Subtarget.is64Bit())
429
431 Custom);
432
433 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) {
434 if (Subtarget.is64Bit())
436 } else if (Subtarget.hasVendorXTHeadBb()) {
437 if (Subtarget.is64Bit())
440 } else if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit()) {
442 } else {
444 }
445
446 if (Subtarget.hasStdExtP())
448
450 Subtarget.hasREV8Like() ? Legal : Expand);
451
452 if (Subtarget.hasREVLike()) {
454 } else {
455 // Zbkb can use rev8+brev8 to implement bitreverse.
457 Subtarget.hasStdExtZbkb() ? Custom : Expand);
458 if (Subtarget.hasStdExtZbkb())
460 }
461
462 if (Subtarget.hasStdExtZbb() ||
463 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
465 Legal);
466 }
467
468 if (Subtarget.hasCTZLike()) {
469 if (Subtarget.is64Bit())
471 } else {
473 }
474
475 if (!Subtarget.hasCPOPLike()) {
476 // TODO: These should be set to LibCall, but this currently breaks
477 // the Linux kernel build. See #101786. Lacks i128 tests, too.
478 if (Subtarget.is64Bit())
480 else
483 }
484
485 if (Subtarget.hasCLZLike()) {
486 // We need the custom lowering to make sure that the resulting sequence
487 // for the 32bit case is efficient on 64bit targets.
488 // Use default promotion for i32 without Zbb.
489 if (Subtarget.is64Bit() &&
490 (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP()))
492 } else {
493 if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit())
496 }
497
498 if (Subtarget.hasStdExtP()) {
500 if (Subtarget.is64Bit())
502 }
503
504 if (Subtarget.hasStdExtP() ||
505 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
507 if (Subtarget.is64Bit())
509 } else if (Subtarget.hasShortForwardBranchIALU()) {
510 // We can use PseudoCCSUB to implement ABS.
512 } else if (Subtarget.is64Bit()) {
514 }
515
516 if (!Subtarget.useMIPSCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
518
519 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
520 !Subtarget.is64Bit()) {
522 MVT::i32, Legal);
523 } else if (Subtarget.hasStdExtP() && Subtarget.is64Bit()) {
525 MVT::i32, Custom);
526 } else if (!Subtarget.hasStdExtZbb() && Subtarget.is64Bit()) {
528 MVT::i32, Custom);
529 }
530
531 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
532 !Subtarget.is64Bit()) {
533 // FIXME: Support i32 on RV64+P by inserting into a v2i32 vector, doing
534 // pssha.w/psshl.w and extracting.
537 }
538
539 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit()) {
540 // FIXME: Support i32 on RV64+P by inserting into a v2i32 vector, doing
541 // paadd.w, paaddu.w and extracting.
543 }
544
545 if (Subtarget.hasStdExtZbc() || Subtarget.hasStdExtZbkc()) {
547 if (Subtarget.hasStdExtZbc())
549 } else if (Subtarget.hasStdExtZvbc() && Subtarget.is64Bit()) {
550 // FIXME: Support i32 on RV32 by zexting from XLEN to i64 and extracting
551 // half of the result (low for CLMUL, high for CLMULH).
552 // TODO: Zvbc32e allows us to do a lot more here.
554 }
555
556 static const unsigned FPLegalNodeTypes[] = {
564
565 static const ISD::CondCode FPCCToExpand[] = {
569
570 static const unsigned FPOpToExpand[] = {ISD::FSIN, ISD::FCOS, ISD::FSINCOS,
571 ISD::FPOW};
572 static const unsigned FPOpToLibCall[] = {ISD::FREM};
573
574 static const unsigned FPRndMode[] = {
577
578 static const unsigned ZfhminZfbfminPromoteOps[] = {
589
590 if (Subtarget.hasStdExtP()) {
591 static const MVT P32VecVTs[] = {MVT::v2i16, MVT::v4i8};
592 static const MVT P64VecVTs[] = {MVT::v2i32, MVT::v4i16, MVT::v8i8};
593 ArrayRef<MVT> VTs;
594 if (Subtarget.is64Bit()) {
595 VTs = P64VecVTs;
596 // There's no instruction for vector shamt in P extension so we unroll to
597 // scalar instructions. Vector VTs that are 32-bit are widened to 64-bit
598 // vector, e.g. v2i16 -> v4i16, before getting unrolled, so we need custom
599 // widen for those operations that will be unrolled.
601 {MVT::v2i16, MVT::v4i8}, Custom);
602 setOperationAction(ISD::INTRINSIC_WO_CHAIN, {MVT::v2i16, MVT::v4i8},
603 Custom);
604 // Operand legalization queries the action using the illegal subvector.
605 setOperationAction(ISD::INSERT_SUBVECTOR, {MVT::v2i16, MVT::v4i8},
606 Custom);
607 } else {
608 VTs = P32VecVTs;
609 }
610 // By default everything must be expanded.
611 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
613
614 for (MVT VT : VTs) {
616 setTruncStoreAction(VT, OtherVT, Expand);
618 OtherVT, Expand);
619 }
620 }
621
633 for (MVT VT : VTs) {
634 if (VT != MVT::v2i32)
636 if (VT.getVectorElementType() != MVT::i8) {
639 }
640 }
648 Custom);
650 Legal);
656 Expand);
658
659 if (!Subtarget.is64Bit())
660 setOperationAction(ISD::BUILD_VECTOR, {MVT::v2i16, MVT::v4i8}, Custom);
661
662 // P extension vector comparisons produce all 1s for true, all 0s for false
664
665 if (!Subtarget.is64Bit()) {
666 // By default everything must be expanded.
667 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
668 setOperationAction(Op, P64VecVTs, Expand);
669
670 for (MVT VT : P64VecVTs) {
672 setTruncStoreAction(VT, OtherVT, Expand);
674 OtherVT, Expand);
675 }
676 }
677
682 setOperationAction({ISD::AND, ISD::OR, ISD::XOR}, {MVT::v4i16, MVT::v8i8},
683 Custom);
686 Legal);
691 P64VecVTs, Legal);
693 {MVT::v4i16, MVT::v8i8}, Legal);
695 setOperationAction(ISD::SSHLSAT, {MVT::v2i32, MVT::v4i16}, Custom);
696 setOperationAction(ISD::BSWAP, MVT::v4i16, Legal);
697 setOperationAction(ISD::BITREVERSE, {MVT::v4i16, MVT::v8i8}, Legal);
704 {MVT::v4i16, MVT::v8i8}, Custom);
705 setOperationAction(ISD::CONCAT_VECTORS, {MVT::v4i16, MVT::v8i8}, Legal);
706 setOperationAction(ISD::EXTRACT_SUBVECTOR, {MVT::v2i16, MVT::v4i8},
707 Legal);
708 setOperationAction({ISD::SELECT, ISD::VSELECT}, {MVT::v4i16, MVT::v8i8},
709 Custom);
711 {MVT::v4i16, MVT::v8i8}, Custom);
716 {MVT::v4i16, MVT::v2i32}, Legal);
717 setOperationAction(ISD::TRUNCATE, {MVT::v4i8, MVT::v2i16}, Legal);
721 P64VecVTs, Expand);
723 // Operation legalization queries the action using the result type.
724 setOperationAction(ISD::INSERT_SUBVECTOR, {MVT::v4i16, MVT::v8i8},
725 Custom);
726 } else {
727 setOperationAction(ISD::MUL, P64VecVTs, Legal);
728 setOperationAction({ISD::MULHS, ISD::MULHU}, {MVT::v2i32, MVT::v4i16},
729 Legal);
732 {MVT::v4i16, MVT::v2i32}, Legal);
733 setOperationAction(ISD::ANY_EXTEND_VECTOR_INREG, {MVT::v4i16, MVT::v2i32},
734 Custom);
735 setOperationAction(ISD::TRUNCATE, {MVT::v4i8, MVT::v2i16}, Custom);
736 }
737 // LegalizeVectorOps uses result VT, LegalizeDAG uses ExtVT.
740 {MVT::v2i8, MVT::v4i8, MVT::v2i16, MVT::v4i16, MVT::v2i32}, Legal);
741 }
742
743 if (Subtarget.hasStdExtZfbfmin()) {
749 setOperationAction(ZfhminZfbfminPromoteOps, MVT::bf16, Promote);
756 }
757
758 if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
759 if (Subtarget.hasStdExtZfhOrZhinx()) {
760 setOperationAction(FPLegalNodeTypes, MVT::f16, Legal);
761 setOperationAction(FPRndMode, MVT::f16,
762 Subtarget.hasStdExtZfa() ? Legal : Custom);
765 Subtarget.hasStdExtZfa() ? Legal : Custom);
766 if (Subtarget.hasStdExtZfa())
768 } else {
769 setOperationAction(ZfhminZfbfminPromoteOps, MVT::f16, Promote);
774 setOperationAction(Op, MVT::f16, Custom);
780 }
781
782 if (!Subtarget.hasStdExtD()) {
783 // FIXME: handle f16 fma when f64 is not legal. Using an f32 fma
784 // instruction runs into double rounding issues, so this is wrong.
785 // Normally we'd use an f64 fma, but without the D extension the f64 type
786 // is not legal. This should probably be a libcall.
787 AddPromotedToType(ISD::FMA, MVT::f16, MVT::f32);
788 AddPromotedToType(ISD::STRICT_FMA, MVT::f16, MVT::f32);
789 }
790
792
795 setCondCodeAction(FPCCToExpand, MVT::f16, Expand);
799
801 ISD::FNEARBYINT, MVT::f16,
802 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ? Legal : Promote);
807 MVT::f16, Promote);
808
809 // FIXME: Need to promote f16 STRICT_* to f32 libcalls, but we don't have
810 // complete support for all operations in LegalizeDAG.
815 MVT::f16, Promote);
816
817 // We need to custom promote this.
818 if (Subtarget.is64Bit())
820 }
821
822 if (Subtarget.hasStdExtFOrZfinx()) {
823 setOperationAction(FPLegalNodeTypes, MVT::f32, Legal);
824 setOperationAction(FPRndMode, MVT::f32,
825 Subtarget.hasStdExtZfa() ? Legal : Custom);
826 setCondCodeAction(FPCCToExpand, MVT::f32, Expand);
830 setOperationAction(FPOpToExpand, MVT::f32, Expand);
831 setOperationAction(FPOpToLibCall, MVT::f32, LibCall);
832 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
833 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
834 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::bf16, Expand);
835 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
839 Subtarget.isSoftFPABI() ? LibCall : Custom);
844
845 if (Subtarget.hasStdExtZfa()) {
849 } else {
851 }
852 }
853
854 if (Subtarget.hasStdExtFOrZfinx() && Subtarget.is64Bit())
856
857 if (Subtarget.hasStdExtDOrZdinx()) {
858 setOperationAction(FPLegalNodeTypes, MVT::f64, Legal);
859
860 if (!Subtarget.is64Bit())
862
863 if (Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
864 !Subtarget.is64Bit()) {
867 }
868
869 if (Subtarget.hasStdExtZfa()) {
871 setOperationAction(FPRndMode, MVT::f64, Legal);
874 } else {
875 if (Subtarget.is64Bit())
876 setOperationAction(FPRndMode, MVT::f64, Custom);
877
879 }
880
883 setCondCodeAction(FPCCToExpand, MVT::f64, Expand);
887 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
888 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
889 setOperationAction(FPOpToExpand, MVT::f64, Expand);
890 setOperationAction(FPOpToLibCall, MVT::f64, LibCall);
891 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
892 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
893 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::bf16, Expand);
894 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
898 Subtarget.isSoftFPABI() ? LibCall : Custom);
903 }
904
905 if (Subtarget.is64Bit()) {
908 MVT::i32, Custom);
910 }
911
912 if (Subtarget.hasStdExtFOrZfinx()) {
914 Custom);
915
916 // f16/bf16 require custom handling.
918 Custom);
920 Custom);
921
930 }
931
934 XLenVT, Custom);
935
937
938 if (Subtarget.is64Bit())
940
941 // TODO: On M-mode only targets, the cycle[h]/time[h] CSR may not be present.
942 // Unfortunately this can't be determined just from the ISA naming string.
944 Subtarget.is64Bit() ? Legal : Custom);
946 Subtarget.is64Bit() ? Legal : Custom);
947
948 if (Subtarget.is64Bit()) {
951 }
952
955 if (Subtarget.is64Bit())
957
958 if (Subtarget.hasVendorXMIPSCBOP())
960 else
962
963 if (Subtarget.hasStdExtZalrsc()) {
964 setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
965 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
967 else
969 } else if (Subtarget.hasForcedAtomics()) {
970 setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
971 } else {
973 }
974
976
978
979 if (getTargetMachine().getTargetTriple().isOSLinux()) {
980 // Custom lowering of llvm.clear_cache.
982 }
983
984 if (Subtarget.hasVInstructions()) {
986
988
989 // RVV intrinsics may have illegal operands.
990 // We also need to custom legalize vmv.x.s.
993 {MVT::i8, MVT::i16}, Custom);
994 if (Subtarget.is64Bit())
996 MVT::i32, Custom);
997 else
999 MVT::i64, Custom);
1000
1002 MVT::Other, Custom);
1003
1004 static const unsigned IntegerVPOps[] = {
1005 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
1006 ISD::VP_UREM, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
1007 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
1008 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
1009 ISD::VP_MERGE,
1010 ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
1011 ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_POISON};
1012
1013 static const unsigned FloatingPointVPOps[] = {
1014 ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
1015 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
1016 ISD::VP_REDUCE_FMINIMUM, ISD::VP_REDUCE_FMAXIMUM};
1017
1018 static const unsigned IntegerVecReduceOps[] = {
1022
1023 static const unsigned FloatingPointVecReduceOps[] = {
1026
1027 static const unsigned FloatingPointLibCallOps[] = {
1030
1031 if (!Subtarget.is64Bit()) {
1032 // We must custom-lower certain vXi64 operations on RV32 due to the vector
1033 // element type being illegal.
1035 MVT::i64, Custom);
1036
1037 setOperationAction(IntegerVecReduceOps, MVT::i64, Custom);
1038
1039 setOperationAction({ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
1040 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
1041 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
1042 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
1043 MVT::i64, Custom);
1044 }
1045
1046 for (MVT VT : BoolVecVTs) {
1047 if (!isTypeLegal(VT))
1048 continue;
1049
1051
1052 // Mask VTs are custom-expanded into a series of standard nodes
1056 VT, Custom);
1057
1059 Custom);
1060
1063 Expand);
1064 setOperationAction(ISD::VP_MERGE, VT, Custom);
1065
1067 ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_POISON},
1068 VT, Custom);
1069
1072 Custom);
1073
1075 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1076 Custom);
1077
1078 // RVV has native int->float & float->int conversions where the
1079 // element type sizes are within one power-of-two of each other. Any
1080 // wider distances between type sizes have to be lowered as sequences
1081 // which progressively narrow the gap in stages.
1086 VT, Custom);
1088 Custom);
1089
1090 // Expand all extending loads to types larger than this, and truncating
1091 // stores from types larger than this.
1093 setTruncStoreAction(VT, OtherVT, Expand);
1095 OtherVT, Expand);
1096 }
1097
1100
1102
1103 setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1104 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1105
1108 MVT::getVectorVT(MVT::i8, VT.getVectorElementCount()));
1109 }
1110
1111 for (MVT VT : IntVecVTs) {
1112 if (!isTypeLegal(VT))
1113 continue;
1114
1117
1118 // Vectors implement MULHS/MULHU.
1120
1121 // nxvXi64 MULHS/MULHU requires the V extension instead of Zve64*.
1122 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
1124
1126 Legal);
1127
1128 if (Subtarget.hasStdExtZvabd()) {
1131 } else {
1133 }
1134
1135 // Custom-lower extensions and truncations from/to mask types.
1137 VT, Custom);
1138
1139 // RVV has native int->float & float->int conversions where the
1140 // element type sizes are within one power-of-two of each other. Any
1141 // wider distances between type sizes have to be lowered as sequences
1142 // which progressively narrow the gap in stages.
1147 VT, Custom);
1149 Custom);
1153 VT, Legal);
1154
1155 // Integer VTs are lowered as a series of "RISCVISD::TRUNCATE_VECTOR_VL"
1156 // nodes which truncate by one power of two at a time.
1159 Custom);
1160
1161 // Custom-lower insert/extract operations to simplify patterns.
1163 Custom);
1164
1165 // Custom-lower reduction operations to set up the corresponding custom
1166 // nodes' operands.
1167 setOperationAction(IntegerVecReduceOps, VT, Custom);
1168
1169 setOperationAction(IntegerVPOps, VT, Custom);
1170
1172
1174 VT, Custom);
1175
1177 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1178 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1179 VT, Custom);
1180 setOperationAction(ISD::VP_LOAD_FF, VT, Custom);
1181
1184 VT, Custom);
1185
1188
1190
1192 setTruncStoreAction(VT, OtherVT, Expand);
1194 OtherVT, Expand);
1195 }
1196
1199
1201 VT, Custom);
1202
1203 if (Subtarget.hasStdExtZvkb()) {
1205 } else {
1208 }
1209
1210 if (Subtarget.hasStdExtZvbb()) {
1212 } else {
1215
1216 // Lower CTLZ_ZERO_POISON and CTTZ_ZERO_POISON if element of VT in the
1217 // range of f32.
1218 EVT FloatVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
1219 if (isTypeLegal(FloatVT)) {
1222 Custom);
1223 }
1224 }
1225
1226 if (VT.getVectorElementType() == MVT::i64) {
1227 if (Subtarget.hasStdExtZvbc())
1229 } else {
1230 if (Subtarget.hasStdExtZvbc32e()) {
1232 } else if (Subtarget.hasStdExtZvbc()) {
1233 // Promote to i64 if the lmul is small enough.
1234 // FIXME: Split if necessary to widen.
1235 // FIXME: Promote clmulh directly without legalizing to clmul first.
1236 MVT I64VecVT = MVT::getVectorVT(MVT::i64, VT.getVectorElementCount());
1237 if (isTypeLegal(I64VecVT))
1239 }
1240 }
1241
1245 VT, Legal);
1246 }
1247
1248 for (MVT VT : VecTupleVTs) {
1249 if (!isTypeLegal(VT))
1250 continue;
1251
1253 }
1254
1255 // Expand various CCs to best match the RVV ISA, which natively supports UNE
1256 // but no other unordered comparisons, and supports all ordered comparisons
1257 // except ONE. Additionally, we expand GT,OGT,GE,OGE for optimization
1258 // purposes; they are expanded to their swapped-operand CCs (LT,OLT,LE,OLE),
1259 // and we pattern-match those back to the "original", swapping operands once
1260 // more. This way we catch both operations and both "vf" and "fv" forms with
1261 // fewer patterns.
1262 static const ISD::CondCode VFPCCToExpand[] = {
1266 };
1267
1268 // TODO: support more ops.
1269 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
1274 ISD::FADD,
1275 ISD::FSUB,
1276 ISD::FMUL,
1277 ISD::FMA,
1278 ISD::FDIV,
1279 ISD::FSQRT,
1280 ISD::FCEIL,
1285 ISD::FRINT,
1288 ISD::SETCC,
1303
1304 // TODO: Make more of these ops legal.
1305 static const unsigned ZvfbfaPromoteOps[] = {ISD::FDIV,
1306 ISD::FSQRT,
1307 ISD::FCEIL,
1312 ISD::FRINT,
1321
1322 // TODO: support more vp ops.
1323 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
1324 ISD::VP_REDUCE_FMIN,
1325 ISD::VP_REDUCE_FMAX,
1326 ISD::VP_REDUCE_FMINIMUM,
1327 ISD::VP_REDUCE_FMAXIMUM};
1328
1329 // Sets common operation actions on RVV floating-point vector types.
1330 const auto SetCommonVFPActions = [&](MVT VT) {
1332 // RVV has native FP_ROUND & FP_EXTEND conversions where the element type
1333 // sizes are within one power-of-two of each other. Therefore conversions
1334 // between vXf16 and vXf64 must be lowered as sequences which convert via
1335 // vXf32.
1339 // Custom-lower insert/extract operations to simplify patterns.
1341 Custom);
1342 // Expand various condition codes (explained above).
1343 setCondCodeAction(VFPCCToExpand, VT, Expand);
1344
1347 Legal);
1349
1353 VT, Custom);
1354
1355 setOperationAction(FloatingPointVecReduceOps, VT, Custom);
1356
1357 // Expand FP operations that need libcalls.
1358 setOperationAction(FloatingPointLibCallOps, VT, Expand);
1359
1361
1363
1365
1367 VT, Custom);
1368
1370 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1371 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1372 VT, Custom);
1373 setOperationAction(ISD::VP_LOAD_FF, VT, Custom);
1374
1377
1380 VT, Custom);
1381
1384
1387 VT, Custom);
1388 setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1389 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1390
1391 setOperationAction(FloatingPointVPOps, VT, Custom);
1392
1394 Custom);
1397 VT, Legal);
1402 VT, Custom);
1403
1405 };
1406
1407 // Sets common extload/truncstore actions on RVV floating-point vector
1408 // types.
1409 const auto SetCommonVFPExtLoadTruncStoreActions =
1410 [&](MVT VT, ArrayRef<MVT::SimpleValueType> SmallerVTs) {
1411 for (auto SmallVT : SmallerVTs) {
1412 setTruncStoreAction(VT, SmallVT, Expand);
1413 setLoadExtAction(ISD::EXTLOAD, VT, SmallVT, Expand);
1414 }
1415 };
1416
1417 // Sets common actions for f16 and bf16 for when there's only
1418 // zvfhmin/zvfbfmin and we need to promote to f32 for most operations.
1419 const auto SetCommonPromoteToF32Actions = [&](MVT VT) {
1422 Custom);
1425 setOperationAction({ISD::VP_MERGE, ISD::SELECT}, VT,
1426 Custom);
1433 VT, Custom);
1434 setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1435 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1436 MVT EltVT = VT.getVectorElementType();
1437 if (isTypeLegal(EltVT))
1439 VT, Custom);
1440 else
1443 ISD::MGATHER, ISD::MSCATTER, ISD::VP_LOAD,
1444 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1445 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1446 ISD::VP_SCATTER},
1447 VT, Custom);
1448 setOperationAction(ISD::VP_LOAD_FF, VT, Custom);
1449
1453
1454 // Expand FP operations that need libcalls.
1455 setOperationAction(FloatingPointLibCallOps, VT, Expand);
1456
1458
1459 // Custom split nxv32[b]f16 since nxv32[b]f32 is not legal.
1460 if (getLMUL(VT) == RISCVVType::LMUL_8) {
1461 setOperationAction(ZvfhminZvfbfminPromoteOps, VT, Custom);
1462 setOperationAction(ZvfhminZvfbfminPromoteVPOps, VT, Custom);
1463 } else {
1464 MVT F32VecVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
1465 setOperationPromotedToType(ZvfhminZvfbfminPromoteOps, VT, F32VecVT);
1466 setOperationPromotedToType(ZvfhminZvfbfminPromoteVPOps, VT, F32VecVT);
1467 }
1468 };
1469
1470 // Sets common actions for zvfbfa, some of instructions are supported
1471 // natively so that we don't need to promote them.
1472 const auto SetZvfbfaActions = [&](MVT VT) {
1475 Custom);
1478 setOperationAction({ISD::VP_MERGE, ISD::SELECT}, VT,
1479 Custom);
1487 VT, Custom);
1490 Legal);
1493 setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1494 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1495
1500 VT, Legal);
1501 setCondCodeAction(VFPCCToExpand, VT, Expand);
1502
1504 ISD::MGATHER, ISD::MSCATTER, ISD::VP_LOAD,
1505 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1506 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1507 ISD::VP_SCATTER},
1508 VT, Custom);
1509 setOperationAction(ISD::VP_LOAD_FF, VT, Custom);
1510
1511 // Expand FP operations that need libcalls.
1512 setOperationAction(FloatingPointLibCallOps, VT, Expand);
1513
1515
1516 // Custom split nxv32[b]f16 since nxv32[b]f32 is not legal.
1517 if (getLMUL(VT) == RISCVVType::LMUL_8) {
1518 setOperationAction(ZvfbfaPromoteOps, VT, Custom);
1519 setOperationAction(ZvfhminZvfbfminPromoteVPOps, VT, Custom);
1520 } else {
1521 MVT F32VecVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
1522 setOperationPromotedToType(ZvfbfaPromoteOps, VT, F32VecVT);
1523 setOperationPromotedToType(ZvfhminZvfbfminPromoteVPOps, VT, F32VecVT);
1524 }
1525 };
1526
1527 if (Subtarget.hasVInstructionsF16()) {
1528 for (MVT VT : F16VecVTs) {
1529 if (!isTypeLegal(VT))
1530 continue;
1531 SetCommonVFPActions(VT);
1532 }
1533 } else if (Subtarget.hasVInstructionsF16Minimal()) {
1534 for (MVT VT : F16VecVTs) {
1535 if (!isTypeLegal(VT))
1536 continue;
1537 SetCommonPromoteToF32Actions(VT);
1538 }
1539 }
1540
1541 if (Subtarget.hasVInstructionsBF16()) {
1542 for (MVT VT : BF16VecVTs) {
1543 if (!isTypeLegal(VT))
1544 continue;
1545 SetZvfbfaActions(VT);
1546 }
1547 } else if (Subtarget.hasVInstructionsBF16Minimal()) {
1548 for (MVT VT : BF16VecVTs) {
1549 if (!isTypeLegal(VT))
1550 continue;
1551 SetCommonPromoteToF32Actions(VT);
1552 }
1553 }
1554
1555 if (Subtarget.hasVInstructionsF32()) {
1556 for (MVT VT : F32VecVTs) {
1557 if (!isTypeLegal(VT))
1558 continue;
1559 SetCommonVFPActions(VT);
1560 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1561 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1562 }
1563 }
1564
1565 if (Subtarget.hasVInstructionsF64()) {
1566 for (MVT VT : F64VecVTs) {
1567 if (!isTypeLegal(VT))
1568 continue;
1569 SetCommonVFPActions(VT);
1570 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1571 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1572 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1573 }
1574 }
1575
1576 if (Subtarget.useRVVForFixedLengthVectors()) {
1578 if (!useRVVForFixedLengthVectorVT(VT))
1579 continue;
1580
1581 // By default everything must be expanded.
1582 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
1585 setTruncStoreAction(VT, OtherVT, Expand);
1587 OtherVT, Expand);
1588 }
1589
1590 // Custom lower fixed vector undefs to scalable vector undefs to avoid
1591 // expansion to a build_vector of 0s.
1593
1594 // We use EXTRACT_SUBVECTOR as a "cast" from scalable to fixed.
1596 Custom);
1597
1600 Custom);
1601
1603 VT, Custom);
1604
1606 VT, Custom);
1607
1609
1611
1613
1615
1618 Custom);
1619
1621
1624 Custom);
1625
1627 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1628 Custom);
1629
1631 {
1640 },
1641 VT, Custom);
1643 Custom);
1644
1646
1647 // Operations below are different for between masks and other vectors.
1648 if (VT.getVectorElementType() == MVT::i1) {
1650
1651 setOperationAction(ISD::VP_MERGE, VT, Custom);
1652
1653 setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1654 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1655
1657 Custom);
1658 continue;
1659 }
1660
1661 // Make SPLAT_VECTOR Legal so DAGCombine will convert splat vectors to
1662 // it before type legalization for i64 vectors on RV32. It will then be
1663 // type legalized to SPLAT_VECTOR_PARTS which we need to Custom handle.
1664 // FIXME: Use SPLAT_VECTOR for all types? DAGCombine probably needs
1665 // improvements first.
1666 if (!Subtarget.is64Bit() && VT.getVectorElementType() == MVT::i64) {
1669
1670 // Lower BUILD_VECTOR with i64 type to VID on RV32 if possible.
1672 }
1673
1676
1677 setOperationAction({ISD::VP_LOAD, ISD::VP_STORE,
1678 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1679 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1680 ISD::VP_SCATTER},
1681 VT, Custom);
1682 setOperationAction(ISD::VP_LOAD_FF, VT, Custom);
1683
1687 VT, Custom);
1688
1691
1693
1694 // vXi64 MULHS/MULHU requires the V extension instead of Zve64*.
1695 if (VT.getVectorElementType() != MVT::i64 || Subtarget.hasStdExtV())
1697
1701 VT, Custom);
1702
1704
1707
1708 // Custom-lower reduction operations to set up the corresponding custom
1709 // nodes' operands.
1713 VT, Custom);
1714
1715 setOperationAction(IntegerVPOps, VT, Custom);
1716
1717 if (Subtarget.hasStdExtZvkb())
1719
1720 if (Subtarget.hasStdExtZvbb()) {
1723 VT, Custom);
1724 } else {
1725 // Lower CTLZ_ZERO_POISON and CTTZ_ZERO_POISON if element of VT in the
1726 // range of f32.
1727 EVT FloatVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
1728 if (isTypeLegal(FloatVT))
1731 Custom);
1732 }
1733
1734 if (VT.getVectorElementType() == MVT::i64) {
1735 if (Subtarget.hasStdExtZvbc())
1737 } else {
1738 if (Subtarget.hasStdExtZvbc32e()) {
1740 } else if (Subtarget.hasStdExtZvbc()) {
1741 // Promote to i64 as is done for scalable vectors.
1742 MVT I64VecVT =
1744 if (I64VecVT.isValid() && useRVVForFixedLengthVectorVT(I64VecVT))
1746 }
1747 }
1748
1752 VT, Custom);
1753 }
1754
1756 // There are no extending loads or truncating stores.
1757 for (MVT InnerVT : MVT::fp_fixedlen_vector_valuetypes()) {
1758 setLoadExtAction(ISD::EXTLOAD, VT, InnerVT, Expand);
1759 setTruncStoreAction(VT, InnerVT, Expand);
1760 }
1761
1762 if (!useRVVForFixedLengthVectorVT(VT))
1763 continue;
1764
1765 // By default everything must be expanded.
1766 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
1768
1769 // Custom lower fixed vector undefs to scalable vector undefs to avoid
1770 // expansion to a build_vector of 0s.
1772
1777 VT, Custom);
1778 setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1779 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1780
1782 VT, Custom);
1783
1786 VT, Custom);
1787 setOperationAction({ISD::VP_LOAD, ISD::VP_STORE, ISD::VP_GATHER,
1788 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1789 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1790 VT, Custom);
1791 setOperationAction(ISD::VP_LOAD_FF, VT, Custom);
1792
1795 Custom);
1796
1798
1799 if (VT.getVectorElementType() == MVT::f16 &&
1800 !Subtarget.hasVInstructionsF16()) {
1802 {ISD::VP_MERGE, ISD::VSELECT, ISD::SELECT}, VT,
1803 Custom);
1806 if (Subtarget.hasStdExtZfhmin()) {
1808 } else {
1809 // We need to custom legalize f16 build vectors if Zfhmin isn't
1810 // available.
1812 }
1816 MVT F32VecVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
1817 // Don't promote f16 vector operations to f32 if f32 vector type is
1818 // not legal.
1819 // Custom lower maximum LMUL case to split to 2 half LMUL operations.
1820 // TODO: Support more operations.
1821 if (!isTypeLegal(F32VecVT)) {
1825 VT, Custom);
1827 continue;
1828 }
1829 setOperationPromotedToType(ZvfhminZvfbfminPromoteOps, VT, F32VecVT);
1830 setOperationPromotedToType(ZvfhminZvfbfminPromoteVPOps, VT, F32VecVT);
1831 continue;
1832 }
1833
1834 if (VT.getVectorElementType() == MVT::bf16) {
1837 if (Subtarget.hasStdExtZfbfmin()) {
1839 } else {
1840 // We need to custom legalize bf16 build vectors if Zfbfmin isn't
1841 // available.
1843 }
1844 if (Subtarget.hasVInstructionsBF16()) {
1846 setCondCodeAction(VFPCCToExpand, VT, Expand);
1847 }
1849 {ISD::VP_MERGE, ISD::VSELECT, ISD::SELECT}, VT,
1850 Custom);
1851 MVT F32VecVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
1852 // Don't promote bf16 vector operations to f32 if f32 vector type is
1853 // not legal.
1854 // Custom lower maximum LMUL case to split to 2 half LMUL operations.
1855 // TODO: Support more operations.
1856 if (!isTypeLegal(F32VecVT)) {
1860 VT, Custom);
1862 continue;
1863 }
1864
1865 if (Subtarget.hasVInstructionsBF16())
1866 setOperationPromotedToType(ZvfbfaPromoteOps, VT, F32VecVT);
1867 else
1868 setOperationPromotedToType(ZvfhminZvfbfminPromoteOps, VT, F32VecVT);
1869 setOperationPromotedToType(ZvfhminZvfbfminPromoteVPOps, VT, F32VecVT);
1870 continue;
1871 }
1872
1874 Custom);
1875
1881 VT, Custom);
1882
1887 VT, Custom);
1888
1889 setCondCodeAction(VFPCCToExpand, VT, Expand);
1890
1893
1894 setOperationAction(FloatingPointVecReduceOps, VT, Custom);
1895
1896 setOperationAction(FloatingPointVPOps, VT, Custom);
1897
1904 VT, Custom);
1905 }
1906
1907 // Custom-legalize bitcasts from fixed-length vectors to scalar types.
1908 setOperationAction(ISD::BITCAST, {MVT::i8, MVT::i16, MVT::i32}, Custom);
1909 if (Subtarget.is64Bit())
1911 if (Subtarget.hasStdExtZfhminOrZhinxmin())
1913 if (Subtarget.hasStdExtZfbfmin())
1915 if (Subtarget.hasStdExtFOrZfinx())
1917 if (Subtarget.hasStdExtDOrZdinx())
1919 }
1920 }
1921
1922 if (Subtarget.hasStdExtZaamo())
1924
1925 if (Subtarget.hasForcedAtomics()) {
1926 // Force __sync libcalls to be emitted for atomic rmw/cas operations.
1932 XLenVT, LibCall);
1933 }
1934
1935 if (Subtarget.hasVendorXTHeadMemIdx()) {
1936 for (unsigned im : {ISD::PRE_INC, ISD::POST_INC}) {
1937 setIndexedLoadAction(im, MVT::i8, Legal);
1938 setIndexedStoreAction(im, MVT::i8, Legal);
1939 setIndexedLoadAction(im, MVT::i16, Legal);
1940 setIndexedStoreAction(im, MVT::i16, Legal);
1941 setIndexedLoadAction(im, MVT::i32, Legal);
1942 setIndexedStoreAction(im, MVT::i32, Legal);
1943
1944 if (Subtarget.is64Bit()) {
1945 setIndexedLoadAction(im, MVT::i64, Legal);
1946 setIndexedStoreAction(im, MVT::i64, Legal);
1947 }
1948 }
1949 }
1950
1951 if (Subtarget.hasVendorXCVmem() && !Subtarget.is64Bit()) {
1955
1959 }
1960
1961 // zve32x is broken for partial_reduce_umla, but let's not make it worse.
1962 if (Subtarget.hasStdExtZvdot4a8i() && Subtarget.getELen() >= 64) {
1963 static const unsigned MLAOps[] = {ISD::PARTIAL_REDUCE_SMLA,
1966 setPartialReduceMLAAction(MLAOps, MVT::nxv1i32, MVT::nxv4i8, Custom);
1967 setPartialReduceMLAAction(MLAOps, MVT::nxv2i32, MVT::nxv8i8, Custom);
1968 setPartialReduceMLAAction(MLAOps, MVT::nxv4i32, MVT::nxv16i8, Custom);
1969 setPartialReduceMLAAction(MLAOps, MVT::nxv8i32, MVT::nxv32i8, Custom);
1970 setPartialReduceMLAAction(MLAOps, MVT::nxv16i32, MVT::nxv64i8, Custom);
1971
1972 // An i64 accumulator is handled by performing an i32 vdot4a* and widening
1973 // the result to i64 (see lowerPARTIAL_REDUCE_MLA).
1974 setPartialReduceMLAAction(MLAOps, MVT::nxv1i64, MVT::nxv8i8, Custom);
1975 setPartialReduceMLAAction(MLAOps, MVT::nxv2i64, MVT::nxv16i8, Custom);
1976 setPartialReduceMLAAction(MLAOps, MVT::nxv4i64, MVT::nxv32i8, Custom);
1977 setPartialReduceMLAAction(MLAOps, MVT::nxv8i64, MVT::nxv64i8, Custom);
1978
1979 if (Subtarget.useRVVForFixedLengthVectors()) {
1981 if ((VT.getVectorElementType() != MVT::i32 &&
1982 VT.getVectorElementType() != MVT::i64) ||
1983 !useRVVForFixedLengthVectorVT(VT))
1984 continue;
1985 ElementCount EC = VT.getVectorElementCount();
1986 unsigned Scale = VT.getVectorElementType() == MVT::i64 ? 8 : 4;
1987 MVT ArgVT = MVT::getVectorVT(MVT::i8, EC.multiplyCoefficientBy(Scale));
1988 setPartialReduceMLAAction(MLAOps, VT, ArgVT, Custom);
1989 }
1990 }
1991 }
1992
1993 // Customize load and store operation for bf16 if zfh isn't enabled.
1994 if (Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh()) {
1995 setOperationAction(ISD::LOAD, MVT::bf16, Custom);
1997 }
1998
1999 // Function alignments.
2000 const Align FunctionAlignment(Subtarget.hasStdExtZca() ? 2 : 4);
2001 setMinFunctionAlignment(FunctionAlignment);
2002 // Set preferred alignments.
2003 setPrefFunctionAlignment(Subtarget.getPrefFunctionAlignment());
2004 setPrefLoopAlignment(Subtarget.getPrefLoopAlignment());
2005
2009 ISD::SRA});
2011
2012 if (Subtarget.hasStdExtFOrZfinx())
2014
2015 // Allow scalar min/max to be combined with vector reductions.
2016 if (Subtarget.hasVInstructions())
2018 if (Subtarget.hasVInstructions() || Subtarget.hasStdExtP())
2020
2021 if ((Subtarget.hasStdExtZbs() && Subtarget.is64Bit()) ||
2022 Subtarget.hasVInstructions() || Subtarget.hasStdExtP())
2024
2025 if (Subtarget.hasStdExtZbkb())
2027
2028 if (Subtarget.hasStdExtFOrZfinx())
2031 if (Subtarget.hasVInstructions())
2036 ISD::MLOAD,
2037 ISD::VP_GATHER,
2038 ISD::VP_SCATTER,
2039 ISD::SRL,
2040 ISD::SHL,
2041 ISD::STORE,
2045 ISD::VP_STORE,
2046 ISD::EXPERIMENTAL_VP_REVERSE,
2047 ISD::SDIV,
2048 ISD::UDIV,
2049 ISD::SREM,
2050 ISD::UREM,
2052 ISD::ABS,
2054 ISD::CTPOP,
2056 ISD::FMA,
2060
2061 if (Subtarget.hasVendorXTHeadMemPair())
2063 if (Subtarget.useRVVForFixedLengthVectors() || Subtarget.hasStdExtP())
2065
2066 setMaxDivRemBitWidthSupported(Subtarget.is64Bit() ? 128 : 64);
2067
2068 setMaxLargeFPConvertBitWidthSupported(Subtarget.is64Bit() ? 128 : 64);
2069
2070 setJumpIsExpensive(Subtarget.isJumpExpensive());
2071
2072 // Disable strict node mutation.
2073 IsStrictFPEnabled = true;
2074 EnableExtLdPromotion = true;
2075
2076 // Let the subtarget decide if a predictable select is more expensive than the
2077 // corresponding branch. This information is used in CGP/SelectOpt to decide
2078 // when to convert selects into branches.
2079 PredictableSelectIsExpensive = Subtarget.predictableSelectIsExpensive();
2080
2081 MaxStoresPerMemsetOptSize = Subtarget.getMaxStoresPerMemset(/*OptSize=*/true);
2082 MaxStoresPerMemset = Subtarget.getMaxStoresPerMemset(/*OptSize=*/false);
2083
2084 MaxGluedStoresPerMemcpy = Subtarget.getMaxGluedStoresPerMemcpy();
2085 MaxStoresPerMemcpyOptSize = Subtarget.getMaxStoresPerMemcpy(/*OptSize=*/true);
2086 MaxStoresPerMemcpy = Subtarget.getMaxStoresPerMemcpy(/*OptSize=*/false);
2087
2089 Subtarget.getMaxStoresPerMemmove(/*OptSize=*/true);
2090 MaxStoresPerMemmove = Subtarget.getMaxStoresPerMemmove(/*OptSize=*/false);
2091
2092 MaxLoadsPerMemcmpOptSize = Subtarget.getMaxLoadsPerMemcmp(/*OptSize=*/true);
2093 MaxLoadsPerMemcmp = Subtarget.getMaxLoadsPerMemcmp(/*OptSize=*/false);
2094}
2095
2098 if (Subtarget.is64Bit() && Subtarget.hasStdExtP())
2099 if (VT == MVT::v2i16 || VT == MVT::v4i8)
2100 return TypeWidenVector;
2101
2103}
2104
2106 LLVMContext &Context,
2107 EVT VT) const {
2108 if (!VT.isVector())
2109 return getPointerTy(DL);
2110 if (Subtarget.hasVInstructions() &&
2111 (VT.isScalableVector() || Subtarget.useRVVForFixedLengthVectors()))
2112 return EVT::getVectorVT(Context, MVT::i1, VT.getVectorElementCount());
2114}
2115
2118 const Value *LHS,
2119 const Value *RHS,
2120 const Function *F) const {
2121 if (F->hasOptSize())
2123
2124 // Merging conditions eliminates a branch, so the budget we are willing to
2125 // spend eagerly computing the RHS condition should scale with how expensive a
2126 // mispredicted branch is. A branch only costs the full penalty when actually
2127 // mispredicted, so scale it down by an assumed misprediction rate (~25%).
2128 int BaseCost = Subtarget.getMispredictionPenalty() / 4;
2129 if (BrMergingBaseCostThresh.getNumOccurrences() > 1)
2130 BaseCost = BrMergingBaseCostThresh;
2131
2132 return {BaseCost, BrMergingLikelyBias, BrMergingUnlikelyBias};
2133}
2134
2136 return Subtarget.getXLenVT();
2137}
2138
2139// Return false if we can lower get_vector_length to a vsetvli intrinsic.
2140bool RISCVTargetLowering::shouldExpandGetVectorLength(EVT TripCountVT,
2141 unsigned VF,
2142 bool IsScalable) const {
2143 if (!Subtarget.hasVInstructions())
2144 return true;
2145
2146 if (!IsScalable)
2147 return true;
2148
2149 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.getXLenVT())
2150 return true;
2151
2152 // Don't allow VF=1 if those types are't legal.
2153 if (VF < RISCV::RVVBitsPerBlock / Subtarget.getELen())
2154 return true;
2155
2156 // VLEN=32 support is incomplete.
2157 if (Subtarget.getRealMinVLen() < RISCV::RVVBitsPerBlock)
2158 return true;
2159
2160 // The maximum VF is for the smallest element width with LMUL=8.
2161 // VF must be a power of 2.
2162 unsigned MaxVF = RISCV::RVVBytesPerBlock * 8;
2163 return VF > MaxVF || !isPowerOf2_32(VF);
2164}
2165
2168 MachineFunction &MF, unsigned Intrinsic) const {
2169 IntrinsicInfo Info;
2170 auto &DL = I.getDataLayout();
2171
2172 auto SetRVVLoadStoreInfo = [&](unsigned PtrOp, bool IsStore,
2173 bool IsUnitStrided, bool UsePtrVal = false) {
2174 Info.opc = IsStore ? ISD::INTRINSIC_VOID : ISD::INTRINSIC_W_CHAIN;
2175 // We can't use ptrVal if the intrinsic can access memory before the
2176 // pointer. This means we can't use it for strided or indexed intrinsics.
2177 if (UsePtrVal)
2178 Info.ptrVal = I.getArgOperand(PtrOp);
2179 else
2180 Info.fallbackAddressSpace =
2181 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
2182 Type *MemTy;
2183 if (IsStore) {
2184 // Store value is the first operand.
2185 MemTy = I.getArgOperand(0)->getType();
2186 } else {
2187 // Use return type. If it's segment load, return type is a struct.
2188 MemTy = I.getType();
2189 if (MemTy->isStructTy())
2190 MemTy = MemTy->getStructElementType(0);
2191 }
2192 if (!IsUnitStrided)
2193 MemTy = MemTy->getScalarType();
2194
2195 Info.memVT = getValueType(DL, MemTy);
2196 if (MemTy->isTargetExtTy()) {
2197 // RISC-V vector tuple type's alignment type should be its element type.
2198 if (cast<TargetExtType>(MemTy)->getName() == "riscv.vector.tuple")
2199 MemTy = Type::getIntNTy(
2200 MemTy->getContext(),
2201 1 << cast<ConstantInt>(I.getArgOperand(I.arg_size() - 1))
2202 ->getZExtValue());
2203 Info.align = DL.getABITypeAlign(MemTy);
2204 } else {
2205 Info.align = Align(DL.getTypeStoreSize(MemTy->getScalarType()));
2206 }
2207 Info.size = MemoryLocation::UnknownSize;
2208 Info.flags |=
2210 Infos.push_back(Info);
2211 };
2212
2213 if (I.hasMetadata(LLVMContext::MD_nontemporal))
2215
2217 switch (Intrinsic) {
2218 default:
2219 return;
2220 case Intrinsic::riscv_masked_atomicrmw_xchg:
2221 case Intrinsic::riscv_masked_atomicrmw_add:
2222 case Intrinsic::riscv_masked_atomicrmw_sub:
2223 case Intrinsic::riscv_masked_atomicrmw_nand:
2224 case Intrinsic::riscv_masked_atomicrmw_max:
2225 case Intrinsic::riscv_masked_atomicrmw_min:
2226 case Intrinsic::riscv_masked_atomicrmw_umax:
2227 case Intrinsic::riscv_masked_atomicrmw_umin:
2228 case Intrinsic::riscv_masked_cmpxchg:
2229 // riscv_masked_{atomicrmw_*,cmpxchg} intrinsics represent an emulated
2230 // narrow atomic operation. These will be expanded to an LR/SC loop that
2231 // reads/writes to/from an aligned 4 byte location. And, or, shift, etc.
2232 // will be used to modify the appropriate part of the 4 byte data and
2233 // preserve the rest.
2234 Info.opc = ISD::INTRINSIC_W_CHAIN;
2235 Info.memVT = MVT::i32;
2236 Info.ptrVal = I.getArgOperand(0);
2237 Info.offset = 0;
2238 Info.align = Align(4);
2241 Infos.push_back(Info);
2242 return;
2243 case Intrinsic::riscv_seg2_load_mask:
2244 case Intrinsic::riscv_seg3_load_mask:
2245 case Intrinsic::riscv_seg4_load_mask:
2246 case Intrinsic::riscv_seg5_load_mask:
2247 case Intrinsic::riscv_seg6_load_mask:
2248 case Intrinsic::riscv_seg7_load_mask:
2249 case Intrinsic::riscv_seg8_load_mask:
2250 case Intrinsic::riscv_sseg2_load_mask:
2251 case Intrinsic::riscv_sseg3_load_mask:
2252 case Intrinsic::riscv_sseg4_load_mask:
2253 case Intrinsic::riscv_sseg5_load_mask:
2254 case Intrinsic::riscv_sseg6_load_mask:
2255 case Intrinsic::riscv_sseg7_load_mask:
2256 case Intrinsic::riscv_sseg8_load_mask:
2257 SetRVVLoadStoreInfo(/*PtrOp*/ 0, /*IsStore*/ false,
2258 /*IsUnitStrided*/ false, /*UsePtrVal*/ true);
2259 return;
2260 case Intrinsic::riscv_seg2_store_mask:
2261 case Intrinsic::riscv_seg3_store_mask:
2262 case Intrinsic::riscv_seg4_store_mask:
2263 case Intrinsic::riscv_seg5_store_mask:
2264 case Intrinsic::riscv_seg6_store_mask:
2265 case Intrinsic::riscv_seg7_store_mask:
2266 case Intrinsic::riscv_seg8_store_mask:
2267 // Operands are (vec, ..., vec, ptr, mask, vl)
2268 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 3,
2269 /*IsStore*/ true,
2270 /*IsUnitStrided*/ false, /*UsePtrVal*/ true);
2271 return;
2272 case Intrinsic::riscv_sseg2_store_mask:
2273 case Intrinsic::riscv_sseg3_store_mask:
2274 case Intrinsic::riscv_sseg4_store_mask:
2275 case Intrinsic::riscv_sseg5_store_mask:
2276 case Intrinsic::riscv_sseg6_store_mask:
2277 case Intrinsic::riscv_sseg7_store_mask:
2278 case Intrinsic::riscv_sseg8_store_mask:
2279 // Operands are (vec, ..., vec, ptr, offset, mask, vl)
2280 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 4,
2281 /*IsStore*/ true,
2282 /*IsUnitStrided*/ false, /*UsePtrVal*/ true);
2283 return;
2284 case Intrinsic::riscv_vlm:
2285 SetRVVLoadStoreInfo(/*PtrOp*/ 0,
2286 /*IsStore*/ false,
2287 /*IsUnitStrided*/ true,
2288 /*UsePtrVal*/ true);
2289 return;
2290 case Intrinsic::riscv_vle:
2291 case Intrinsic::riscv_vle_mask:
2292 case Intrinsic::riscv_vleff:
2293 case Intrinsic::riscv_vleff_mask:
2294 SetRVVLoadStoreInfo(/*PtrOp*/ 1,
2295 /*IsStore*/ false,
2296 /*IsUnitStrided*/ true,
2297 /*UsePtrVal*/ true);
2298 return;
2299 case Intrinsic::riscv_vsm:
2300 case Intrinsic::riscv_vse:
2301 case Intrinsic::riscv_vse_mask:
2302 SetRVVLoadStoreInfo(/*PtrOp*/ 1,
2303 /*IsStore*/ true,
2304 /*IsUnitStrided*/ true,
2305 /*UsePtrVal*/ true);
2306 return;
2307 case Intrinsic::riscv_vlse:
2308 case Intrinsic::riscv_vlse_mask:
2309 case Intrinsic::riscv_vloxei:
2310 case Intrinsic::riscv_vloxei_mask:
2311 case Intrinsic::riscv_vluxei:
2312 case Intrinsic::riscv_vluxei_mask:
2313 SetRVVLoadStoreInfo(/*PtrOp*/ 1,
2314 /*IsStore*/ false,
2315 /*IsUnitStrided*/ false);
2316 return;
2317 case Intrinsic::riscv_vsse:
2318 case Intrinsic::riscv_vsse_mask:
2319 case Intrinsic::riscv_vsoxei:
2320 case Intrinsic::riscv_vsoxei_mask:
2321 case Intrinsic::riscv_vsuxei:
2322 case Intrinsic::riscv_vsuxei_mask:
2323 SetRVVLoadStoreInfo(/*PtrOp*/ 1,
2324 /*IsStore*/ true,
2325 /*IsUnitStrided*/ false);
2326 return;
2327 case Intrinsic::riscv_vlseg2:
2328 case Intrinsic::riscv_vlseg3:
2329 case Intrinsic::riscv_vlseg4:
2330 case Intrinsic::riscv_vlseg5:
2331 case Intrinsic::riscv_vlseg6:
2332 case Intrinsic::riscv_vlseg7:
2333 case Intrinsic::riscv_vlseg8:
2334 case Intrinsic::riscv_vlseg2ff:
2335 case Intrinsic::riscv_vlseg3ff:
2336 case Intrinsic::riscv_vlseg4ff:
2337 case Intrinsic::riscv_vlseg5ff:
2338 case Intrinsic::riscv_vlseg6ff:
2339 case Intrinsic::riscv_vlseg7ff:
2340 case Intrinsic::riscv_vlseg8ff:
2341 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 3,
2342 /*IsStore*/ false,
2343 /*IsUnitStrided*/ false, /*UsePtrVal*/ true);
2344 return;
2345 case Intrinsic::riscv_vlseg2_mask:
2346 case Intrinsic::riscv_vlseg3_mask:
2347 case Intrinsic::riscv_vlseg4_mask:
2348 case Intrinsic::riscv_vlseg5_mask:
2349 case Intrinsic::riscv_vlseg6_mask:
2350 case Intrinsic::riscv_vlseg7_mask:
2351 case Intrinsic::riscv_vlseg8_mask:
2352 case Intrinsic::riscv_vlseg2ff_mask:
2353 case Intrinsic::riscv_vlseg3ff_mask:
2354 case Intrinsic::riscv_vlseg4ff_mask:
2355 case Intrinsic::riscv_vlseg5ff_mask:
2356 case Intrinsic::riscv_vlseg6ff_mask:
2357 case Intrinsic::riscv_vlseg7ff_mask:
2358 case Intrinsic::riscv_vlseg8ff_mask:
2359 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 5,
2360 /*IsStore*/ false,
2361 /*IsUnitStrided*/ false, /*UsePtrVal*/ true);
2362 return;
2363 case Intrinsic::riscv_vlsseg2:
2364 case Intrinsic::riscv_vlsseg3:
2365 case Intrinsic::riscv_vlsseg4:
2366 case Intrinsic::riscv_vlsseg5:
2367 case Intrinsic::riscv_vlsseg6:
2368 case Intrinsic::riscv_vlsseg7:
2369 case Intrinsic::riscv_vlsseg8:
2370 case Intrinsic::riscv_vloxseg2:
2371 case Intrinsic::riscv_vloxseg3:
2372 case Intrinsic::riscv_vloxseg4:
2373 case Intrinsic::riscv_vloxseg5:
2374 case Intrinsic::riscv_vloxseg6:
2375 case Intrinsic::riscv_vloxseg7:
2376 case Intrinsic::riscv_vloxseg8:
2377 case Intrinsic::riscv_vluxseg2:
2378 case Intrinsic::riscv_vluxseg3:
2379 case Intrinsic::riscv_vluxseg4:
2380 case Intrinsic::riscv_vluxseg5:
2381 case Intrinsic::riscv_vluxseg6:
2382 case Intrinsic::riscv_vluxseg7:
2383 case Intrinsic::riscv_vluxseg8:
2384 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 4,
2385 /*IsStore*/ false,
2386 /*IsUnitStrided*/ false);
2387 return;
2388 case Intrinsic::riscv_vlsseg2_mask:
2389 case Intrinsic::riscv_vlsseg3_mask:
2390 case Intrinsic::riscv_vlsseg4_mask:
2391 case Intrinsic::riscv_vlsseg5_mask:
2392 case Intrinsic::riscv_vlsseg6_mask:
2393 case Intrinsic::riscv_vlsseg7_mask:
2394 case Intrinsic::riscv_vlsseg8_mask:
2395 case Intrinsic::riscv_vloxseg2_mask:
2396 case Intrinsic::riscv_vloxseg3_mask:
2397 case Intrinsic::riscv_vloxseg4_mask:
2398 case Intrinsic::riscv_vloxseg5_mask:
2399 case Intrinsic::riscv_vloxseg6_mask:
2400 case Intrinsic::riscv_vloxseg7_mask:
2401 case Intrinsic::riscv_vloxseg8_mask:
2402 case Intrinsic::riscv_vluxseg2_mask:
2403 case Intrinsic::riscv_vluxseg3_mask:
2404 case Intrinsic::riscv_vluxseg4_mask:
2405 case Intrinsic::riscv_vluxseg5_mask:
2406 case Intrinsic::riscv_vluxseg6_mask:
2407 case Intrinsic::riscv_vluxseg7_mask:
2408 case Intrinsic::riscv_vluxseg8_mask:
2409 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 6,
2410 /*IsStore*/ false,
2411 /*IsUnitStrided*/ false);
2412 return;
2413 case Intrinsic::riscv_vsseg2:
2414 case Intrinsic::riscv_vsseg3:
2415 case Intrinsic::riscv_vsseg4:
2416 case Intrinsic::riscv_vsseg5:
2417 case Intrinsic::riscv_vsseg6:
2418 case Intrinsic::riscv_vsseg7:
2419 case Intrinsic::riscv_vsseg8:
2420 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 3,
2421 /*IsStore*/ true,
2422 /*IsUnitStrided*/ false);
2423 return;
2424 case Intrinsic::riscv_vsseg2_mask:
2425 case Intrinsic::riscv_vsseg3_mask:
2426 case Intrinsic::riscv_vsseg4_mask:
2427 case Intrinsic::riscv_vsseg5_mask:
2428 case Intrinsic::riscv_vsseg6_mask:
2429 case Intrinsic::riscv_vsseg7_mask:
2430 case Intrinsic::riscv_vsseg8_mask:
2431 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 4,
2432 /*IsStore*/ true,
2433 /*IsUnitStrided*/ false);
2434 return;
2435 case Intrinsic::riscv_vssseg2:
2436 case Intrinsic::riscv_vssseg3:
2437 case Intrinsic::riscv_vssseg4:
2438 case Intrinsic::riscv_vssseg5:
2439 case Intrinsic::riscv_vssseg6:
2440 case Intrinsic::riscv_vssseg7:
2441 case Intrinsic::riscv_vssseg8:
2442 case Intrinsic::riscv_vsoxseg2:
2443 case Intrinsic::riscv_vsoxseg3:
2444 case Intrinsic::riscv_vsoxseg4:
2445 case Intrinsic::riscv_vsoxseg5:
2446 case Intrinsic::riscv_vsoxseg6:
2447 case Intrinsic::riscv_vsoxseg7:
2448 case Intrinsic::riscv_vsoxseg8:
2449 case Intrinsic::riscv_vsuxseg2:
2450 case Intrinsic::riscv_vsuxseg3:
2451 case Intrinsic::riscv_vsuxseg4:
2452 case Intrinsic::riscv_vsuxseg5:
2453 case Intrinsic::riscv_vsuxseg6:
2454 case Intrinsic::riscv_vsuxseg7:
2455 case Intrinsic::riscv_vsuxseg8:
2456 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 4,
2457 /*IsStore*/ true,
2458 /*IsUnitStrided*/ false);
2459 return;
2460 case Intrinsic::riscv_vssseg2_mask:
2461 case Intrinsic::riscv_vssseg3_mask:
2462 case Intrinsic::riscv_vssseg4_mask:
2463 case Intrinsic::riscv_vssseg5_mask:
2464 case Intrinsic::riscv_vssseg6_mask:
2465 case Intrinsic::riscv_vssseg7_mask:
2466 case Intrinsic::riscv_vssseg8_mask:
2467 case Intrinsic::riscv_vsoxseg2_mask:
2468 case Intrinsic::riscv_vsoxseg3_mask:
2469 case Intrinsic::riscv_vsoxseg4_mask:
2470 case Intrinsic::riscv_vsoxseg5_mask:
2471 case Intrinsic::riscv_vsoxseg6_mask:
2472 case Intrinsic::riscv_vsoxseg7_mask:
2473 case Intrinsic::riscv_vsoxseg8_mask:
2474 case Intrinsic::riscv_vsuxseg2_mask:
2475 case Intrinsic::riscv_vsuxseg3_mask:
2476 case Intrinsic::riscv_vsuxseg4_mask:
2477 case Intrinsic::riscv_vsuxseg5_mask:
2478 case Intrinsic::riscv_vsuxseg6_mask:
2479 case Intrinsic::riscv_vsuxseg7_mask:
2480 case Intrinsic::riscv_vsuxseg8_mask:
2481 SetRVVLoadStoreInfo(/*PtrOp*/ I.arg_size() - 5,
2482 /*IsStore*/ true,
2483 /*IsUnitStrided*/ false);
2484 return;
2485 case Intrinsic::riscv_sf_vlte8:
2486 case Intrinsic::riscv_sf_vlte16:
2487 case Intrinsic::riscv_sf_vlte32:
2488 case Intrinsic::riscv_sf_vlte64:
2489 Info.opc = ISD::INTRINSIC_VOID;
2490 Info.ptrVal = I.getArgOperand(1);
2491 switch (Intrinsic) {
2492 case Intrinsic::riscv_sf_vlte8:
2493 Info.memVT = MVT::i8;
2494 Info.align = Align(1);
2495 break;
2496 case Intrinsic::riscv_sf_vlte16:
2497 Info.memVT = MVT::i16;
2498 Info.align = Align(2);
2499 break;
2500 case Intrinsic::riscv_sf_vlte32:
2501 Info.memVT = MVT::i32;
2502 Info.align = Align(4);
2503 break;
2504 case Intrinsic::riscv_sf_vlte64:
2505 Info.memVT = MVT::i64;
2506 Info.align = Align(8);
2507 break;
2508 }
2509 Info.size = MemoryLocation::UnknownSize;
2510 Info.flags |= MachineMemOperand::MOLoad;
2511 Infos.push_back(Info);
2512 return;
2513 case Intrinsic::riscv_sf_vste8:
2514 case Intrinsic::riscv_sf_vste16:
2515 case Intrinsic::riscv_sf_vste32:
2516 case Intrinsic::riscv_sf_vste64:
2517 Info.opc = ISD::INTRINSIC_VOID;
2518 Info.ptrVal = I.getArgOperand(1);
2519 switch (Intrinsic) {
2520 case Intrinsic::riscv_sf_vste8:
2521 Info.memVT = MVT::i8;
2522 Info.align = Align(1);
2523 break;
2524 case Intrinsic::riscv_sf_vste16:
2525 Info.memVT = MVT::i16;
2526 Info.align = Align(2);
2527 break;
2528 case Intrinsic::riscv_sf_vste32:
2529 Info.memVT = MVT::i32;
2530 Info.align = Align(4);
2531 break;
2532 case Intrinsic::riscv_sf_vste64:
2533 Info.memVT = MVT::i64;
2534 Info.align = Align(8);
2535 break;
2536 }
2537 Info.size = MemoryLocation::UnknownSize;
2538 Info.flags |= MachineMemOperand::MOStore;
2539 Infos.push_back(Info);
2540 return;
2541 }
2542}
2543
2545 const AddrMode &AM, Type *Ty,
2546 unsigned AS,
2547 Instruction *I) const {
2548 // No global is ever allowed as a base.
2549 if (AM.BaseGV)
2550 return false;
2551
2552 // None of our addressing modes allows a scalable offset
2553 if (AM.ScalableOffset)
2554 return false;
2555
2556 // RVV instructions only support register addressing.
2557 if (Subtarget.hasVInstructions() && isa<VectorType>(Ty))
2558 return AM.HasBaseReg && AM.Scale == 0 && !AM.BaseOffs;
2559
2560 // The Xqcilo extension provides load/store instructions with a 26-bit signed
2561 // offset.
2562 if (Subtarget.hasVendorXqcilo()) {
2563 if (!isInt<26>(AM.BaseOffs))
2564 return false;
2565 } else if (!isInt<12>(AM.BaseOffs)) {
2566 // Otherwise require a 12-bit signed offset.
2567 return false;
2568 }
2569
2570 switch (AM.Scale) {
2571 case 0: // "r+i" or just "i", depending on HasBaseReg.
2572 break;
2573 case 1:
2574 if (!AM.HasBaseReg) // allow "r+i".
2575 break;
2576 return false; // disallow "r+r" or "r+r+i".
2577 default:
2578 return false;
2579 }
2580
2581 return true;
2582}
2583
2585 return isInt<12>(Imm);
2586}
2587
2589 // The Xqcilia extension provides add-immediate instructions with a 26-bit
2590 // signed immediate.
2591 if (Subtarget.hasVendorXqcilia())
2592 return isInt<26>(Imm);
2593 return isInt<12>(Imm);
2594}
2595
2596// On RV32, 64-bit integers are split into their high and low parts and held
2597// in two different registers, so the trunc is free since the low register can
2598// just be used.
2599// FIXME: Should we consider i64->i32 free on RV64 to match the EVT version of
2600// isTruncateFree?
2602 if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
2603 return false;
2604 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
2605 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
2606 return (SrcBits == 64 && DestBits == 32);
2607}
2608
2610 // We consider i64->i32 free on RV64 since we have good selection of W
2611 // instructions that make promoting operations back to i64 free in many cases.
2612 if (SrcVT.isVector() || DstVT.isVector() || !SrcVT.isInteger() ||
2613 !DstVT.isInteger())
2614 return false;
2615 unsigned SrcBits = SrcVT.getSizeInBits();
2616 unsigned DestBits = DstVT.getSizeInBits();
2617 return (SrcBits == 64 && DestBits == 32);
2618}
2619
2621 EVT SrcVT = Val.getValueType();
2622 // free truncate from vnsrl and vnsra
2623 if (Subtarget.hasVInstructions() &&
2624 (Val.getOpcode() == ISD::SRL || Val.getOpcode() == ISD::SRA) &&
2625 SrcVT.isVector() && VT2.isVector()) {
2626 unsigned SrcBits = SrcVT.getVectorElementType().getSizeInBits();
2627 unsigned DestBits = VT2.getVectorElementType().getSizeInBits();
2628 if (SrcBits == DestBits * 2) {
2629 return true;
2630 }
2631 }
2632 return TargetLowering::isTruncateFree(Val, VT2);
2633}
2634
2636 // Zexts are free if they can be combined with a load.
2637 // Don't advertise i32->i64 zextload as being free for RV64. It interacts
2638 // poorly with type legalization of compares preferring sext.
2639 if (auto *LD = dyn_cast<LoadSDNode>(Val)) {
2640 EVT MemVT = LD->getMemoryVT();
2641 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
2642 (LD->getExtensionType() == ISD::NON_EXTLOAD ||
2643 LD->getExtensionType() == ISD::ZEXTLOAD))
2644 return true;
2645 }
2646
2647 return TargetLowering::isZExtFree(Val, VT2);
2648}
2649
2651 return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
2652}
2653
2655 return Subtarget.is64Bit() && CI->getType()->isIntegerTy(32);
2656}
2657
2659 return Subtarget.hasCTZLike();
2660}
2661
2663 return Subtarget.hasCLZLike();
2664}
2665
2667 const Instruction &AndI) const {
2668 // We expect to be able to match a bit extraction instruction if the Zbs
2669 // extension is supported and the mask is a power of two. However, we
2670 // conservatively return false if the mask would fit in an ANDI instruction,
2671 // on the basis that it's possible the sinking+duplication of the AND in
2672 // CodeGenPrepare triggered by this hook wouldn't decrease the instruction
2673 // count and would increase code size (e.g. ANDI+BNEZ => BEXTI+BNEZ).
2674 if (!Subtarget.hasBEXTILike())
2675 return false;
2677 if (!Mask)
2678 return false;
2679 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2680}
2681
2683 EVT VT = Y.getValueType();
2684
2685 if (VT.isVector())
2686 return false;
2687
2688 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2689 (!isa<ConstantSDNode>(Y) || cast<ConstantSDNode>(Y)->isOpaque());
2690}
2691
2693 EVT VT = Y.getValueType();
2694
2695 if (!VT.isVector())
2696 return hasAndNotCompare(Y);
2697
2698 return Subtarget.hasStdExtZvkb();
2699}
2700
2702 // Zbs provides BEXT[_I], which can be used with SEQZ/SNEZ as a bit test.
2703 if (Subtarget.hasStdExtZbs())
2704 return X.getValueType().isScalarInteger();
2705 auto *C = dyn_cast<ConstantSDNode>(Y);
2706 // XTheadBs provides th.tst (similar to bexti), if Y is a constant
2707 if (Subtarget.hasVendorXTHeadBs())
2708 return C != nullptr;
2709 // We can use ANDI+SEQZ/SNEZ as a bit test. Y contains the bit position.
2710 return C && C->getAPIntValue().ule(10);
2711}
2712
2714 unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X,
2715 SDValue Y) const {
2716 if (SelectOpcode != ISD::VSELECT)
2717 return false;
2718
2719 // Only enable for rvv.
2720 if (!VT.isVector() || !Subtarget.hasVInstructions())
2721 return false;
2722
2723 if (VT.isFixedLengthVector() && !isTypeLegal(VT))
2724 return false;
2725
2726 return true;
2727}
2728
2730 Type *Ty) const {
2731 assert(Ty->isIntegerTy());
2732
2733 unsigned BitSize = Ty->getIntegerBitWidth();
2734 if (BitSize > Subtarget.getXLen())
2735 return false;
2736
2737 // Fast path, assume 32-bit immediates are cheap.
2738 int64_t Val = Imm.getSExtValue();
2739 if (isInt<32>(Val))
2740 return true;
2741
2742 // A constant pool entry may be more aligned than the load we're trying to
2743 // replace. If we don't support unaligned scalar mem, prefer the constant
2744 // pool.
2745 // TODO: Can the caller pass down the alignment?
2746 if (!Subtarget.enableUnalignedScalarMem())
2747 return true;
2748
2749 // Prefer to keep the load if it would require many instructions.
2750 // This uses the same threshold we use for constant pools but doesn't
2751 // check useConstantPoolForLargeInts.
2752 // TODO: Should we keep the load only when we're definitely going to emit a
2753 // constant pool?
2754
2756 return Seq.size() <= Subtarget.getMaxBuildIntsCost();
2757}
2758
2762 unsigned OldShiftOpcode, unsigned NewShiftOpcode,
2763 SelectionDAG &DAG) const {
2764 // One interesting pattern that we'd want to form is 'bit extract':
2765 // ((1 >> Y) & 1) ==/!= 0
2766 // But we also need to be careful not to try to reverse that fold.
2767
2768 // Is this '((1 >> Y) & 1)'?
2769 if (XC && OldShiftOpcode == ISD::SRL && XC->isOne())
2770 return false; // Keep the 'bit extract' pattern.
2771
2772 // Will this be '((1 >> Y) & 1)' after the transform?
2773 if (NewShiftOpcode == ISD::SRL && CC->isOne())
2774 return true; // Do form the 'bit extract' pattern.
2775
2776 // If 'X' is a constant, and we transform, then we will immediately
2777 // try to undo the fold, thus causing endless combine loop.
2778 // So only do the transform if X is not a constant. This matches the default
2779 // implementation of this function.
2780 return !XC;
2781}
2782
2784 unsigned Opc = VecOp.getOpcode();
2785
2786 // Assume target opcodes can't be scalarized.
2787 // TODO - do we have any exceptions?
2788 if (Opc >= ISD::BUILTIN_OP_END || !isBinOp(Opc))
2789 return false;
2790
2791 // If the vector op is not supported, try to convert to scalar.
2792 EVT VecVT = VecOp.getValueType();
2794 return true;
2795
2796 // If the vector op is supported, but the scalar op is not, the transform may
2797 // not be worthwhile.
2798 // Permit a vector binary operation can be converted to scalar binary
2799 // operation which is custom lowered with illegal type.
2800 EVT ScalarVT = VecVT.getScalarType();
2801 return isOperationLegalOrCustomOrPromote(Opc, ScalarVT) ||
2802 isOperationCustom(Opc, ScalarVT);
2803}
2804
2806 const GlobalAddressSDNode *GA) const {
2807 // In order to maximise the opportunity for common subexpression elimination,
2808 // keep a separate ADD node for the global address offset instead of folding
2809 // it in the global address node. Later peephole optimisations may choose to
2810 // fold it back in when profitable.
2811 return false;
2812}
2813
2814// Returns 0-31 if the fli instruction is available for the type and this is
2815// legal FP immediate for the type. Returns -1 otherwise.
2817 if (!Subtarget.hasStdExtZfa())
2818 return -1;
2819
2820 bool IsSupportedVT = false;
2821 if (VT == MVT::f16) {
2822 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2823 } else if (VT == MVT::f32) {
2824 IsSupportedVT = true;
2825 } else if (VT == MVT::f64) {
2826 assert(Subtarget.hasStdExtD() && "Expect D extension");
2827 IsSupportedVT = true;
2828 }
2829
2830 if (!IsSupportedVT)
2831 return -1;
2832
2834}
2835
2837 bool ForCodeSize) const {
2838 bool IsLegalVT = false;
2839 if (VT == MVT::f16)
2840 IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin();
2841 else if (VT == MVT::f32)
2842 IsLegalVT = Subtarget.hasStdExtFOrZfinx();
2843 else if (VT == MVT::f64)
2844 IsLegalVT = Subtarget.hasStdExtDOrZdinx();
2845 else if (VT == MVT::bf16)
2846 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2847
2848 if (!IsLegalVT)
2849 return false;
2850
2851 if (getLegalZfaFPImm(Imm, VT) >= 0)
2852 return true;
2853
2854 // Some constants can be produced by fli+fneg.
2855 if (Imm.isNegative() && getLegalZfaFPImm(-Imm, VT) >= 0)
2856 return true;
2857
2858 // Cannot create a 64 bit floating-point immediate value for rv32.
2859 if (Subtarget.getXLen() < VT.getScalarSizeInBits()) {
2860 // td can handle +0.0 or -0.0 already.
2861 // -0.0 can be created by fmv + fneg.
2862 return Imm.isZero();
2863 }
2864
2865 // Special case: fmv + fneg
2866 if (Imm.isNegZero())
2867 return true;
2868
2869 // Building an integer and then converting requires a fmv at the end of
2870 // the integer sequence. The fmv is not required for Zfinx.
2871 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2872 const int Cost =
2873 FmvCost + RISCVMatInt::getIntMatCost(Imm.bitcastToAPInt(),
2874 Subtarget.getXLen(), Subtarget);
2875 return Cost <= FPImmCost;
2876}
2877
2878// TODO: This is very conservative.
2881 unsigned Index) const {
2882 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
2883 (ResVT == MVT::v4i8 || ResVT == MVT::v2i16)) {
2884 if ((Index % ResVT.getVectorNumElements()) == 0)
2887 }
2888
2889 if (!Subtarget.hasVInstructions())
2891
2894
2895 // Extracts from index 0 are just subreg extracts.
2896 if (Index == 0)
2898
2899 // Only support extracting a fixed from a fixed vector for now.
2900 if (ResVT.isScalableVector() || SrcVT.isScalableVector())
2902
2903 EVT EltVT = ResVT.getVectorElementType();
2904 assert(EltVT == SrcVT.getVectorElementType() && "Should hold for node");
2905
2906 // The smallest type we can slide is i8.
2907 if (EltVT == MVT::i1)
2909
2910 unsigned ResElts = ResVT.getVectorNumElements();
2911 unsigned SrcElts = SrcVT.getVectorNumElements();
2912
2913 unsigned MinVLen = Subtarget.getRealMinVLen();
2914 unsigned MinVLMAX = MinVLen / EltVT.getSizeInBits();
2915
2916 // If we're extracting only data from the first VLEN bits of the source
2917 // then we can always do this with an m1 vslidedown.vx. Restricting the
2918 // Index ensures we can use a vslidedown.vi.
2919 // TODO: We can generalize this when the exact VLEN is known.
2920 if (Index + ResElts <= MinVLMAX && Index < 31)
2922
2923 // Convervatively only handle extracting half of a vector.
2924 // TODO: We can do arbitrary slidedowns, but for now only support extracting
2925 // the upper half of a vector until we have more test coverage.
2926 // TODO: For sizes which aren't multiples of VLEN sizes, this may not be
2927 // a cheap extract. However, this case is important in practice for
2928 // shuffled extracts of longer vectors. How resolve?
2929 if ((ResElts * 2) == SrcElts && Index == ResElts)
2932}
2933
2935 CallingConv::ID CC,
2936 EVT VT) const {
2937 // Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled.
2938 // We might still end up using a GPR but that will be decided based on ABI.
2939 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2940 !Subtarget.hasStdExtZfhminOrZhinxmin())
2941 return MVT::f32;
2942
2943 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
2944}
2945
2946unsigned
2948 std::optional<MVT> RegisterVT) const {
2949 // Pair inline assembly operand
2950 if (VT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2951 *RegisterVT == MVT::Untyped)
2952 return 1;
2953
2954 return TargetLowering::getNumRegisters(Context, VT, RegisterVT);
2955}
2956
2958 CallingConv::ID CC,
2959 EVT VT) const {
2960 // Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled.
2961 // We might still end up using a GPR but that will be decided based on ABI.
2962 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2963 !Subtarget.hasStdExtZfhminOrZhinxmin())
2964 return 1;
2965
2966 return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
2967}
2968
2969// Changes the condition code and swaps operands if necessary, so the SetCC
2970// operation matches one of the comparisons supported directly by branches
2971// in the RISC-V ISA. May adjust compares to favor compare with 0 over compare
2972// with 1/-1.
2974 ISD::CondCode &CC, SelectionDAG &DAG,
2975 const RISCVSubtarget &Subtarget) {
2976 // If this is a single bit test that can't be handled by ANDI, shift the
2977 // bit to be tested to the MSB and perform a signed compare with 0.
2978 if (isIntEqualitySetCC(CC) && isNullConstant(RHS) &&
2979 LHS.getOpcode() == ISD::AND && LHS.hasOneUse() &&
2980 isa<ConstantSDNode>(LHS.getOperand(1)) &&
2981 // XAndesPerf supports branch on test bit.
2982 !Subtarget.hasVendorXAndesPerf()) {
2983 uint64_t Mask = LHS.getConstantOperandVal(1);
2984 if ((isPowerOf2_64(Mask) || isMask_64(Mask)) && !isInt<12>(Mask)) {
2985 unsigned ShAmt = 0;
2986 if (isPowerOf2_64(Mask)) {
2987 CC = CC == ISD::SETEQ ? ISD::SETGE : ISD::SETLT;
2988 ShAmt = LHS.getValueSizeInBits() - 1 - Log2_64(Mask);
2989 } else {
2990 ShAmt = LHS.getValueSizeInBits() - llvm::bit_width(Mask);
2991 }
2992
2993 LHS = LHS.getOperand(0);
2994 if (ShAmt != 0)
2995 LHS = DAG.getNode(ISD::SHL, DL, LHS.getValueType(), LHS,
2996 DAG.getConstant(ShAmt, DL, LHS.getValueType()));
2997 return;
2998 }
2999 }
3000
3001 if (auto *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
3002 int64_t C = RHSC->getSExtValue();
3003 switch (CC) {
3004 default: break;
3005 case ISD::SETGT:
3006 // Convert X > -1 to X >= 0.
3007 if (C == -1) {
3008 RHS = DAG.getConstant(0, DL, RHS.getValueType());
3009 CC = ISD::SETGE;
3010 return;
3011 }
3012 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
3013 C != INT64_MAX && isInt<5>(C + 1)) {
3014 // We have a conditional move instruction for SETGE but not SETGT.
3015 // Convert X > C to X >= C + 1, if (C + 1) is a 5-bit signed immediate.
3016 RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType());
3017 CC = ISD::SETGE;
3018 return;
3019 }
3020 if (Subtarget.hasVendorXqcibi() && C != INT64_MAX && isInt<16>(C + 1)) {
3021 // We have a branch immediate instruction for SETGE but not SETGT.
3022 // Convert X > C to X >= C + 1, if (C + 1) is a 16-bit signed immediate.
3023 RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType());
3024 CC = ISD::SETGE;
3025 return;
3026 }
3027 break;
3028 case ISD::SETLT:
3029 // Convert X < 1 to 0 >= X.
3030 if (C == 1) {
3031 RHS = LHS;
3032 LHS = DAG.getConstant(0, DL, RHS.getValueType());
3033 CC = ISD::SETGE;
3034 return;
3035 }
3036 break;
3037 case ISD::SETUGT:
3038 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
3039 C != INT64_MAX && isUInt<5>(C + 1)) {
3040 // We have a conditional move instruction for SETUGE but not SETUGT.
3041 // Convert X > C to X >= C + 1, if (C + 1) is a 5-bit signed immediate.
3042 RHS = DAG.getConstant(C + 1, DL, RHS.getValueType());
3043 CC = ISD::SETUGE;
3044 return;
3045 }
3046 if (Subtarget.hasVendorXqcibi() && C != INT64_MAX && isUInt<16>(C + 1)) {
3047 // We have a branch immediate instruction for SETUGE but not SETUGT.
3048 // Convert X > C to X >= C + 1, if (C + 1) is a 16-bit unsigned
3049 // immediate.
3050 RHS = DAG.getConstant(C + 1, DL, RHS.getValueType());
3051 CC = ISD::SETUGE;
3052 return;
3053 }
3054 break;
3055 }
3056 }
3057
3058 switch (CC) {
3059 default:
3060 break;
3061 case ISD::SETGT:
3062 case ISD::SETLE:
3063 case ISD::SETUGT:
3064 case ISD::SETULE:
3066 std::swap(LHS, RHS);
3067 break;
3068 }
3069}
3070
3072 if (VT.isRISCVVectorTuple()) {
3073 if (VT.SimpleTy >= MVT::riscv_nxv1i8x2 &&
3074 VT.SimpleTy <= MVT::riscv_nxv1i8x8)
3075 return RISCVVType::LMUL_F8;
3076 if (VT.SimpleTy >= MVT::riscv_nxv2i8x2 &&
3077 VT.SimpleTy <= MVT::riscv_nxv2i8x8)
3078 return RISCVVType::LMUL_F4;
3079 if (VT.SimpleTy >= MVT::riscv_nxv4i8x2 &&
3080 VT.SimpleTy <= MVT::riscv_nxv4i8x8)
3081 return RISCVVType::LMUL_F2;
3082 if (VT.SimpleTy >= MVT::riscv_nxv8i8x2 &&
3083 VT.SimpleTy <= MVT::riscv_nxv8i8x8)
3084 return RISCVVType::LMUL_1;
3085 if (VT.SimpleTy >= MVT::riscv_nxv16i8x2 &&
3086 VT.SimpleTy <= MVT::riscv_nxv16i8x4)
3087 return RISCVVType::LMUL_2;
3088 if (VT.SimpleTy == MVT::riscv_nxv32i8x2)
3089 return RISCVVType::LMUL_4;
3090 llvm_unreachable("Invalid vector tuple type LMUL.");
3091 }
3092
3093 assert(VT.isScalableVector() && "Expecting a scalable vector type");
3094 unsigned KnownSize = VT.getSizeInBits().getKnownMinValue();
3095 if (VT.getVectorElementType() == MVT::i1)
3096 KnownSize *= 8;
3097
3098 switch (KnownSize) {
3099 default:
3100 llvm_unreachable("Invalid LMUL.");
3101 case 8:
3102 return RISCVVType::LMUL_F8;
3103 case 16:
3104 return RISCVVType::LMUL_F4;
3105 case 32:
3106 return RISCVVType::LMUL_F2;
3107 case 64:
3108 return RISCVVType::LMUL_1;
3109 case 128:
3110 return RISCVVType::LMUL_2;
3111 case 256:
3112 return RISCVVType::LMUL_4;
3113 case 512:
3114 return RISCVVType::LMUL_8;
3115 }
3116}
3117
3119 switch (LMul) {
3120 default:
3121 llvm_unreachable("Invalid LMUL.");
3125 case RISCVVType::LMUL_1:
3126 return RISCV::VRRegClassID;
3127 case RISCVVType::LMUL_2:
3128 return RISCV::VRM2RegClassID;
3129 case RISCVVType::LMUL_4:
3130 return RISCV::VRM4RegClassID;
3131 case RISCVVType::LMUL_8:
3132 return RISCV::VRM8RegClassID;
3133 }
3134}
3135
3136unsigned RISCVTargetLowering::getSubregIndexByMVT(MVT VT, unsigned Index) {
3137 RISCVVType::VLMUL LMUL = getLMUL(VT);
3138 if (LMUL == RISCVVType::LMUL_F8 || LMUL == RISCVVType::LMUL_F4 ||
3139 LMUL == RISCVVType::LMUL_F2 || LMUL == RISCVVType::LMUL_1) {
3140 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
3141 "Unexpected subreg numbering");
3142 return RISCV::sub_vrm1_0 + Index;
3143 }
3144 if (LMUL == RISCVVType::LMUL_2) {
3145 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
3146 "Unexpected subreg numbering");
3147 return RISCV::sub_vrm2_0 + Index;
3148 }
3149 if (LMUL == RISCVVType::LMUL_4) {
3150 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
3151 "Unexpected subreg numbering");
3152 return RISCV::sub_vrm4_0 + Index;
3153 }
3154 llvm_unreachable("Invalid vector type.");
3155}
3156
3158 if (VT.isRISCVVectorTuple()) {
3159 unsigned NF = VT.getRISCVVectorTupleNumFields();
3160 unsigned RegsPerField =
3161 std::max(1U, (unsigned)VT.getSizeInBits().getKnownMinValue() /
3162 (NF * RISCV::RVVBitsPerBlock));
3163 switch (RegsPerField) {
3164 case 1:
3165 if (NF == 2)
3166 return RISCV::VRN2M1RegClassID;
3167 if (NF == 3)
3168 return RISCV::VRN3M1RegClassID;
3169 if (NF == 4)
3170 return RISCV::VRN4M1RegClassID;
3171 if (NF == 5)
3172 return RISCV::VRN5M1RegClassID;
3173 if (NF == 6)
3174 return RISCV::VRN6M1RegClassID;
3175 if (NF == 7)
3176 return RISCV::VRN7M1RegClassID;
3177 if (NF == 8)
3178 return RISCV::VRN8M1RegClassID;
3179 break;
3180 case 2:
3181 if (NF == 2)
3182 return RISCV::VRN2M2RegClassID;
3183 if (NF == 3)
3184 return RISCV::VRN3M2RegClassID;
3185 if (NF == 4)
3186 return RISCV::VRN4M2RegClassID;
3187 break;
3188 case 4:
3189 assert(NF == 2);
3190 return RISCV::VRN2M4RegClassID;
3191 default:
3192 break;
3193 }
3194 llvm_unreachable("Invalid vector tuple type RegClass.");
3195 }
3196
3197 if (VT.getVectorElementType() == MVT::i1)
3198 return RISCV::VRRegClassID;
3199 return getRegClassIDForLMUL(getLMUL(VT));
3200}
3201
3202// Attempt to decompose a subvector insert/extract between VecVT and
3203// SubVecVT via subregister indices. Returns the subregister index that
3204// can perform the subvector insert/extract with the given element index, as
3205// well as the index corresponding to any leftover subvectors that must be
3206// further inserted/extracted within the register class for SubVecVT.
3207std::pair<unsigned, unsigned>
3209 MVT VecVT, MVT SubVecVT, unsigned InsertExtractIdx,
3210 const RISCVRegisterInfo *TRI) {
3211 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
3212 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
3213 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
3214 "Register classes not ordered");
3215 unsigned VecRegClassID = getRegClassIDForVecVT(VecVT);
3216 unsigned SubRegClassID = getRegClassIDForVecVT(SubVecVT);
3217
3218 // If VecVT is a vector tuple type, either it's the tuple type with same
3219 // RegClass with SubVecVT or SubVecVT is a actually a subvector of the VecVT.
3220 if (VecVT.isRISCVVectorTuple()) {
3221 if (VecRegClassID == SubRegClassID)
3222 return {RISCV::NoSubRegister, 0};
3223
3224 assert(SubVecVT.isScalableVector() &&
3225 "Only allow scalable vector subvector.");
3226 assert(getLMUL(VecVT) == getLMUL(SubVecVT) &&
3227 "Invalid vector tuple insert/extract for vector and subvector with "
3228 "different LMUL.");
3229 return {getSubregIndexByMVT(VecVT, InsertExtractIdx), 0};
3230 }
3231
3232 // Try to compose a subregister index that takes us from the incoming
3233 // LMUL>1 register class down to the outgoing one. At each step we half
3234 // the LMUL:
3235 // nxv16i32@12 -> nxv2i32: sub_vrm4_1_then_sub_vrm2_1_then_sub_vrm1_0
3236 // Note that this is not guaranteed to find a subregister index, such as
3237 // when we are extracting from one VR type to another.
3238 unsigned SubRegIdx = RISCV::NoSubRegister;
3239 for (const unsigned RCID :
3240 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
3241 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
3242 VecVT = VecVT.getHalfNumVectorElementsVT();
3243 bool IsHi =
3244 InsertExtractIdx >= VecVT.getVectorElementCount().getKnownMinValue();
3245 SubRegIdx = TRI->composeSubRegIndices(SubRegIdx,
3246 getSubregIndexByMVT(VecVT, IsHi));
3247 if (IsHi)
3248 InsertExtractIdx -= VecVT.getVectorElementCount().getKnownMinValue();
3249 }
3250 return {SubRegIdx, InsertExtractIdx};
3251}
3252
3253// Permit combining of mask vectors as BUILD_VECTOR never expands to scalar
3254// stores for those types.
3255bool RISCVTargetLowering::mergeStoresAfterLegalization(EVT VT) const {
3256 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
3257 (VT == MVT::i32 || VT == MVT::v2i16 || VT == MVT::v4i8))
3258 return false;
3259
3260 return !Subtarget.useRVVForFixedLengthVectors() ||
3261 VT.isFixedLengthVectorOf(MVT::i1);
3262}
3263
3265 if (!ScalarTy.isSimple())
3266 return false;
3267 switch (ScalarTy.getSimpleVT().SimpleTy) {
3268 case MVT::iPTR:
3269 return Subtarget.is64Bit() ? Subtarget.hasVInstructionsI64() : true;
3270 case MVT::i8:
3271 case MVT::i16:
3272 case MVT::i32:
3273 return Subtarget.hasVInstructions();
3274 case MVT::i64:
3275 return Subtarget.hasVInstructionsI64();
3276 case MVT::f16:
3277 return Subtarget.hasVInstructionsF16Minimal();
3278 case MVT::bf16:
3279 return Subtarget.hasVInstructionsBF16Minimal();
3280 case MVT::f32:
3281 return Subtarget.hasVInstructionsF32();
3282 case MVT::f64:
3283 return Subtarget.hasVInstructionsF64();
3284 default:
3285 return false;
3286 }
3287}
3288
3289
3291 return NumRepeatedDivisors;
3292}
3293
3295 assert((Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
3296 Op.getOpcode() == ISD::INTRINSIC_W_CHAIN) &&
3297 "Unexpected opcode");
3298 bool HasChain = Op.getOpcode() == ISD::INTRINSIC_W_CHAIN;
3299 unsigned IntNo = Op.getConstantOperandVal(HasChain ? 1 : 0);
3301 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
3302 if (!II)
3303 return SDValue();
3304 return Op.getOperand(II->VLOperand + 1 + HasChain);
3305}
3306
3308 const RISCVSubtarget &Subtarget) {
3309 assert(VT.isFixedLengthVector() && "Expected a fixed length vector type!");
3310 if (!Subtarget.useRVVForFixedLengthVectors())
3311 return false;
3312
3313 // We only support a set of vector types with a consistent maximum fixed size
3314 // across all supported vector element types to avoid legalization issues.
3315 // Therefore -- since the largest is v1024i8/v512i16/etc -- the largest
3316 // fixed-length vector type we support is 1024 bytes.
3317 if (VT.getVectorNumElements() > 1024 || VT.getFixedSizeInBits() > 1024 * 8)
3318 return false;
3319
3320 unsigned MinVLen = Subtarget.getRealMinVLen();
3321
3322 MVT EltVT = VT.getVectorElementType();
3323
3324 // Don't use RVV for vectors we cannot scalarize if required.
3325 switch (EltVT.SimpleTy) {
3326 // i1 is supported but has different rules.
3327 default:
3328 return false;
3329 case MVT::i1:
3330 // Masks can only use a single register.
3331 if (VT.getVectorNumElements() > MinVLen)
3332 return false;
3333 MinVLen /= 8;
3334 break;
3335 case MVT::i8:
3336 case MVT::i16:
3337 case MVT::i32:
3338 break;
3339 case MVT::i64:
3340 if (!Subtarget.hasVInstructionsI64())
3341 return false;
3342 break;
3343 case MVT::f16:
3344 if (!Subtarget.hasVInstructionsF16Minimal())
3345 return false;
3346 break;
3347 case MVT::bf16:
3348 if (!Subtarget.hasVInstructionsBF16Minimal())
3349 return false;
3350 break;
3351 case MVT::f32:
3352 if (!Subtarget.hasVInstructionsF32())
3353 return false;
3354 break;
3355 case MVT::f64:
3356 if (!Subtarget.hasVInstructionsF64())
3357 return false;
3358 break;
3359 }
3360
3361 // Reject elements larger than ELEN.
3362 if (EltVT.getSizeInBits() > Subtarget.getELen())
3363 return false;
3364
3365 unsigned LMul = divideCeil(VT.getSizeInBits(), MinVLen);
3366 // Don't use RVV for types that don't fit.
3367 if (LMul > Subtarget.getMaxLMULForFixedLengthVectors())
3368 return false;
3369
3370 // TODO: Perhaps an artificial restriction, but worth having whilst getting
3371 // the base fixed length RVV support in place.
3372 if (!VT.isPow2VectorType())
3373 return false;
3374
3375 return true;
3376}
3377
3378bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(MVT VT) const {
3379 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
3380}
3381
3382// Return the largest legal scalable vector type that matches VT's element type.
3384 const RISCVSubtarget &Subtarget) {
3385 // This may be called before legal types are setup.
3386 assert(((VT.isFixedLengthVector() &&
3387 Subtarget.getTargetLowering()->isTypeLegal(VT)) ||
3388 useRVVForFixedLengthVectorVT(VT, Subtarget)) &&
3389 "Expected legal fixed length vector!");
3390
3391 unsigned MinVLen = Subtarget.getRealMinVLen();
3392 unsigned MaxELen = Subtarget.getELen();
3393
3394 MVT EltVT = VT.getVectorElementType();
3395 switch (EltVT.SimpleTy) {
3396 default:
3397 llvm_unreachable("unexpected element type for RVV container");
3398 case MVT::i1:
3399 case MVT::i8:
3400 case MVT::i16:
3401 case MVT::i32:
3402 case MVT::i64:
3403 case MVT::bf16:
3404 case MVT::f16:
3405 case MVT::f32:
3406 case MVT::f64: {
3407 // We prefer to use LMUL=1 for VLEN sized types. Use fractional lmuls for
3408 // narrower types. The smallest fractional LMUL we support is 8/ELEN. Within
3409 // each fractional LMUL we support SEW between 8 and LMUL*ELEN.
3410 unsigned NumElts =
3412 NumElts = std::max(NumElts, RISCV::RVVBitsPerBlock / MaxELen);
3413 assert(isPowerOf2_32(NumElts) && "Expected power of 2 NumElts");
3414 return MVT::getScalableVectorVT(EltVT, NumElts);
3415 }
3416 }
3417}
3418
3420 return ::getContainerForFixedLengthVector(VT, getSubtarget());
3421}
3422
3423// Grow V to consume an entire RVV register.
3425 const RISCVSubtarget &Subtarget) {
3426 assert(VT.isScalableVector() &&
3427 "Expected to convert into a scalable vector!");
3428 assert(V.getValueType().isFixedLengthVector() &&
3429 "Expected a fixed length vector operand!");
3430 SDLoc DL(V);
3431 return DAG.getInsertSubvector(DL, DAG.getUNDEF(VT), V, 0);
3432}
3433
3434// Shrink V so it's just big enough to maintain a VT's worth of data.
3436 const RISCVSubtarget &Subtarget) {
3438 "Expected to convert into a fixed length vector!");
3439 assert(V.getValueType().isScalableVector() &&
3440 "Expected a scalable vector operand!");
3441 SDLoc DL(V);
3442 return DAG.getExtractSubvector(DL, VT, V, 0);
3443}
3444
3445/// Return the type of the mask type suitable for masking the provided
3446/// vector type. This is simply an i1 element type vector of the same
3447/// (possibly scalable) length.
3448static MVT getMaskTypeFor(MVT VecVT) {
3449 assert(VecVT.isVector());
3451 return MVT::getVectorVT(MVT::i1, EC);
3452}
3453
3454/// Creates an all ones mask suitable for masking a vector of type VecTy with
3455/// vector length VL. .
3456static SDValue getAllOnesMask(MVT VecVT, SDValue VL, const SDLoc &DL,
3457 SelectionDAG &DAG) {
3458 MVT MaskVT = getMaskTypeFor(VecVT);
3459 return DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VL);
3460}
3461
3462static std::pair<SDValue, SDValue>
3464 const RISCVSubtarget &Subtarget) {
3465 assert(VecVT.isScalableVector() && "Expecting a scalable vector");
3466 SDValue VL = DAG.getRegister(RISCV::X0, Subtarget.getXLenVT());
3467 SDValue Mask = getAllOnesMask(VecVT, VL, DL, DAG);
3468 return {Mask, VL};
3469}
3470
3471static std::pair<SDValue, SDValue>
3472getDefaultVLOps(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
3473 SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
3474 assert(ContainerVT.isScalableVector() && "Expecting scalable container type");
3475 SDValue VL = DAG.getConstant(NumElts, DL, Subtarget.getXLenVT());
3476 SDValue Mask = getAllOnesMask(ContainerVT, VL, DL, DAG);
3477 return {Mask, VL};
3478}
3479
3480// Gets the two common "VL" operands: an all-ones mask and the vector length.
3481// VecVT is a vector type, either fixed-length or scalable, and ContainerVT is
3482// the vector type that the fixed-length vector is contained in. Otherwise if
3483// VecVT is scalable, then ContainerVT should be the same as VecVT.
3484static std::pair<SDValue, SDValue>
3485getDefaultVLOps(MVT VecVT, MVT ContainerVT, const SDLoc &DL, SelectionDAG &DAG,
3486 const RISCVSubtarget &Subtarget) {
3487 if (VecVT.isFixedLengthVector())
3488 return getDefaultVLOps(VecVT.getVectorNumElements(), ContainerVT, DL, DAG,
3489 Subtarget);
3490 assert(ContainerVT.isScalableVector() && "Expecting scalable container type");
3491 return getDefaultScalableVLOps(ContainerVT, DL, DAG, Subtarget);
3492}
3493
3495 SelectionDAG &DAG) const {
3496 assert(VecVT.isScalableVector() && "Expected scalable vector");
3497 return DAG.getElementCount(DL, Subtarget.getXLenVT(),
3498 VecVT.getVectorElementCount());
3499}
3500
3501std::pair<unsigned, unsigned>
3503 const RISCVSubtarget &Subtarget) {
3504 assert(VecVT.isScalableVector() && "Expected scalable vector");
3505
3506 unsigned EltSize = VecVT.getScalarSizeInBits();
3507 unsigned MinSize = VecVT.getSizeInBits().getKnownMinValue();
3508
3509 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
3510 unsigned MaxVLMAX =
3511 RISCVTargetLowering::computeVLMAX(VectorBitsMax, EltSize, MinSize);
3512
3513 unsigned VectorBitsMin = Subtarget.getRealMinVLen();
3514 unsigned MinVLMAX =
3515 RISCVTargetLowering::computeVLMAX(VectorBitsMin, EltSize, MinSize);
3516
3517 return std::make_pair(MinVLMAX, MaxVLMAX);
3518}
3519
3520// The state of RVV BUILD_VECTOR and VECTOR_SHUFFLE lowering is that very few
3521// of either is (currently) supported. This can get us into an infinite loop
3522// where we try to lower a BUILD_VECTOR as a VECTOR_SHUFFLE as a BUILD_VECTOR
3523// as a ..., etc.
3524// Until either (or both) of these can reliably lower any node, reporting that
3525// we don't want to expand BUILD_VECTORs via VECTOR_SHUFFLEs at least breaks
3526// the infinite loop. Note that this lowers BUILD_VECTOR through the stack,
3527// which is not desirable.
3529 EVT VT, unsigned DefinedValues) const {
3530 return false;
3531}
3532
3534 // TODO: Here assume reciprocal throughput is 1 for LMUL_1, it is
3535 // implementation-defined.
3536 if (!VT.isVector())
3538 unsigned DLenFactor = Subtarget.getDLenFactor();
3539 unsigned Cost;
3540 if (VT.isScalableVector()) {
3541 unsigned LMul;
3542 bool Fractional;
3543 std::tie(LMul, Fractional) =
3545 if (Fractional)
3546 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
3547 else
3548 Cost = (LMul * DLenFactor);
3549 } else {
3550 Cost = divideCeil(VT.getSizeInBits(), Subtarget.getRealMinVLen() / DLenFactor);
3551 }
3552 return Cost;
3553}
3554
3555
3556/// Return the cost of a vrgather.vv instruction for the type VT. vrgather.vv
3557/// may be quadratic in the number of vreg implied by LMUL, and is assumed to
3558/// be by default. VRGatherCostModel reflects available options. Note that
3559/// operand (index and possibly mask) are handled separately.
3561 auto LMULCost = getLMULCost(VT);
3562 bool Log2CostModel =
3563 Subtarget.getVRGatherCostModel() == llvm::RISCVSubtarget::NLog2N;
3564 if (Log2CostModel && LMULCost.isValid()) {
3565 unsigned Log = Log2_64(LMULCost.getValue());
3566 if (Log > 0)
3567 return LMULCost * Log;
3568 }
3569 return LMULCost * LMULCost;
3570}
3571
3572/// Return the cost of a vrgather.vi (or vx) instruction for the type VT.
3573/// vrgather.vi/vx may be linear in the number of vregs implied by LMUL,
3574/// or may track the vrgather.vv cost. It is implementation-dependent.
3578
3579/// Return the cost of a vslidedown.vx or vslideup.vx instruction
3580/// for the type VT. (This does not cover the vslide1up or vslide1down
3581/// variants.) Slides may be linear in the number of vregs implied by LMUL,
3582/// or may track the vrgather.vv cost. It is implementation-dependent.
3586
3587/// Return the cost of a vslidedown.vi or vslideup.vi instruction
3588/// for the type VT. (This does not cover the vslide1up or vslide1down
3589/// variants.) Slides may be linear in the number of vregs implied by LMUL,
3590/// or may track the vrgather.vv cost. It is implementation-dependent.
3594
3596 const RISCVSubtarget &Subtarget) {
3597 // f16 conversions are promoted to f32 when Zfh/Zhinx are not supported.
3598 // bf16 conversions are always promoted to f32.
3599 if ((Op.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx()) ||
3600 Op.getValueType() == MVT::bf16) {
3601 bool IsStrict = Op->isStrictFPOpcode();
3602
3603 SDLoc DL(Op);
3604 if (IsStrict) {
3605 SDValue Val = DAG.getNode(Op.getOpcode(), DL, {MVT::f32, MVT::Other},
3606 {Op.getOperand(0), Op.getOperand(1)});
3607 return DAG.getNode(ISD::STRICT_FP_ROUND, DL,
3608 {Op.getValueType(), MVT::Other},
3609 {Val.getValue(1), Val.getValue(0),
3610 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true)});
3611 }
3612 return DAG.getNode(
3613 ISD::FP_ROUND, DL, Op.getValueType(),
3614 DAG.getNode(Op.getOpcode(), DL, MVT::f32, Op.getOperand(0)),
3615 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true));
3616 }
3617
3618 // Other operations are legal.
3619 return Op;
3620}
3621
3623 const RISCVSubtarget &Subtarget) {
3624 // RISC-V FP-to-int conversions saturate to the destination register size, but
3625 // don't produce 0 for nan. We can use a conversion instruction and fix the
3626 // nan case with a compare and a select.
3627 SDValue Src = Op.getOperand(0);
3628
3629 MVT DstVT = Op.getSimpleValueType();
3630 EVT SatVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
3631
3632 bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
3633
3634 if (!DstVT.isVector()) {
3635 // For bf16 or for f16 in absence of Zfh, promote to f32, then saturate
3636 // the result.
3637 if ((Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx()) ||
3638 Src.getValueType() == MVT::bf16) {
3639 Src = DAG.getNode(ISD::FP_EXTEND, SDLoc(Op), MVT::f32, Src);
3640 }
3641
3642 unsigned Opc;
3643 if (SatVT == DstVT)
3644 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
3645 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
3646 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
3647 else
3648 return SDValue();
3649 // FIXME: Support other SatVTs by clamping before or after the conversion.
3650
3651 SDLoc DL(Op);
3652 SDValue FpToInt = DAG.getNode(
3653 Opc, DL, DstVT, Src,
3655
3656 if (Opc == RISCVISD::FCVT_WU_RV64)
3657 FpToInt = DAG.getZeroExtendInReg(FpToInt, DL, MVT::i32);
3658
3659 SDValue ZeroInt = DAG.getConstant(0, DL, DstVT);
3660 return DAG.getSelectCC(DL, Src, Src, ZeroInt, FpToInt,
3662 }
3663
3664 // Vectors.
3665
3666 MVT DstEltVT = DstVT.getVectorElementType();
3667 MVT SrcVT = Src.getSimpleValueType();
3668 MVT SrcEltVT = SrcVT.getVectorElementType();
3669 unsigned SrcEltSize = SrcEltVT.getSizeInBits();
3670 unsigned DstEltSize = DstEltVT.getSizeInBits();
3671
3672 // Only handle saturating to the destination type.
3673 if (SatVT != DstEltVT)
3674 return SDValue();
3675
3676 MVT DstContainerVT = DstVT;
3677 MVT SrcContainerVT = SrcVT;
3678 if (DstVT.isFixedLengthVector()) {
3679 DstContainerVT = getContainerForFixedLengthVector(DstVT, Subtarget);
3680 SrcContainerVT = getContainerForFixedLengthVector(SrcVT, Subtarget);
3681 assert(DstContainerVT.getVectorElementCount() ==
3682 SrcContainerVT.getVectorElementCount() &&
3683 "Expected same element count");
3684 Src = convertToScalableVector(SrcContainerVT, Src, DAG, Subtarget);
3685 }
3686
3687 SDLoc DL(Op);
3688
3689 auto [Mask, VL] = getDefaultVLOps(DstVT, DstContainerVT, DL, DAG, Subtarget);
3690
3691 SDValue IsNan = DAG.getNode(RISCVISD::SETCC_VL, DL, Mask.getValueType(),
3692 {Src, Src, DAG.getCondCode(ISD::SETNE),
3693 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
3694
3695 // Need to widen by more than 1 step, promote the FP type, then do a widening
3696 // convert.
3697 if (DstEltSize > (2 * SrcEltSize)) {
3698 assert(SrcContainerVT.getVectorElementType() == MVT::f16 && "Unexpected VT!");
3699 MVT InterVT = SrcContainerVT.changeVectorElementType(MVT::f32);
3700 Src = DAG.getNode(RISCVISD::FP_EXTEND_VL, DL, InterVT, Src, Mask, VL);
3701 }
3702
3703 MVT CvtContainerVT = DstContainerVT;
3704 MVT CvtEltVT = DstEltVT;
3705 if (SrcEltSize > (2 * DstEltSize)) {
3706 CvtEltVT = MVT::getIntegerVT(SrcEltVT.getSizeInBits() / 2);
3707 CvtContainerVT = CvtContainerVT.changeVectorElementType(CvtEltVT);
3708 }
3709
3710 unsigned RVVOpc =
3711 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
3712 SDValue Res = DAG.getNode(RVVOpc, DL, CvtContainerVT, Src, Mask, VL);
3713
3714 while (CvtContainerVT != DstContainerVT) {
3715 CvtEltVT = MVT::getIntegerVT(CvtEltVT.getSizeInBits() / 2);
3716 CvtContainerVT = CvtContainerVT.changeVectorElementType(CvtEltVT);
3717 // Rounding mode here is arbitrary since we aren't shifting out any bits.
3718 unsigned ClipOpc = IsSigned ? RISCVISD::TRUNCATE_VECTOR_VL_SSAT
3719 : RISCVISD::TRUNCATE_VECTOR_VL_USAT;
3720 Res = DAG.getNode(ClipOpc, DL, CvtContainerVT, Res, Mask, VL);
3721 }
3722
3723 SDValue SplatZero = DAG.getNode(
3724 RISCVISD::VMV_V_X_VL, DL, DstContainerVT, DAG.getUNDEF(DstContainerVT),
3725 DAG.getConstant(0, DL, Subtarget.getXLenVT()), VL);
3726 Res = DAG.getNode(RISCVISD::VMERGE_VL, DL, DstContainerVT, IsNan, SplatZero,
3727 Res, DAG.getUNDEF(DstContainerVT), VL);
3728
3729 if (DstVT.isFixedLengthVector())
3730 Res = convertFromScalableVector(DstVT, Res, DAG, Subtarget);
3731
3732 return Res;
3733}
3734
3736 const RISCVSubtarget &Subtarget) {
3737 bool IsStrict = Op->isStrictFPOpcode();
3738 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
3739
3740 // f16 conversions are promoted to f32 when Zfh/Zhinx is not enabled.
3741 // bf16 conversions are always promoted to f32.
3742 if ((SrcVal.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx()) ||
3743 SrcVal.getValueType() == MVT::bf16) {
3744 SDLoc DL(Op);
3745 if (IsStrict) {
3746 SDValue Ext =
3747 DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
3748 {Op.getOperand(0), SrcVal});
3749 return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
3750 {Ext.getValue(1), Ext.getValue(0)});
3751 }
3752 return DAG.getNode(Op.getOpcode(), DL, Op.getValueType(),
3753 DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, SrcVal));
3754 }
3755
3756 // Other operations are legal.
3757 return Op;
3758}
3759
3761 switch (Opc) {
3762 case ISD::FROUNDEVEN:
3764 return RISCVFPRndMode::RNE;
3765 case ISD::FTRUNC:
3766 case ISD::STRICT_FTRUNC:
3767 return RISCVFPRndMode::RTZ;
3768 case ISD::FFLOOR:
3769 case ISD::STRICT_FFLOOR:
3770 return RISCVFPRndMode::RDN;
3771 case ISD::FCEIL:
3772 case ISD::STRICT_FCEIL:
3773 return RISCVFPRndMode::RUP;
3774 case ISD::FROUND:
3775 case ISD::LROUND:
3776 case ISD::LLROUND:
3777 case ISD::STRICT_FROUND:
3778 case ISD::STRICT_LROUND:
3780 return RISCVFPRndMode::RMM;
3781 case ISD::FRINT:
3782 case ISD::LRINT:
3783 case ISD::LLRINT:
3784 case ISD::STRICT_FRINT:
3785 case ISD::STRICT_LRINT:
3786 case ISD::STRICT_LLRINT:
3787 return RISCVFPRndMode::DYN;
3788 }
3789
3791}
3792
3793// Expand vector FTRUNC, FCEIL, FFLOOR and FROUND by converting to
3794// the integer domain and back. Taking care to avoid converting values that are
3795// nan or already correct.
3796static SDValue
3798 const RISCVSubtarget &Subtarget) {
3799 MVT VT = Op.getSimpleValueType();
3800 assert(VT.isVector() && "Unexpected type");
3801
3802 SDLoc DL(Op);
3803
3804 SDValue Src = Op.getOperand(0);
3805
3806 // Freeze the source since we are increasing the number of uses.
3807 Src = DAG.getFreeze(Src);
3808
3809 MVT ContainerVT = VT;
3810 if (VT.isFixedLengthVector()) {
3811 ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
3812 Src = convertToScalableVector(ContainerVT, Src, DAG, Subtarget);
3813 }
3814
3815 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
3816
3817 // We do the conversion on the absolute value and fix the sign at the end.
3818 SDValue Abs = DAG.getNode(RISCVISD::FABS_VL, DL, ContainerVT, Src, Mask, VL);
3819
3820 // Determine the largest integer that can be represented exactly. This and
3821 // values larger than it don't have any fractional bits so don't need to
3822 // be converted.
3823 const fltSemantics &FltSem = ContainerVT.getFltSemantics();
3824 unsigned Precision = APFloat::semanticsPrecision(FltSem);
3825 APFloat MaxVal = APFloat(FltSem);
3826 MaxVal.convertFromAPInt(APInt::getOneBitSet(Precision, Precision - 1),
3827 /*IsSigned*/ false, APFloat::rmNearestTiesToEven);
3828 SDValue MaxValNode =
3829 DAG.getConstantFP(MaxVal, DL, ContainerVT.getVectorElementType());
3830 SDValue MaxValSplat = DAG.getNode(RISCVISD::VFMV_V_F_VL, DL, ContainerVT,
3831 DAG.getUNDEF(ContainerVT), MaxValNode, VL);
3832
3833 // If abs(Src) was larger than MaxVal or nan, keep it.
3834 MVT SetccVT = MVT::getVectorVT(MVT::i1, ContainerVT.getVectorElementCount());
3835 Mask =
3836 DAG.getNode(RISCVISD::SETCC_VL, DL, SetccVT,
3837 {Abs, MaxValSplat, DAG.getCondCode(ISD::SETOLT),
3838 Mask, Mask, VL});
3839
3840 // Truncate to integer and convert back to FP.
3841 MVT IntVT = ContainerVT.changeVectorElementTypeToInteger();
3842 MVT XLenVT = Subtarget.getXLenVT();
3843 SDValue Truncated;
3844
3845 switch (Op.getOpcode()) {
3846 default:
3847 llvm_unreachable("Unexpected opcode");
3848 case ISD::FRINT:
3849 case ISD::FCEIL:
3850 case ISD::FFLOOR:
3851 case ISD::FROUND:
3852 case ISD::FROUNDEVEN: {
3855 Truncated = DAG.getNode(RISCVISD::VFCVT_RM_X_F_VL, DL, IntVT, Src, Mask,
3856 DAG.getTargetConstant(FRM, DL, XLenVT), VL);
3857 break;
3858 }
3859 case ISD::FTRUNC:
3860 Truncated = DAG.getNode(RISCVISD::VFCVT_RTZ_X_F_VL, DL, IntVT, Src,
3861 Mask, VL);
3862 break;
3863 case ISD::FNEARBYINT:
3864 Truncated = DAG.getNode(RISCVISD::VFROUND_NOEXCEPT_VL, DL, ContainerVT, Src,
3865 Mask, VL);
3866 break;
3867 }
3868
3869 // VFROUND_NOEXCEPT_VL includes SINT_TO_FP_VL.
3870 if (Truncated.getOpcode() != RISCVISD::VFROUND_NOEXCEPT_VL)
3871 Truncated = DAG.getNode(RISCVISD::SINT_TO_FP_VL, DL, ContainerVT, Truncated,
3872 Mask, VL);
3873
3874 // Restore the original sign so that -0.0 is preserved.
3875 Truncated = DAG.getNode(RISCVISD::FCOPYSIGN_VL, DL, ContainerVT, Truncated,
3876 Src, Src, Mask, VL);
3877
3878 if (!VT.isFixedLengthVector())
3879 return Truncated;
3880
3881 return convertFromScalableVector(VT, Truncated, DAG, Subtarget);
3882}
3883
3884// Expand vector STRICT_FTRUNC, STRICT_FCEIL, STRICT_FFLOOR, STRICT_FROUND
3885// STRICT_FROUNDEVEN and STRICT_FNEARBYINT by converting sNan of the source to
3886// qNan and converting the new source to integer and back to FP.
3887static SDValue
3889 const RISCVSubtarget &Subtarget) {
3890 SDLoc DL(Op);
3891 MVT VT = Op.getSimpleValueType();
3892 SDValue Chain = Op.getOperand(0);
3893 SDValue Src = Op.getOperand(1);
3894
3895 MVT ContainerVT = VT;
3896 if (VT.isFixedLengthVector()) {
3897 ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
3898 Src = convertToScalableVector(ContainerVT, Src, DAG, Subtarget);
3899 }
3900
3901 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
3902
3903 // Freeze the source since we are increasing the number of uses.
3904 Src = DAG.getFreeze(Src);
3905
3906 // Convert sNan to qNan by executing x + x for all unordered element x in Src.
3907 MVT MaskVT = Mask.getSimpleValueType();
3908 SDValue Unorder = DAG.getNode(RISCVISD::STRICT_FSETCC_VL, DL,
3909 DAG.getVTList(MaskVT, MVT::Other),
3910 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3911 DAG.getUNDEF(MaskVT), Mask, VL});
3912 Chain = Unorder.getValue(1);
3913 Src = DAG.getNode(RISCVISD::STRICT_FADD_VL, DL,
3914 DAG.getVTList(ContainerVT, MVT::Other),
3915 {Chain, Src, Src, Src, Unorder, VL});
3916 Chain = Src.getValue(1);
3917
3918 // We do the conversion on the absolute value and fix the sign at the end.
3919 SDValue Abs = DAG.getNode(RISCVISD::FABS_VL, DL, ContainerVT, Src, Mask, VL);
3920
3921 // Determine the largest integer that can be represented exactly. This and
3922 // values larger than it don't have any fractional bits so don't need to
3923 // be converted.
3924 const fltSemantics &FltSem = ContainerVT.getFltSemantics();
3925 unsigned Precision = APFloat::semanticsPrecision(FltSem);
3926 APFloat MaxVal = APFloat(FltSem);
3927 MaxVal.convertFromAPInt(APInt::getOneBitSet(Precision, Precision - 1),
3928 /*IsSigned*/ false, APFloat::rmNearestTiesToEven);
3929 SDValue MaxValNode =
3930 DAG.getConstantFP(MaxVal, DL, ContainerVT.getVectorElementType());
3931 SDValue MaxValSplat = DAG.getNode(RISCVISD::VFMV_V_F_VL, DL, ContainerVT,
3932 DAG.getUNDEF(ContainerVT), MaxValNode, VL);
3933
3934 // If abs(Src) was larger than MaxVal or nan, keep it.
3935 Mask = DAG.getNode(
3936 RISCVISD::SETCC_VL, DL, MaskVT,
3937 {Abs, MaxValSplat, DAG.getCondCode(ISD::SETOLT), Mask, Mask, VL});
3938
3939 // Truncate to integer and convert back to FP.
3940 MVT IntVT = ContainerVT.changeVectorElementTypeToInteger();
3941 MVT XLenVT = Subtarget.getXLenVT();
3942 SDValue Truncated;
3943
3944 switch (Op.getOpcode()) {
3945 default:
3946 llvm_unreachable("Unexpected opcode");
3947 case ISD::STRICT_FCEIL:
3948 case ISD::STRICT_FFLOOR:
3949 case ISD::STRICT_FROUND:
3953 Truncated = DAG.getNode(
3954 RISCVISD::STRICT_VFCVT_RM_X_F_VL, DL, DAG.getVTList(IntVT, MVT::Other),
3955 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3956 break;
3957 }
3958 case ISD::STRICT_FTRUNC:
3959 Truncated =
3960 DAG.getNode(RISCVISD::STRICT_VFCVT_RTZ_X_F_VL, DL,
3961 DAG.getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3962 break;
3964 Truncated = DAG.getNode(RISCVISD::STRICT_VFROUND_NOEXCEPT_VL, DL,
3965 DAG.getVTList(ContainerVT, MVT::Other), Chain, Src,
3966 Mask, VL);
3967 break;
3968 }
3969 Chain = Truncated.getValue(1);
3970
3971 // VFROUND_NOEXCEPT_VL includes SINT_TO_FP_VL.
3972 if (Op.getOpcode() != ISD::STRICT_FNEARBYINT) {
3973 Truncated = DAG.getNode(RISCVISD::STRICT_SINT_TO_FP_VL, DL,
3974 DAG.getVTList(ContainerVT, MVT::Other), Chain,
3975 Truncated, Mask, VL);
3976 Chain = Truncated.getValue(1);
3977 }
3978
3979 // Restore the original sign so that -0.0 is preserved.
3980 Truncated = DAG.getNode(RISCVISD::FCOPYSIGN_VL, DL, ContainerVT, Truncated,
3981 Src, Src, Mask, VL);
3982
3983 if (VT.isFixedLengthVector())
3984 Truncated = convertFromScalableVector(VT, Truncated, DAG, Subtarget);
3985 return DAG.getMergeValues({Truncated, Chain}, DL);
3986}
3987
3988static SDValue
3990 const RISCVSubtarget &Subtarget) {
3991 MVT VT = Op.getSimpleValueType();
3992 if (VT.isVector())
3993 return lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(Op, DAG, Subtarget);
3994
3995 if (DAG.shouldOptForSize())
3996 return SDValue();
3997
3998 SDLoc DL(Op);
3999 SDValue Src = Op.getOperand(0);
4000
4001 // Create an integer the size of the mantissa with the MSB set. This and all
4002 // values larger than it don't have any fractional bits so don't need to be
4003 // converted.
4004 const fltSemantics &FltSem = VT.getFltSemantics();
4005 unsigned Precision = APFloat::semanticsPrecision(FltSem);
4006 APFloat MaxVal = APFloat(FltSem);
4007 MaxVal.convertFromAPInt(APInt::getOneBitSet(Precision, Precision - 1),
4008 /*IsSigned*/ false, APFloat::rmNearestTiesToEven);
4009 SDValue MaxValNode = DAG.getConstantFP(MaxVal, DL, VT);
4010
4012 return DAG.getNode(RISCVISD::FROUND, DL, VT, Src, MaxValNode,
4013 DAG.getTargetConstant(FRM, DL, Subtarget.getXLenVT()));
4014}
4015
4016// Expand vector [L]LRINT and [L]LROUND by converting to the integer domain.
4018 const RISCVSubtarget &Subtarget) {
4019 SDLoc DL(Op);
4020 MVT DstVT = Op.getSimpleValueType();
4021 SDValue Src = Op.getOperand(0);
4022 MVT SrcVT = Src.getSimpleValueType();
4023 assert(SrcVT.isVector() && DstVT.isVector() &&
4024 !(SrcVT.isFixedLengthVector() ^ DstVT.isFixedLengthVector()) &&
4025 "Unexpected type");
4026
4027 MVT DstContainerVT = DstVT;
4028 MVT SrcContainerVT = SrcVT;
4029
4030 if (DstVT.isFixedLengthVector()) {
4031 DstContainerVT = getContainerForFixedLengthVector(DstVT, Subtarget);
4032 SrcContainerVT = getContainerForFixedLengthVector(SrcVT, Subtarget);
4033 Src = convertToScalableVector(SrcContainerVT, Src, DAG, Subtarget);
4034 }
4035
4036 auto [Mask, VL] = getDefaultVLOps(SrcVT, SrcContainerVT, DL, DAG, Subtarget);
4037
4038 // [b]f16 -> f32
4039 MVT SrcElemType = SrcVT.getVectorElementType();
4040 if (SrcElemType == MVT::f16 || SrcElemType == MVT::bf16) {
4041 MVT F32VT = SrcContainerVT.changeVectorElementType(MVT::f32);
4042 Src = DAG.getNode(RISCVISD::FP_EXTEND_VL, DL, F32VT, Src, Mask, VL);
4043 }
4044
4045 SDValue Res =
4046 DAG.getNode(RISCVISD::VFCVT_RM_X_F_VL, DL, DstContainerVT, Src, Mask,
4047 DAG.getTargetConstant(matchRoundingOp(Op.getOpcode()), DL,
4048 Subtarget.getXLenVT()),
4049 VL);
4050
4051 if (!DstVT.isFixedLengthVector())
4052 return Res;
4053
4054 return convertFromScalableVector(DstVT, Res, DAG, Subtarget);
4055}
4056
4057static SDValue
4059 const SDLoc &DL, EVT VT, SDValue Passthru, SDValue Op,
4060 SDValue Offset, SDValue Mask, SDValue VL,
4062 if (Passthru.isUndef())
4064 SDValue PolicyOp = DAG.getTargetConstant(Policy, DL, Subtarget.getXLenVT());
4065 SDValue Ops[] = {Passthru, Op, Offset, Mask, VL, PolicyOp};
4066 return DAG.getNode(RISCVISD::VSLIDEDOWN_VL, DL, VT, Ops);
4067}
4068
4069static SDValue
4070getVSlideup(SelectionDAG &DAG, const RISCVSubtarget &Subtarget, const SDLoc &DL,
4071 EVT VT, SDValue Passthru, SDValue Op, SDValue Offset, SDValue Mask,
4072 SDValue VL,
4074 if (Passthru.isUndef())
4076 SDValue PolicyOp = DAG.getTargetConstant(Policy, DL, Subtarget.getXLenVT());
4077 SDValue Ops[] = {Passthru, Op, Offset, Mask, VL, PolicyOp};
4078 return DAG.getNode(RISCVISD::VSLIDEUP_VL, DL, VT, Ops);
4079}
4080
4084 int64_t Addend;
4085};
4086
4087static std::optional<APInt> getExactInteger(const APFloat &APF,
4089 // We will use a SINT_TO_FP to materialize this constant so we should use a
4090 // signed APSInt here.
4091 APSInt ValInt(BitWidth, /*IsUnsigned*/ false);
4092 // We use an arbitrary rounding mode here. If a floating-point is an exact
4093 // integer (e.g., 1.0), the rounding mode does not affect the output value. If
4094 // the rounding mode changes the output value, then it is not an exact
4095 // integer.
4097 bool IsExact;
4098 // If it is out of signed integer range, it will return an invalid operation.
4099 // If it is not an exact integer, IsExact is false.
4100 if ((APF.convertToInteger(ValInt, ArbitraryRM, &IsExact) ==
4102 !IsExact)
4103 return std::nullopt;
4104 return ValInt.extractBits(BitWidth, 0);
4105}
4106
4107// Try to match an arithmetic-sequence BUILD_VECTOR [X,X+S,X+2*S,...,X+(N-1)*S]
4108// to the (non-zero) step S and start value X. This can be then lowered as the
4109// RVV sequence (VID * S) + X, for example.
4110// The step S is represented as an integer numerator divided by a positive
4111// denominator. Note that the implementation currently only identifies
4112// sequences in which either the numerator is +/- 1 or the denominator is 1. It
4113// cannot detect 2/3, for example.
4114// Note that this method will also match potentially unappealing index
4115// sequences, like <i32 0, i32 50939494>, however it is left to the caller to
4116// determine whether this is worth generating code for.
4117//
4118// EltSizeInBits is the size of the type that the sequence will be calculated
4119// in, i.e. SEW for build_vectors or XLEN for address calculations.
4120static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
4121 unsigned EltSizeInBits) {
4122 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unexpected BUILD_VECTOR");
4124 return std::nullopt;
4125 bool IsInteger = Op.getValueType().isInteger();
4126
4127 std::optional<unsigned> SeqStepDenom;
4128 std::optional<APInt> SeqStepNum;
4129 std::optional<APInt> SeqAddend;
4130 std::optional<std::pair<APInt, unsigned>> PrevElt;
4131 assert(EltSizeInBits >= Op.getValueType().getScalarSizeInBits());
4132
4133 // First extract the ops into a list of constant integer values. This may not
4134 // be possible for floats if they're not all representable as integers.
4135 SmallVector<std::optional<APInt>> Elts(Op.getNumOperands());
4136 const unsigned OpSize = Op.getScalarValueSizeInBits();
4137 for (auto [Idx, Elt] : enumerate(Op->op_values())) {
4138 if (Elt.isUndef()) {
4139 Elts[Idx] = std::nullopt;
4140 continue;
4141 }
4142 if (IsInteger) {
4143 Elts[Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
4144 } else {
4145 auto ExactInteger =
4146 getExactInteger(cast<ConstantFPSDNode>(Elt)->getValueAPF(), OpSize);
4147 if (!ExactInteger)
4148 return std::nullopt;
4149 Elts[Idx] = *ExactInteger;
4150 }
4151 }
4152
4153 for (auto [Idx, Elt] : enumerate(Elts)) {
4154 // Assume undef elements match the sequence; we just have to be careful
4155 // when interpolating across them.
4156 if (!Elt)
4157 continue;
4158
4159 if (PrevElt) {
4160 // Calculate the step since the last non-undef element, and ensure
4161 // it's consistent across the entire sequence.
4162 unsigned IdxDiff = Idx - PrevElt->second;
4163 APInt ValDiff = *Elt - PrevElt->first;
4164
4165 // A zero-value value difference means that we're somewhere in the middle
4166 // of a fractional step, e.g. <0,0,0*,0,1,1,1,1>. Wait until we notice a
4167 // step change before evaluating the sequence.
4168 if (ValDiff == 0)
4169 continue;
4170
4171 int64_t Remainder = ValDiff.srem(IdxDiff);
4172 // Normalize the step if it's greater than 1.
4173 if (Remainder != ValDiff.getSExtValue()) {
4174 // The difference must cleanly divide the element span.
4175 if (Remainder != 0)
4176 return std::nullopt;
4177 ValDiff = ValDiff.sdiv(IdxDiff);
4178 IdxDiff = 1;
4179 }
4180
4181 if (!SeqStepNum)
4182 SeqStepNum = ValDiff;
4183 else if (ValDiff != SeqStepNum)
4184 return std::nullopt;
4185
4186 if (!SeqStepDenom)
4187 SeqStepDenom = IdxDiff;
4188 else if (IdxDiff != *SeqStepDenom)
4189 return std::nullopt;
4190 }
4191
4192 // Record this non-undef element for later.
4193 if (!PrevElt || PrevElt->first != *Elt)
4194 PrevElt = std::make_pair(*Elt, Idx);
4195 }
4196
4197 // We need to have logged a step for this to count as a legal index sequence.
4198 if (!SeqStepNum || !SeqStepDenom)
4199 return std::nullopt;
4200
4201 // Loop back through the sequence and validate elements we might have skipped
4202 // while waiting for a valid step. While doing this, log any sequence addend.
4203 for (auto [Idx, Elt] : enumerate(Elts)) {
4204 if (!Elt)
4205 continue;
4206 APInt ExpectedVal =
4207 (APInt(EltSizeInBits, Idx, /*isSigned=*/false, /*implicitTrunc=*/true) *
4208 *SeqStepNum)
4209 .sdiv(*SeqStepDenom);
4210
4211 APInt Addend = *Elt - ExpectedVal;
4212 if (!SeqAddend)
4213 SeqAddend = Addend;
4214 else if (Addend != SeqAddend)
4215 return std::nullopt;
4216 }
4217
4218 assert(SeqAddend && "Must have an addend if we have a step");
4219
4220 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
4221 SeqAddend->getSExtValue()};
4222}
4223
4224// Match a splatted value (SPLAT_VECTOR/BUILD_VECTOR) of an EXTRACT_VECTOR_ELT
4225// and lower it as a VRGATHER_VX_VL from the source vector.
4226static SDValue matchSplatAsGather(SDValue SplatVal, MVT VT, const SDLoc &DL,
4227 SelectionDAG &DAG,
4228 const RISCVSubtarget &Subtarget) {
4229 if (SplatVal.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
4230 return SDValue();
4231 SDValue Src = SplatVal.getOperand(0);
4232 // Don't perform this optimization for i1 vectors, or if the element types are
4233 // different
4234 // FIXME: Support i1 vectors, maybe by promoting to i8?
4235 MVT EltTy = VT.getVectorElementType();
4236 if (EltTy == MVT::i1 ||
4237 !DAG.getTargetLoweringInfo().isTypeLegal(Src.getValueType()))
4238 return SDValue();
4239 MVT SrcVT = Src.getSimpleValueType();
4240 if (EltTy != SrcVT.getVectorElementType())
4241 return SDValue();
4242 SDValue Idx = SplatVal.getOperand(1);
4243 // The index must be a legal type.
4244 if (Idx.getValueType() != Subtarget.getXLenVT())
4245 return SDValue();
4246
4247 // Check that we know Idx lies within VT
4248 if (!TypeSize::isKnownLE(SrcVT.getSizeInBits(), VT.getSizeInBits())) {
4249 auto *CIdx = dyn_cast<ConstantSDNode>(Idx);
4250 if (!CIdx || CIdx->getZExtValue() >= VT.getVectorMinNumElements())
4251 return SDValue();
4252 }
4253
4254 // Convert fixed length vectors to scalable
4255 MVT ContainerVT = VT;
4256 if (VT.isFixedLengthVector())
4257 ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
4258
4259 MVT SrcContainerVT = SrcVT;
4260 if (SrcVT.isFixedLengthVector()) {
4261 SrcContainerVT = getContainerForFixedLengthVector(SrcVT, Subtarget);
4262 Src = convertToScalableVector(SrcContainerVT, Src, DAG, Subtarget);
4263 }
4264
4265 // Put Vec in a VT sized vector
4266 if (SrcContainerVT.getVectorMinNumElements() <
4267 ContainerVT.getVectorMinNumElements())
4268 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(ContainerVT), Src, 0);
4269 else
4270 Src = DAG.getExtractSubvector(DL, ContainerVT, Src, 0);
4271
4272 // We checked that Idx fits inside VT earlier
4273 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
4274 SDValue Gather = DAG.getNode(RISCVISD::VRGATHER_VX_VL, DL, ContainerVT, Src,
4275 Idx, DAG.getUNDEF(ContainerVT), Mask, VL);
4276 if (VT.isFixedLengthVector())
4277 Gather = convertFromScalableVector(VT, Gather, DAG, Subtarget);
4278 return Gather;
4279}
4280
4282 const RISCVSubtarget &Subtarget) {
4283 MVT VT = Op.getSimpleValueType();
4284 assert(VT.isFixedLengthVector() && "Unexpected vector!");
4285
4286 MVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
4287
4288 SDLoc DL(Op);
4289 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
4290
4291 if (auto SimpleVID = isSimpleVIDSequence(Op, Op.getScalarValueSizeInBits())) {
4292 int64_t StepNumerator = SimpleVID->StepNumerator;
4293 unsigned StepDenominator = SimpleVID->StepDenominator;
4294 int64_t Addend = SimpleVID->Addend;
4295
4296 assert(StepNumerator != 0 && "Invalid step");
4297 bool Negate = false;
4298 int64_t SplatStepVal = StepNumerator;
4299 unsigned StepOpcode = ISD::MUL;
4300 // Exclude INT64_MIN to avoid passing it to std::abs. We won't optimize it
4301 // anyway as the shift of 63 won't fit in uimm5.
4302 if (StepNumerator != 1 && StepNumerator != INT64_MIN &&
4303 isPowerOf2_64(std::abs(StepNumerator))) {
4304 Negate = StepNumerator < 0;
4305 StepOpcode = ISD::SHL;
4306 SplatStepVal = Log2_64(std::abs(StepNumerator));
4307 }
4308
4309 // Only emit VIDs with suitably-small steps. We use imm5 as a threshold
4310 // since it's the immediate value many RVV instructions accept. There is
4311 // no vmul.vi instruction so ensure multiply constant can fit in a
4312 // single addi instruction. For the addend, we allow up to 32 bits..
4313 if (((StepOpcode == ISD::MUL && isInt<12>(SplatStepVal)) ||
4314 (StepOpcode == ISD::SHL && isUInt<5>(SplatStepVal))) &&
4315 isPowerOf2_32(StepDenominator) &&
4316 (SplatStepVal >= 0 || StepDenominator == 1) && isInt<32>(Addend)) {
4317 MVT VIDVT =
4319 MVT VIDContainerVT = getContainerForFixedLengthVector(VIDVT, Subtarget);
4320 SDValue VID = DAG.getNode(RISCVISD::VID_VL, DL, VIDContainerVT, Mask, VL);
4321 // Convert right out of the scalable type so we can use standard ISD
4322 // nodes for the rest of the computation. If we used scalable types with
4323 // these, we'd lose the fixed-length vector info and generate worse
4324 // vsetvli code.
4325 VID = convertFromScalableVector(VIDVT, VID, DAG, Subtarget);
4326 if ((StepOpcode == ISD::MUL && SplatStepVal != 1) ||
4327 (StepOpcode == ISD::SHL && SplatStepVal != 0)) {
4328 SDValue SplatStep = DAG.getSignedConstant(SplatStepVal, DL, VIDVT);
4329 VID = DAG.getNode(StepOpcode, DL, VIDVT, VID, SplatStep);
4330 }
4331 if (StepDenominator != 1) {
4332 SDValue SplatStep =
4333 DAG.getConstant(Log2_64(StepDenominator), DL, VIDVT);
4334 VID = DAG.getNode(ISD::SRL, DL, VIDVT, VID, SplatStep);
4335 }
4336 if (Addend != 0 || Negate) {
4337 SDValue SplatAddend = DAG.getSignedConstant(Addend, DL, VIDVT);
4338 VID = DAG.getNode(Negate ? ISD::SUB : ISD::ADD, DL, VIDVT, SplatAddend,
4339 VID);
4340 }
4341 if (VT.isFloatingPoint()) {
4342 // TODO: Use vfwcvt to reduce register pressure.
4343 VID = DAG.getNode(ISD::SINT_TO_FP, DL, VT, VID);
4344 }
4345 return VID;
4346 }
4347 }
4348
4349 return SDValue();
4350}
4351
4352/// Try and optimize BUILD_VECTORs with "dominant values" - these are values
4353/// which constitute a large proportion of the elements. In such cases we can
4354/// splat a vector with the dominant element and make up the shortfall with
4355/// INSERT_VECTOR_ELTs. Returns SDValue if not profitable.
4356/// Note that this includes vectors of 2 elements by association. The
4357/// upper-most element is the "dominant" one, allowing us to use a splat to
4358/// "insert" the upper element, and an insert of the lower element at position
4359/// 0, which improves codegen.
4361 const RISCVSubtarget &Subtarget) {
4362 MVT VT = Op.getSimpleValueType();
4363 assert(VT.isFixedLengthVector() && "Unexpected vector!");
4364
4365 MVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
4366
4367 SDLoc DL(Op);
4368 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
4369
4370 MVT XLenVT = Subtarget.getXLenVT();
4371 unsigned NumElts = Op.getNumOperands();
4372
4373 SDValue DominantValue;
4374 unsigned MostCommonCount = 0;
4375 DenseMap<SDValue, unsigned> ValueCounts;
4376 unsigned NumUndefElts =
4377 count_if(Op->op_values(), [](const SDValue &V) { return V.isUndef(); });
4378
4379 // Track the number of scalar loads we know we'd be inserting, estimated as
4380 // any non-zero floating-point constant. Other kinds of element are either
4381 // already in registers or are materialized on demand. The threshold at which
4382 // a vector load is more desirable than several scalar materializion and
4383 // vector-insertion instructions is not known.
4384 unsigned NumScalarLoads = 0;
4385
4386 for (SDValue V : Op->op_values()) {
4387 if (V.isUndef())
4388 continue;
4389
4390 unsigned &Count = ValueCounts[V];
4391 if (0 == Count)
4392 if (auto *CFP = dyn_cast<ConstantFPSDNode>(V))
4393 NumScalarLoads += !CFP->isPosZero();
4394
4395 // Is this value dominant? In case of a tie, prefer the highest element as
4396 // it's cheaper to insert near the beginning of a vector than it is at the
4397 // end.
4398 if (++Count >= MostCommonCount) {
4399 DominantValue = V;
4400 MostCommonCount = Count;
4401 }
4402 }
4403
4404 assert(DominantValue && "Not expecting an all-undef BUILD_VECTOR");
4405 unsigned NumDefElts = NumElts - NumUndefElts;
4406 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
4407
4408 // Don't perform this optimization when optimizing for size, since
4409 // materializing elements and inserting them tends to cause code bloat.
4410 if (!DAG.shouldOptForSize() && NumScalarLoads < NumElts &&
4411 (NumElts != 2 || ISD::isBuildVectorOfConstantSDNodes(Op.getNode())) &&
4412 ((MostCommonCount > DominantValueCountThreshold) ||
4413 (ValueCounts.size() <= Log2_32(NumDefElts)))) {
4414 // Start by splatting the most common element.
4415 SDValue Vec = DAG.getSplatBuildVector(VT, DL, DominantValue);
4416
4417 DenseSet<SDValue> Processed{DominantValue};
4418
4419 // We can handle an insert into the last element (of a splat) via
4420 // v(f)slide1down. This is slightly better than the vslideup insert
4421 // lowering as it avoids the need for a vector group temporary. It
4422 // is also better than using vmerge.vx as it avoids the need to
4423 // materialize the mask in a vector register.
4424 if (SDValue LastOp = Op->getOperand(Op->getNumOperands() - 1);
4425 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
4426 LastOp != DominantValue) {
4427 Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget);
4428 auto OpCode =
4429 VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
4430 if (!VT.isFloatingPoint())
4431 LastOp = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, LastOp);
4432 Vec = DAG.getNode(OpCode, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Vec,
4433 LastOp, Mask, VL);
4434 Vec = convertFromScalableVector(VT, Vec, DAG, Subtarget);
4435 Processed.insert(LastOp);
4436 }
4437
4438 MVT SelMaskTy = VT.changeVectorElementType(MVT::i1);
4439 for (const auto &OpIdx : enumerate(Op->ops())) {
4440 const SDValue &V = OpIdx.value();
4441 if (V.isUndef() || !Processed.insert(V).second)
4442 continue;
4443 if (ValueCounts[V] == 1) {
4444 Vec = DAG.getInsertVectorElt(DL, Vec, V, OpIdx.index());
4445 } else {
4446 // Blend in all instances of this value using a VSELECT, using a
4447 // mask where each bit signals whether that element is the one
4448 // we're after.
4450 transform(Op->op_values(), std::back_inserter(Ops), [&](SDValue V1) {
4451 return DAG.getConstant(V == V1, DL, XLenVT);
4452 });
4453 Vec = DAG.getNode(ISD::VSELECT, DL, VT,
4454 DAG.getBuildVector(SelMaskTy, DL, Ops),
4455 DAG.getSplatBuildVector(VT, DL, V), Vec);
4456 }
4457 }
4458
4459 return Vec;
4460 }
4461
4462 return SDValue();
4463}
4464
4466 const RISCVSubtarget &Subtarget) {
4467 MVT VT = Op.getSimpleValueType();
4468 assert(VT.isFixedLengthVector() && "Unexpected vector!");
4469
4470 MVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
4471
4472 SDLoc DL(Op);
4473 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
4474
4475 MVT XLenVT = Subtarget.getXLenVT();
4476 unsigned NumElts = Op.getNumOperands();
4477
4478 if (VT.getVectorElementType() == MVT::i1) {
4479 if (ISD::isBuildVectorAllZeros(Op.getNode())) {
4480 SDValue VMClr = DAG.getNode(RISCVISD::VMCLR_VL, DL, ContainerVT, VL);
4481 return convertFromScalableVector(VT, VMClr, DAG, Subtarget);
4482 }
4483
4484 if (ISD::isBuildVectorAllOnes(Op.getNode())) {
4485 SDValue VMSet = DAG.getNode(RISCVISD::VMSET_VL, DL, ContainerVT, VL);
4486 return convertFromScalableVector(VT, VMSet, DAG, Subtarget);
4487 }
4488
4489 // Lower constant mask BUILD_VECTORs via an integer vector type, in
4490 // scalar integer chunks whose bit-width depends on the number of mask
4491 // bits and XLEN.
4492 // First, determine the most appropriate scalar integer type to use. This
4493 // is at most XLenVT, but may be shrunk to a smaller vector element type
4494 // according to the size of the final vector - use i8 chunks rather than
4495 // XLenVT if we're producing a v8i1. This results in more consistent
4496 // codegen across RV32 and RV64.
4497 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.getXLen());
4498 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.getELen());
4499 // If we have to use more than one INSERT_VECTOR_ELT then this
4500 // optimization is likely to increase code size; avoid performing it in
4501 // such a case. We can use a load from a constant pool in this case.
4502 if (DAG.shouldOptForSize() && NumElts > NumViaIntegerBits)
4503 return SDValue();
4504 // Now we can create our integer vector type. Note that it may be larger
4505 // than the resulting mask type: v4i1 would use v1i8 as its integer type.
4506 unsigned IntegerViaVecElts = divideCeil(NumElts, NumViaIntegerBits);
4507 MVT IntegerViaVecVT =
4508 MVT::getVectorVT(MVT::getIntegerVT(NumViaIntegerBits),
4509 IntegerViaVecElts);
4510
4511 uint64_t Bits = 0;
4512 unsigned BitPos = 0, IntegerEltIdx = 0;
4513 SmallVector<SDValue, 8> Elts(IntegerViaVecElts);
4514
4515 for (unsigned I = 0; I < NumElts;) {
4516 SDValue V = Op.getOperand(I);
4517 bool BitValue = !V.isUndef() && V->getAsZExtVal();
4518 Bits |= ((uint64_t)BitValue << BitPos);
4519 ++BitPos;
4520 ++I;
4521
4522 // Once we accumulate enough bits to fill our scalar type or process the
4523 // last element, insert into our vector and clear our accumulated data.
4524 if (I % NumViaIntegerBits == 0 || I == NumElts) {
4525 if (NumViaIntegerBits <= 32)
4526 Bits = SignExtend64<32>(Bits);
4527 SDValue Elt = DAG.getSignedConstant(Bits, DL, XLenVT);
4528 Elts[IntegerEltIdx] = Elt;
4529 Bits = 0;
4530 BitPos = 0;
4531 IntegerEltIdx++;
4532 }
4533 }
4534
4535 SDValue Vec = DAG.getBuildVector(IntegerViaVecVT, DL, Elts);
4536
4537 if (NumElts < NumViaIntegerBits) {
4538 // If we're producing a smaller vector than our minimum legal integer
4539 // type, bitcast to the equivalent (known-legal) mask type, and extract
4540 // our final mask.
4541 assert(IntegerViaVecVT == MVT::v1i8 && "Unexpected mask vector type");
4542 Vec = DAG.getBitcast(MVT::v8i1, Vec);
4543 Vec = DAG.getExtractSubvector(DL, VT, Vec, 0);
4544 } else {
4545 // Else we must have produced an integer type with the same size as the
4546 // mask type; bitcast for the final result.
4547 assert(VT.getSizeInBits() == IntegerViaVecVT.getSizeInBits());
4548 Vec = DAG.getBitcast(VT, Vec);
4549 }
4550
4551 return Vec;
4552 }
4553
4555 unsigned Opc = VT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL
4556 : RISCVISD::VMV_V_X_VL;
4557 if (!VT.isFloatingPoint())
4558 Splat = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Splat);
4559 Splat =
4560 DAG.getNode(Opc, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Splat, VL);
4561 return convertFromScalableVector(VT, Splat, DAG, Subtarget);
4562 }
4563
4564 // Try and match index sequences, which we can lower to the vid instruction
4565 // with optional modifications. An all-undef vector is matched by
4566 // getSplatValue, above.
4567 if (SDValue Res = lowerBuildVectorViaVID(Op, DAG, Subtarget))
4568 return Res;
4569
4570 // For very small build_vectors, use a single scalar insert of a constant.
4571 // TODO: Base this on constant rematerialization cost, not size.
4572 const unsigned EltBitSize = VT.getScalarSizeInBits();
4573 if (VT.getSizeInBits() <= 32 &&
4575 MVT ViaIntVT = MVT::getIntegerVT(VT.getSizeInBits());
4576 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
4577 "Unexpected sequence type");
4578 // If we can use the original VL with the modified element type, this
4579 // means we only have a VTYPE toggle, not a VL toggle. TODO: Should this
4580 // be moved into InsertVSETVLI?
4581 unsigned ViaVecLen =
4582 (Subtarget.getRealMinVLen() >= VT.getSizeInBits() * NumElts) ? NumElts : 1;
4583 MVT ViaVecVT = MVT::getVectorVT(ViaIntVT, ViaVecLen);
4584
4585 uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
4586 uint64_t SplatValue = 0;
4587 // Construct the amalgamated value at this larger vector type.
4588 for (const auto &OpIdx : enumerate(Op->op_values())) {
4589 const auto &SeqV = OpIdx.value();
4590 if (!SeqV.isUndef())
4591 SplatValue |=
4592 ((SeqV->getAsZExtVal() & EltMask) << (OpIdx.index() * EltBitSize));
4593 }
4594
4595 // On RV64, sign-extend from 32 to 64 bits where possible in order to
4596 // achieve better constant materializion.
4597 // On RV32, we need to sign-extend to use getSignedConstant.
4598 if (ViaIntVT == MVT::i32)
4599 SplatValue = SignExtend64<32>(SplatValue);
4600
4601 SDValue Vec = DAG.getInsertVectorElt(
4602 DL, DAG.getUNDEF(ViaVecVT),
4603 DAG.getSignedConstant(SplatValue, DL, XLenVT), 0);
4604 if (ViaVecLen != 1)
4605 Vec = DAG.getExtractSubvector(DL, MVT::getVectorVT(ViaIntVT, 1), Vec, 0);
4606 return DAG.getBitcast(VT, Vec);
4607 }
4608
4609
4610 // Attempt to detect "hidden" splats, which only reveal themselves as splats
4611 // when re-interpreted as a vector with a larger element type. For example,
4612 // v4i16 = build_vector i16 0, i16 1, i16 0, i16 1
4613 // could be instead splat as
4614 // v2i32 = build_vector i32 0x00010000, i32 0x00010000
4615 // TODO: This optimization could also work on non-constant splats, but it
4616 // would require bit-manipulation instructions to construct the splat value.
4617 SmallVector<SDValue> Sequence;
4618 const auto *BV = cast<BuildVectorSDNode>(Op);
4619 if (VT.isInteger() && EltBitSize < Subtarget.getELen() &&
4621 BV->getRepeatedSequence(Sequence) &&
4622 (Sequence.size() * EltBitSize) <= Subtarget.getELen()) {
4623 unsigned SeqLen = Sequence.size();
4624 MVT ViaIntVT = MVT::getIntegerVT(EltBitSize * SeqLen);
4625 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
4626 ViaIntVT == MVT::i64) &&
4627 "Unexpected sequence type");
4628
4629 // If we can use the original VL with the modified element type, this
4630 // means we only have a VTYPE toggle, not a VL toggle. TODO: Should this
4631 // be moved into InsertVSETVLI?
4632 const unsigned RequiredVL = NumElts / SeqLen;
4633 const unsigned ViaVecLen =
4634 (Subtarget.getRealMinVLen() >= ViaIntVT.getSizeInBits() * NumElts) ?
4635 NumElts : RequiredVL;
4636 MVT ViaVecVT = MVT::getVectorVT(ViaIntVT, ViaVecLen);
4637
4638 unsigned EltIdx = 0;
4639 uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
4640 uint64_t SplatValue = 0;
4641 // Construct the amalgamated value which can be splatted as this larger
4642 // vector type.
4643 for (const auto &SeqV : Sequence) {
4644 if (!SeqV.isUndef())
4645 SplatValue |=
4646 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
4647 EltIdx++;
4648 }
4649
4650 // On RV64, sign-extend from 32 to 64 bits where possible in order to
4651 // achieve better constant materializion.
4652 // On RV32, we need to sign-extend to use getSignedConstant.
4653 if (ViaIntVT == MVT::i32)
4654 SplatValue = SignExtend64<32>(SplatValue);
4655
4656 // Since we can't introduce illegal i64 types at this stage, we can only
4657 // perform an i64 splat on RV32 if it is its own sign-extended value. That
4658 // way we can use RVV instructions to splat.
4659 assert((ViaIntVT.bitsLE(XLenVT) ||
4660 (!Subtarget.is64Bit() && ViaIntVT == MVT::i64)) &&
4661 "Unexpected bitcast sequence");
4662 if (ViaIntVT.bitsLE(XLenVT) || isInt<32>(SplatValue)) {
4663 SDValue ViaVL =
4664 DAG.getConstant(ViaVecVT.getVectorNumElements(), DL, XLenVT);
4665 MVT ViaContainerVT =
4666 getContainerForFixedLengthVector(ViaVecVT, Subtarget);
4667 SDValue Splat =
4668 DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ViaContainerVT,
4669 DAG.getUNDEF(ViaContainerVT),
4670 DAG.getSignedConstant(SplatValue, DL, XLenVT), ViaVL);
4671 Splat = convertFromScalableVector(ViaVecVT, Splat, DAG, Subtarget);
4672 if (ViaVecLen != RequiredVL)
4674 DL, MVT::getVectorVT(ViaIntVT, RequiredVL), Splat, 0);
4675 return DAG.getBitcast(VT, Splat);
4676 }
4677 }
4678
4679 // If the number of signbits allows, see if we can lower as a <N x i8>.
4680 // Our main goal here is to reduce LMUL (and thus work) required to
4681 // build the constant, but we will also narrow if the resulting
4682 // narrow vector is known to materialize cheaply.
4683 // TODO: We really should be costing the smaller vector. There are
4684 // profitable cases this misses.
4685 if (EltBitSize > 8 && VT.isInteger() &&
4686 (NumElts <= 4 || VT.getSizeInBits() > Subtarget.getRealMinVLen()) &&
4687 DAG.ComputeMaxSignificantBits(Op) <= 8) {
4688 SDValue Source = DAG.getBuildVector(VT.changeVectorElementType(MVT::i8),
4689 DL, Op->ops());
4690 Source = convertToScalableVector(ContainerVT.changeVectorElementType(MVT::i8),
4691 Source, DAG, Subtarget);
4692 SDValue Res = DAG.getNode(RISCVISD::VSEXT_VL, DL, ContainerVT, Source, Mask, VL);
4693 return convertFromScalableVector(VT, Res, DAG, Subtarget);
4694 }
4695
4696 if (SDValue Res = lowerBuildVectorViaDominantValues(Op, DAG, Subtarget))
4697 return Res;
4698
4699 // For constant vectors, use generic constant pool lowering. Otherwise,
4700 // we'd have to materialize constants in GPRs just to move them into the
4701 // vector.
4702 return SDValue();
4703}
4704
4705static unsigned getPACKOpcode(unsigned DestBW,
4706 const RISCVSubtarget &Subtarget) {
4707 switch (DestBW) {
4708 default:
4709 llvm_unreachable("Unsupported pack size");
4710 case 16:
4711 return RISCV::PACKH;
4712 case 32:
4713 return Subtarget.is64Bit() ? RISCV::PACKW : RISCV::PACK;
4714 case 64:
4715 assert(Subtarget.is64Bit());
4716 return RISCV::PACK;
4717 }
4718}
4719
4720/// Double the element size of the build vector to reduce the number
4721/// of vslide1down in the build vector chain. In the worst case, this
4722/// trades three scalar operations for 1 vector operation. Scalar
4723/// operations are generally lower latency, and for out-of-order cores
4724/// we also benefit from additional parallelism.
4726 const RISCVSubtarget &Subtarget) {
4727 SDLoc DL(Op);
4728 MVT VT = Op.getSimpleValueType();
4729 assert(VT.isFixedLengthVector() && "Unexpected vector!");
4730 MVT ElemVT = VT.getVectorElementType();
4731 if (!ElemVT.isInteger())
4732 return SDValue();
4733
4734 // TODO: Relax these architectural restrictions, possibly with costing
4735 // of the actual instructions required.
4736 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4737 return SDValue();
4738
4739 unsigned NumElts = VT.getVectorNumElements();
4740 unsigned ElemSizeInBits = ElemVT.getSizeInBits();
4741 if (ElemSizeInBits >= std::min(Subtarget.getELen(), Subtarget.getXLen()) ||
4742 NumElts % 2 != 0)
4743 return SDValue();
4744
4745 // Produce [B,A] packed into a type twice as wide. Note that all
4746 // scalars are XLenVT, possibly masked (see below).
4747 MVT XLenVT = Subtarget.getXLenVT();
4748 SDValue Mask = DAG.getConstant(
4749 APInt::getLowBitsSet(XLenVT.getSizeInBits(), ElemSizeInBits), DL, XLenVT);
4750 auto pack = [&](SDValue A, SDValue B) {
4751 // Bias the scheduling of the inserted operations to near the
4752 // definition of the element - this tends to reduce register
4753 // pressure overall.
4754 SDLoc ElemDL(B);
4755 if (Subtarget.hasStdExtZbkb())
4756 // Note that we're relying on the high bits of the result being
4757 // don't care. For PACKW, the result is *sign* extended.
4758 return SDValue(
4759 DAG.getMachineNode(getPACKOpcode(ElemSizeInBits * 2, Subtarget),
4760 ElemDL, XLenVT, A, B),
4761 0);
4762
4763 A = DAG.getNode(ISD::AND, SDLoc(A), XLenVT, A, Mask);
4764 B = DAG.getNode(ISD::AND, SDLoc(B), XLenVT, B, Mask);
4765 SDValue ShtAmt = DAG.getConstant(ElemSizeInBits, ElemDL, XLenVT);
4766 return DAG.getNode(ISD::OR, ElemDL, XLenVT, A,
4767 DAG.getNode(ISD::SHL, ElemDL, XLenVT, B, ShtAmt),
4769 };
4770
4771 SmallVector<SDValue> NewOperands;
4772 NewOperands.reserve(NumElts / 2);
4773 for (unsigned i = 0; i < VT.getVectorNumElements(); i += 2)
4774 NewOperands.push_back(pack(Op.getOperand(i), Op.getOperand(i + 1)));
4775 assert(NumElts == NewOperands.size() * 2);
4776 MVT WideVT = MVT::getIntegerVT(ElemSizeInBits * 2);
4777 MVT WideVecVT = MVT::getVectorVT(WideVT, NumElts / 2);
4778 return DAG.getNode(ISD::BITCAST, DL, VT,
4779 DAG.getBuildVector(WideVecVT, DL, NewOperands));
4780}
4781
4783 const RISCVSubtarget &Subtarget) {
4784 MVT VT = Op.getSimpleValueType();
4785 assert(VT.isFixedLengthVector() && "Unexpected vector!");
4786
4787 MVT EltVT = VT.getVectorElementType();
4788 MVT XLenVT = Subtarget.getXLenVT();
4789
4790 SDLoc DL(Op);
4791
4792 if (Subtarget.isRV32() && Subtarget.hasStdExtP()) {
4793 if (VT == MVT::v2i16) {
4794 SDValue Lo = DAG.getBitcast(
4795 MVT::v2i16,
4796 DAG.getAnyExtOrTrunc(Op->getOperand(0), DL, MVT::i32));
4797 SDValue Hi = DAG.getBitcast(
4798 MVT::v2i16,
4799 DAG.getAnyExtOrTrunc(Op->getOperand(1), DL, MVT::i32));
4800 return DAG.getNode(RISCVISD::PPAIRE, DL, MVT::v2i16, Lo, Hi);
4801 }
4802
4803 if (VT == MVT::v4i8) {
4804 // <4 x i8> BUILD_VECTOR a, b, c, d -> PACK(PPACK.DH pair(a, c), pair(b,
4805 // d))
4806 SDValue Val0 =
4807 DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(0));
4808 SDValue Val1 =
4809 DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(1));
4810 SDValue Val2 =
4811 DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(2));
4812 SDValue Val3 =
4813 DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(3));
4814 SDValue Concat1 =
4815 DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Val0, Val2);
4816 SDValue Concat2 =
4817 DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Val1, Val3);
4818 SDValue PPairE =
4819 DAG.getNode(RISCVISD::PPAIRE, DL, MVT::v8i8, Concat1, Concat2);
4820
4821 SDValue Lo = DAG.getExtractSubvector(DL, MVT::v4i8, PPairE, 0);
4822 SDValue Hi = DAG.getExtractSubvector(DL, MVT::v4i8, PPairE, 4);
4823
4824 return DAG.getBitcast(MVT::v4i8,
4825 DAG.getNode(RISCVISD::PPAIRE, DL, MVT::v2i16,
4826 DAG.getBitcast(MVT::v2i16, Lo),
4827 DAG.getBitcast(MVT::v2i16, Hi)));
4828 }
4829
4830 llvm_unreachable("Unexpected RV32 P BUILD_VECTOR type");
4831 }
4832
4833 // Proper support for f16 requires Zvfh. bf16 always requires special
4834 // handling. We need to cast the scalar to integer and create an integer
4835 // build_vector.
4836 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
4837 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
4838 MVT IVT = VT.changeVectorElementType(MVT::i16);
4839 SmallVector<SDValue, 16> NewOps(Op.getNumOperands());
4840 for (const auto &[I, U] : enumerate(Op->ops())) {
4841 SDValue Elem = U.get();
4842 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4843 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4844 // Called by LegalizeDAG, we need to use XLenVT operations since we
4845 // can't create illegal types.
4846 if (auto *C = dyn_cast<ConstantFPSDNode>(Elem)) {
4847 // Manually constant fold so the integer build_vector can be lowered
4848 // better. Waiting for DAGCombine will be too late.
4849 APInt V =
4850 C->getValueAPF().bitcastToAPInt().sext(XLenVT.getSizeInBits());
4851 NewOps[I] = DAG.getConstant(V, DL, XLenVT);
4852 } else {
4853 NewOps[I] = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Elem);
4854 }
4855 } else {
4856 // Called by scalar type legalizer, we can use i16.
4857 NewOps[I] = DAG.getBitcast(MVT::i16, Op.getOperand(I));
4858 }
4859 }
4860 SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, DL, IVT, NewOps);
4861 return DAG.getBitcast(VT, Res);
4862 }
4863
4864 if (ISD::isBuildVectorOfConstantSDNodes(Op.getNode()) ||
4866 return lowerBuildVectorOfConstants(Op, DAG, Subtarget);
4867
4868 MVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
4869
4870 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
4871
4872 if (VT.getVectorElementType() == MVT::i1) {
4873 // A BUILD_VECTOR can be lowered as a SETCC. For each fixed-length mask
4874 // vector type, we have a legal equivalently-sized i8 type, so we can use
4875 // that.
4876 MVT WideVecVT = VT.changeVectorElementType(MVT::i8);
4877 SDValue VecZero = DAG.getConstant(0, DL, WideVecVT);
4878
4879 SDValue WideVec;
4881 // For a splat, perform a scalar truncate before creating the wider
4882 // vector.
4883 Splat = DAG.getNode(ISD::AND, DL, Splat.getValueType(), Splat,
4884 DAG.getConstant(1, DL, Splat.getValueType()));
4885 WideVec = DAG.getSplatBuildVector(WideVecVT, DL, Splat);
4886 } else {
4887 SmallVector<SDValue, 8> Ops(Op->op_values());
4888 WideVec = DAG.getBuildVector(WideVecVT, DL, Ops);
4889 SDValue VecOne = DAG.getConstant(1, DL, WideVecVT);
4890 WideVec = DAG.getNode(ISD::AND, DL, WideVecVT, WideVec, VecOne);
4891 }
4892
4893 return DAG.getSetCC(DL, VT, WideVec, VecZero, ISD::SETNE);
4894 }
4895
4897 if (auto Gather = matchSplatAsGather(Splat, VT, DL, DAG, Subtarget))
4898 return Gather;
4899
4900 if (!VT.isFloatingPoint())
4901 Splat = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Splat);
4902
4903 // Prefer vmv.s.x/vfmv.s.f if legal to reduce work and register
4904 // pressure at high LMUL.
4905 bool IsScalar = all_of(Op->ops().drop_front(),
4906 [](const SDUse &U) { return U.get().isUndef(); });
4907 unsigned Opc =
4908 VT.isFloatingPoint()
4909 ? (IsScalar ? RISCVISD::VFMV_S_F_VL : RISCVISD::VFMV_V_F_VL)
4910 : (IsScalar ? RISCVISD::VMV_S_X_VL : RISCVISD::VMV_V_X_VL);
4911 Splat =
4912 DAG.getNode(Opc, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Splat, VL);
4913 return convertFromScalableVector(VT, Splat, DAG, Subtarget);
4914 }
4915
4916 if (SDValue Res = lowerBuildVectorViaDominantValues(Op, DAG, Subtarget))
4917 return Res;
4918
4919 // If we're compiling for an exact VLEN value, we can split our work per
4920 // register in the register group.
4921 if (const auto VLen = Subtarget.getRealVLen();
4922 VLen && VT.getSizeInBits().getKnownMinValue() > *VLen) {
4923 MVT ElemVT = VT.getVectorElementType();
4924 unsigned ElemsPerVReg = *VLen / ElemVT.getFixedSizeInBits();
4925 EVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
4926 MVT OneRegVT = MVT::getVectorVT(ElemVT, ElemsPerVReg);
4927 MVT M1VT = getContainerForFixedLengthVector(OneRegVT, Subtarget);
4928 assert(M1VT == RISCVTargetLowering::getM1VT(M1VT));
4929
4930 // The following semantically builds up a fixed length concat_vector
4931 // of the component build_vectors. We eagerly lower to scalable and
4932 // insert_subvector here to avoid DAG combining it back to a large
4933 // build_vector.
4934 SmallVector<SDValue> BuildVectorOps(Op->ops());
4935 unsigned NumOpElts = M1VT.getVectorMinNumElements();
4936 SDValue Vec = DAG.getUNDEF(ContainerVT);
4937 for (unsigned i = 0; i < VT.getVectorNumElements(); i += ElemsPerVReg) {
4938 auto OneVRegOfOps = ArrayRef(BuildVectorOps).slice(i, ElemsPerVReg);
4939 SDValue SubBV =
4940 DAG.getNode(ISD::BUILD_VECTOR, DL, OneRegVT, OneVRegOfOps);
4941 SubBV = convertToScalableVector(M1VT, SubBV, DAG, Subtarget);
4942 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4943 Vec = DAG.getInsertSubvector(DL, Vec, SubBV, InsertIdx);
4944 }
4945 return convertFromScalableVector(VT, Vec, DAG, Subtarget);
4946 }
4947
4948 // If we're about to resort to vslide1down (or stack usage), pack our
4949 // elements into the widest scalar type we can. This will force a VL/VTYPE
4950 // toggle, but reduces the critical path, the number of vslide1down ops
4951 // required, and possibly enables scalar folds of the values.
4952 if (SDValue Res = lowerBuildVectorViaPacking(Op, DAG, Subtarget))
4953 return Res;
4954
4955 // For m1 vectors, if we have non-undef values in both halves of our vector,
4956 // split the vector into low and high halves, build them separately, then
4957 // use a vselect to combine them. For long vectors, this cuts the critical
4958 // path of the vslide1down sequence in half, and gives us an opportunity
4959 // to special case each half independently. Note that we don't change the
4960 // length of the sub-vectors here, so if both fallback to the generic
4961 // vslide1down path, we should be able to fold the vselect into the final
4962 // vslidedown (for the undef tail) for the first half w/ masking.
4963 unsigned NumElts = VT.getVectorNumElements();
4964 unsigned NumUndefElts =
4965 count_if(Op->op_values(), [](const SDValue &V) { return V.isUndef(); });
4966 unsigned NumDefElts = NumElts - NumUndefElts;
4967 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
4968 ContainerVT.bitsLE(RISCVTargetLowering::getM1VT(ContainerVT))) {
4969 SmallVector<SDValue> SubVecAOps, SubVecBOps;
4970 SmallVector<SDValue> MaskVals;
4971 SDValue UndefElem = DAG.getUNDEF(Op->getOperand(0)->getValueType(0));
4972 SubVecAOps.reserve(NumElts);
4973 SubVecBOps.reserve(NumElts);
4974 for (const auto &[Idx, U] : enumerate(Op->ops())) {
4975 SDValue Elem = U.get();
4976 if (Idx < NumElts / 2) {
4977 SubVecAOps.push_back(Elem);
4978 SubVecBOps.push_back(UndefElem);
4979 } else {
4980 SubVecAOps.push_back(UndefElem);
4981 SubVecBOps.push_back(Elem);
4982 }
4983 bool SelectMaskVal = (Idx < NumElts / 2);
4984 MaskVals.push_back(DAG.getConstant(SelectMaskVal, DL, XLenVT));
4985 }
4986 assert(SubVecAOps.size() == NumElts && SubVecBOps.size() == NumElts &&
4987 MaskVals.size() == NumElts);
4988
4989 SDValue SubVecA = DAG.getBuildVector(VT, DL, SubVecAOps);
4990 SDValue SubVecB = DAG.getBuildVector(VT, DL, SubVecBOps);
4991 MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
4992 SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, MaskVals);
4993 return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, SubVecA, SubVecB);
4994 }
4995
4996 // Cap the cost at a value linear to the number of elements in the vector.
4997 // The default lowering is to use the stack. The vector store + scalar loads
4998 // is linear in VL. However, at high lmuls vslide1down and vslidedown end up
4999 // being (at least) linear in LMUL. As a result, using the vslidedown
5000 // lowering for every element ends up being VL*LMUL..
5001 // TODO: Should we be directly costing the stack alternative? Doing so might
5002 // give us a more accurate upper bound.
5003 InstructionCost LinearBudget = VT.getVectorNumElements() * 2;
5004
5005 // TODO: unify with TTI getSlideCost.
5006 InstructionCost PerSlideCost = 1;
5007 switch (RISCVTargetLowering::getLMUL(ContainerVT)) {
5008 default: break;
5009 case RISCVVType::LMUL_2:
5010 PerSlideCost = 2;
5011 break;
5012 case RISCVVType::LMUL_4:
5013 PerSlideCost = 4;
5014 break;
5015 case RISCVVType::LMUL_8:
5016 PerSlideCost = 8;
5017 break;
5018 }
5019
5020 // TODO: Should we be using the build instseq then cost + evaluate scheme
5021 // we use for integer constants here?
5022 unsigned UndefCount = 0;
5023 for (const SDValue &V : Op->ops()) {
5024 if (V.isUndef()) {
5025 UndefCount++;
5026 continue;
5027 }
5028 if (UndefCount) {
5029 LinearBudget -= PerSlideCost;
5030 UndefCount = 0;
5031 }
5032 LinearBudget -= PerSlideCost;
5033 }
5034 if (UndefCount) {
5035 LinearBudget -= PerSlideCost;
5036 }
5037
5038 if (LinearBudget < 0)
5039 return SDValue();
5040
5041 assert((!VT.isFloatingPoint() ||
5042 VT.getVectorElementType().getSizeInBits() <= Subtarget.getFLen()) &&
5043 "Illegal type which will result in reserved encoding");
5044
5045 const unsigned Policy = RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC;
5046
5047 // General case: splat the first operand and slide other operands down one
5048 // by one to form a vector. Alternatively, if every operand is an
5049 // extraction from element 0 of a vector, we use that vector from the last
5050 // extraction as the start value and slide up instead of slide down. Such that
5051 // (1) we can avoid the initial splat (2) we can turn those vslide1up into
5052 // vslideup of 1 later and eliminate the vector to scalar movement, which is
5053 // something we cannot do with vslide1down/vslidedown.
5054 // Of course, using vslide1up/vslideup might increase the register pressure,
5055 // and that's why we conservatively limit to cases where every operand is an
5056 // extraction from the first element.
5057 SmallVector<SDValue> Operands(Op->op_begin(), Op->op_end());
5058 SDValue EVec;
5059 bool SlideUp = false;
5060 auto getVSlide = [&](EVT ContainerVT, SDValue Passthru, SDValue Vec,
5061 SDValue Offset, SDValue Mask, SDValue VL) -> SDValue {
5062 if (SlideUp)
5063 return getVSlideup(DAG, Subtarget, DL, ContainerVT, Passthru, Vec, Offset,
5064 Mask, VL, Policy);
5065 return getVSlidedown(DAG, Subtarget, DL, ContainerVT, Passthru, Vec, Offset,
5066 Mask, VL, Policy);
5067 };
5068
5069 // The reason we don't use all_of here is because we're also capturing EVec
5070 // from the last non-undef operand. If the std::execution_policy of the
5071 // underlying std::all_of is anything but std::sequenced_policy we might
5072 // capture the wrong EVec.
5073 for (SDValue V : Operands) {
5074 using namespace SDPatternMatch;
5075 SlideUp = V.isUndef() || sd_match(V, m_ExtractElt(m_Value(EVec), m_Zero()));
5076 if (!SlideUp)
5077 break;
5078 }
5079
5080 // Do not slideup if the element type of EVec is different.
5081 if (SlideUp) {
5082 MVT EVecEltVT = EVec.getSimpleValueType().getVectorElementType();
5083 MVT ContainerEltVT = ContainerVT.getVectorElementType();
5084 if (EVecEltVT != ContainerEltVT)
5085 SlideUp = false;
5086 }
5087
5088 if (SlideUp) {
5089 MVT EVecContainerVT = EVec.getSimpleValueType();
5090 // Make sure the original vector has scalable vector type.
5091 if (EVecContainerVT.isFixedLengthVector()) {
5092 EVecContainerVT =
5093 getContainerForFixedLengthVector(EVecContainerVT, Subtarget);
5094 EVec = convertToScalableVector(EVecContainerVT, EVec, DAG, Subtarget);
5095 }
5096
5097 // Adapt EVec's type into ContainerVT.
5098 if (EVecContainerVT.getVectorMinNumElements() <
5099 ContainerVT.getVectorMinNumElements())
5100 EVec = DAG.getInsertSubvector(DL, DAG.getUNDEF(ContainerVT), EVec, 0);
5101 else
5102 EVec = DAG.getExtractSubvector(DL, ContainerVT, EVec, 0);
5103
5104 // Reverse the elements as we're going to slide up from the last element.
5105 std::reverse(Operands.begin(), Operands.end());
5106 }
5107
5108 SDValue Vec;
5109 UndefCount = 0;
5110 for (SDValue V : Operands) {
5111 if (V.isUndef()) {
5112 UndefCount++;
5113 continue;
5114 }
5115
5116 // Start our sequence with either a TA splat or extract source in the
5117 // hopes that hardware is able to recognize there's no dependency on the
5118 // prior value of our temporary register.
5119 if (!Vec) {
5120 if (SlideUp) {
5121 Vec = EVec;
5122 } else {
5123 Vec = DAG.getSplatVector(VT, DL, V);
5124 Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget);
5125 }
5126
5127 UndefCount = 0;
5128 continue;
5129 }
5130
5131 if (UndefCount) {
5132 const SDValue Offset = DAG.getConstant(UndefCount, DL, Subtarget.getXLenVT());
5133 Vec = getVSlide(ContainerVT, DAG.getUNDEF(ContainerVT), Vec, Offset, Mask,
5134 VL);
5135 UndefCount = 0;
5136 }
5137
5138 unsigned Opcode;
5139 if (VT.isFloatingPoint())
5140 Opcode = SlideUp ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VFSLIDE1DOWN_VL;
5141 else
5142 Opcode = SlideUp ? RISCVISD::VSLIDE1UP_VL : RISCVISD::VSLIDE1DOWN_VL;
5143
5144 if (!VT.isFloatingPoint())
5145 V = DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getXLenVT(), V);
5146 Vec = DAG.getNode(Opcode, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Vec,
5147 V, Mask, VL);
5148 }
5149 if (UndefCount) {
5150 const SDValue Offset = DAG.getConstant(UndefCount, DL, Subtarget.getXLenVT());
5151 Vec = getVSlide(ContainerVT, DAG.getUNDEF(ContainerVT), Vec, Offset, Mask,
5152 VL);
5153 }
5154 return convertFromScalableVector(VT, Vec, DAG, Subtarget);
5155}
5156
5157static SDValue splatPartsI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
5159 SelectionDAG &DAG) {
5160 if (!Passthru)
5161 Passthru = DAG.getUNDEF(VT);
5163 int32_t LoC = cast<ConstantSDNode>(Lo)->getSExtValue();
5164 int32_t HiC = cast<ConstantSDNode>(Hi)->getSExtValue();
5165 // If Hi constant is all the same sign bit as Lo, lower this as a custom
5166 // node in order to try and match RVV vector/scalar instructions.
5167 if ((LoC >> 31) == HiC)
5168 return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, Passthru, Lo, VL);
5169
5170 // Use vmv.v.x with EEW=32. Use either a vsetivli or vsetvli to change
5171 // VL. This can temporarily increase VL if VL less than VLMAX.
5172 if (LoC == HiC) {
5173 SDValue NewVL;
5174 if (isa<ConstantSDNode>(VL) && isUInt<4>(VL->getAsZExtVal()))
5175 NewVL = DAG.getNode(ISD::ADD, DL, VL.getValueType(), VL, VL);
5176 else
5177 NewVL = DAG.getRegister(RISCV::X0, MVT::i32);
5178 MVT InterVT =
5179 MVT::getVectorVT(MVT::i32, VT.getVectorElementCount() * 2);
5180 auto InterVec = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, InterVT,
5181 DAG.getUNDEF(InterVT), Lo, NewVL);
5182 return DAG.getNode(ISD::BITCAST, DL, VT, InterVec);
5183 }
5184 }
5185
5186 // Detect cases where Hi is (SRA Lo, 31) which means Hi is Lo sign extended.
5187 if (Hi.getOpcode() == ISD::SRA && Hi.getOperand(0) == Lo &&
5188 isa<ConstantSDNode>(Hi.getOperand(1)) &&
5189 Hi.getConstantOperandVal(1) == 31)
5190 return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, Passthru, Lo, VL);
5191
5192 // If the hi bits of the splat are undefined, then it's fine to just splat Lo
5193 // even if it might be sign extended.
5194 if (Hi.isUndef())
5195 return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, Passthru, Lo, VL);
5196
5197 // Fall back to a stack store and stride x0 vector load.
5198 return DAG.getNode(RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL, DL, VT, Passthru, Lo,
5199 Hi, VL);
5200}
5201
5202// Called by type legalization to handle splat of i64 on RV32.
5203// FIXME: We can optimize this when the type has sign or zero bits in one
5204// of the halves.
5205static SDValue splatSplitI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
5206 SDValue Scalar, SDValue VL,
5207 SelectionDAG &DAG) {
5208 assert(Scalar.getValueType() == MVT::i64 && "Unexpected VT!");
5209 SDValue Lo, Hi;
5210 std::tie(Lo, Hi) = DAG.SplitScalar(Scalar, DL, MVT::i32, MVT::i32);
5211 return splatPartsI64WithVL(DL, VT, Passthru, Lo, Hi, VL, DAG);
5212}
5213
5214// This function lowers a splat of a scalar operand Splat with the vector
5215// length VL. It ensures the final sequence is type legal, which is useful when
5216// lowering a splat after type legalization.
5217static SDValue lowerScalarSplat(SDValue Passthru, SDValue Scalar, SDValue VL,
5218 MVT VT, const SDLoc &DL, SelectionDAG &DAG,
5219 const RISCVSubtarget &Subtarget) {
5220 bool HasPassthru = Passthru && !Passthru.isUndef();
5221 if (!HasPassthru && !Passthru)
5222 Passthru = DAG.getUNDEF(VT);
5223
5224 MVT EltVT = VT.getVectorElementType();
5225 MVT XLenVT = Subtarget.getXLenVT();
5226
5227 if (VT.isFloatingPoint()) {
5228 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
5229 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
5230 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
5231 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
5232 Scalar = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Scalar);
5233 else
5234 Scalar = DAG.getNode(ISD::BITCAST, DL, MVT::i16, Scalar);
5235 MVT IVT = VT.changeVectorElementType(MVT::i16);
5236 Passthru = DAG.getNode(ISD::BITCAST, DL, IVT, Passthru);
5237 SDValue Splat =
5238 lowerScalarSplat(Passthru, Scalar, VL, IVT, DL, DAG, Subtarget);
5239 return DAG.getNode(ISD::BITCAST, DL, VT, Splat);
5240 }
5241 return DAG.getNode(RISCVISD::VFMV_V_F_VL, DL, VT, Passthru, Scalar, VL);
5242 }
5243
5244 // Simplest case is that the operand needs to be promoted to XLenVT.
5245 if (Scalar.getValueType().bitsLE(XLenVT)) {
5246 // If the operand is a constant, sign extend to increase our chances
5247 // of being able to use a .vi instruction. ANY_EXTEND would become a
5248 // a zero extend and the simm5 check in isel would fail.
5249 // FIXME: Should we ignore the upper bits in isel instead?
5250 unsigned ExtOpc =
5252 Scalar = DAG.getNode(ExtOpc, DL, XLenVT, Scalar);
5253 return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, Passthru, Scalar, VL);
5254 }
5255
5256 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
5257 "Unexpected scalar for splat lowering!");
5258
5259 if (isOneConstant(VL) && isNullConstant(Scalar))
5260 return DAG.getNode(RISCVISD::VMV_S_X_VL, DL, VT, Passthru,
5261 DAG.getConstant(0, DL, XLenVT), VL);
5262
5263 // Otherwise use the more complicated splatting algorithm.
5264 return splatSplitI64WithVL(DL, VT, Passthru, Scalar, VL, DAG);
5265}
5266
5267// This function lowers an insert of a scalar operand Scalar into lane
5268// 0 of the vector regardless of the value of VL. The contents of the
5269// remaining lanes of the result vector are unspecified. VL is assumed
5270// to be non-zero.
5272 const SDLoc &DL, SelectionDAG &DAG,
5273 const RISCVSubtarget &Subtarget) {
5274 assert(VT.isScalableVector() && "Expect VT is scalable vector type.");
5275
5276 const MVT XLenVT = Subtarget.getXLenVT();
5277 SDValue Passthru = DAG.getUNDEF(VT);
5278
5279 if (Scalar.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
5280 isNullConstant(Scalar.getOperand(1))) {
5281 SDValue ExtractedVal = Scalar.getOperand(0);
5282 // The element types must be the same.
5283 if (ExtractedVal.getValueType().getVectorElementType() ==
5284 VT.getVectorElementType()) {
5285 MVT ExtractedVT = ExtractedVal.getSimpleValueType();
5286 MVT ExtractedContainerVT = ExtractedVT;
5287 if (ExtractedContainerVT.isFixedLengthVector()) {
5288 ExtractedContainerVT =
5289 getContainerForFixedLengthVector(ExtractedContainerVT, Subtarget);
5290 ExtractedVal = convertToScalableVector(ExtractedContainerVT,
5291 ExtractedVal, DAG, Subtarget);
5292 }
5293 if (ExtractedContainerVT.bitsLE(VT))
5294 return DAG.getInsertSubvector(DL, Passthru, ExtractedVal, 0);
5295 return DAG.getExtractSubvector(DL, VT, ExtractedVal, 0);
5296 }
5297 }
5298
5299 if (VT.isFloatingPoint())
5300 return DAG.getNode(RISCVISD::VFMV_S_F_VL, DL, VT, DAG.getUNDEF(VT), Scalar,
5301 VL);
5302
5303 // Avoid the tricky legalization cases by falling back to using the
5304 // splat code which already handles it gracefully.
5305 if (!Scalar.getValueType().bitsLE(XLenVT))
5306 return lowerScalarSplat(DAG.getUNDEF(VT), Scalar,
5307 DAG.getConstant(1, DL, XLenVT),
5308 VT, DL, DAG, Subtarget);
5309
5310 // If the operand is a constant, sign extend to increase our chances
5311 // of being able to use a .vi instruction. ANY_EXTEND would become a
5312 // a zero extend and the simm5 check in isel would fail.
5313 // FIXME: Should we ignore the upper bits in isel instead?
5314 unsigned ExtOpc =
5316 Scalar = DAG.getNode(ExtOpc, DL, XLenVT, Scalar);
5317 return DAG.getNode(RISCVISD::VMV_S_X_VL, DL, VT, DAG.getUNDEF(VT), Scalar,
5318 VL);
5319}
5320
5321/// If concat_vector(V1,V2) could be folded away to some existing
5322/// vector source, return it. Note that the source may be larger
5323/// than the requested concat_vector (i.e. a extract_subvector
5324/// might be required.)
5326 EVT VT = V1.getValueType();
5327 assert(VT == V2.getValueType() && "argument types must match");
5328 // Both input must be extracts.
5329 if (V1.getOpcode() != ISD::EXTRACT_SUBVECTOR ||
5331 return SDValue();
5332
5333 // Extracting from the same source.
5334 SDValue Src = V1.getOperand(0);
5335 if (Src != V2.getOperand(0) ||
5336 VT.isScalableVector() != Src.getValueType().isScalableVector())
5337 return SDValue();
5338
5339 // The extracts must extract the two halves of the source.
5340 if (V1.getConstantOperandVal(1) != 0 ||
5342 return SDValue();
5343
5344 return Src;
5345}
5346
5347// Can this shuffle be performed on exactly one (possibly larger) input?
5349
5350 if (V2.isUndef())
5351 return V1;
5352
5353 unsigned NumElts = VT.getVectorNumElements();
5354 // Src needs to have twice the number of elements.
5355 // TODO: Update shuffle lowering to add the extract subvector
5356 if (SDValue Src = foldConcatVector(V1, V2);
5357 Src && Src.getValueType().getVectorNumElements() == (NumElts * 2))
5358 return Src;
5359
5360 return SDValue();
5361}
5362
5363static bool isLegalVTForZvzipOperand(MVT VT, const RISCVSubtarget &Subtarget) {
5364 MVT ContainerVT = VT;
5365 if (VT.isFixedLengthVector())
5366 ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
5367 // Determine LMUL of the container vector.
5368 return RISCVTargetLowering::getLMUL(ContainerVT) != RISCVVType::LMUL_8;
5369}
5370
5371/// Is this shuffle interleaving contiguous elements from one vector into the
5372/// even elements and contiguous elements from another vector into the odd
5373/// elements. \p EvenSrc will contain the element that should be in the first
5374/// even element. \p OddSrc will contain the element that should be in the first
5375/// odd element. These can be the first element in a source or the element half
5376/// way through the source.
5377static bool isInterleaveShuffle(ArrayRef<int> Mask, MVT VT, int &EvenSrc,
5378 int &OddSrc, const RISCVSubtarget &Subtarget) {
5379 // We need to be able to widen elements to the next larger integer type or
5380 // use the vzip instruction at e64.
5381 if (VT.getScalarSizeInBits() >= Subtarget.getELen()) {
5382 if (!Subtarget.hasStdExtZvzip())
5383 return false;
5384 if (!isLegalVTForZvzipOperand(VT, Subtarget))
5385 return false;
5386 }
5387
5388 int Size = Mask.size();
5389 int NumElts = VT.getVectorNumElements();
5390 assert(Size == (int)NumElts && "Unexpected mask size");
5391
5392 SmallVector<unsigned, 2> StartIndexes;
5393 if (!ShuffleVectorInst::isInterleaveMask(Mask, 2, Size * 2, StartIndexes))
5394 return false;
5395
5396 EvenSrc = StartIndexes[0];
5397 OddSrc = StartIndexes[1];
5398
5399 // One source should be low half of first vector.
5400 if (EvenSrc != 0 && OddSrc != 0)
5401 return false;
5402
5403 // Subvectors will be subtracted from either at the start of the two input
5404 // vectors, or at the start and middle of the first vector if it's an unary
5405 // interleave.
5406 // In both cases, HalfNumElts will be extracted.
5407 // We need to ensure that the extract indices are 0 or HalfNumElts otherwise
5408 // we'll create an illegal extract_subvector.
5409 // FIXME: We could support other values using a slidedown first.
5410 int HalfNumElts = NumElts / 2;
5411 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
5412}
5413
5414/// Is this mask representing a masked combination of two slides?
5416 std::array<std::pair<int, int>, 2> &SrcInfo) {
5417 if (!llvm::isMaskedSlidePair(Mask, Mask.size(), SrcInfo))
5418 return false;
5419
5420 // Avoid matching vselect idioms
5421 if (SrcInfo[0].second == 0 && SrcInfo[1].second == 0)
5422 return false;
5423 // Prefer vslideup as the second instruction, and identity
5424 // only as the initial instruction.
5425 if ((SrcInfo[0].second > 0 && SrcInfo[1].second < 0) ||
5426 SrcInfo[1].second == 0)
5427 std::swap(SrcInfo[0], SrcInfo[1]);
5428 assert(SrcInfo[0].first != -1 && "Must find one slide");
5429 return true;
5430}
5431
5432// Exactly matches the semantics of a previously existing custom matcher
5433// to allow migration to new matcher without changing output.
5434static bool isElementRotate(const std::array<std::pair<int, int>, 2> &SrcInfo,
5435 unsigned NumElts) {
5436 if (SrcInfo[1].first == -1)
5437 return true;
5438 return SrcInfo[0].second < 0 && SrcInfo[1].second > 0 &&
5439 SrcInfo[1].second - SrcInfo[0].second == (int)NumElts;
5440}
5441
5442static bool isAlternating(const std::array<std::pair<int, int>, 2> &SrcInfo,
5443 ArrayRef<int> Mask, unsigned Factor,
5444 bool RequiredPolarity) {
5445 int NumElts = Mask.size();
5446 for (const auto &[Idx, M] : enumerate(Mask)) {
5447 if (M < 0)
5448 continue;
5449 int Src = M >= NumElts;
5450 int Diff = (int)Idx - (M % NumElts);
5451 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
5452 assert(C != (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
5453 "Must match exactly one of the two slides");
5454 if (RequiredPolarity != (C == (Idx / Factor) % 2))
5455 return false;
5456 }
5457 return true;
5458}
5459
5460/// Given a shuffle which can be represented as a pair of two slides,
5461/// see if it is a pair-even idiom.
5462/// Pair-even is:
5463/// vs2: a0 a1 a2 a3
5464/// vs1: b0 b1 b2 b3
5465/// vd: a0 b0 a2 b2
5466static bool isPairEven(const std::array<std::pair<int, int>, 2> &SrcInfo,
5467 ArrayRef<int> Mask, unsigned &Factor) {
5468 Factor = SrcInfo[1].second;
5469 return SrcInfo[0].second == 0 && isPowerOf2_32(Factor) &&
5470 Mask.size() % Factor == 0 &&
5471 isAlternating(SrcInfo, Mask, Factor, true);
5472}
5473
5474/// Given a shuffle which can be represented as a pair of two slides,
5475/// see if it is a pair-odd idiom.
5476/// Pair-odd is:
5477/// vs2: a0 a1 a2 a3
5478/// vs1: b0 b1 b2 b3
5479/// vd: a1 b1 a3 b3
5480/// Note that the operand order is swapped due to the way we canonicalize
5481/// the slides, so SrCInfo[0] is vs1, and SrcInfo[1] is vs2.
5482static bool isPairOdd(const std::array<std::pair<int, int>, 2> &SrcInfo,
5483 ArrayRef<int> Mask, unsigned &Factor) {
5484 Factor = -SrcInfo[1].second;
5485 return SrcInfo[0].second == 0 && isPowerOf2_32(Factor) &&
5486 Mask.size() % Factor == 0 &&
5487 isAlternating(SrcInfo, Mask, Factor, false);
5488}
5489
5490// Lower a deinterleave shuffle to SRL and TRUNC. Factor must be
5491// 2, 4, 8 and the integer type Factor-times larger than VT's
5492// element type must be a legal element type.
5493// [a, p, b, q, c, r, d, s] -> [a, b, c, d] (Factor=2, Index=0)
5494// -> [p, q, r, s] (Factor=2, Index=1)
5496 SDValue Src, unsigned Factor,
5497 unsigned Index, SelectionDAG &DAG) {
5498 unsigned EltBits = VT.getScalarSizeInBits();
5499 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
5500 MVT WideSrcVT = MVT::getVectorVT(MVT::getIntegerVT(EltBits * Factor),
5501 SrcEC.divideCoefficientBy(Factor));
5502 MVT ResVT = MVT::getVectorVT(MVT::getIntegerVT(EltBits),
5503 SrcEC.divideCoefficientBy(Factor));
5504 Src = DAG.getBitcast(WideSrcVT, Src);
5505
5506 unsigned Shift = Index * EltBits;
5507 SDValue Res = DAG.getNode(ISD::SRL, DL, WideSrcVT, Src,
5508 DAG.getConstant(Shift, DL, WideSrcVT));
5509 Res = DAG.getNode(ISD::TRUNCATE, DL, ResVT, Res);
5511 Res = DAG.getBitcast(CastVT, Res);
5512 return DAG.getInsertSubvector(DL, DAG.getUNDEF(VT), Res, 0);
5513}
5514
5515/// Match a single source shuffle which is an identity except that some
5516/// particular element is repeated. This can be lowered as a masked
5517/// vrgather.vi/vx. Note that the two source form of this is handled
5518/// by the recursive splitting logic and doesn't need special handling.
5520 const RISCVSubtarget &Subtarget,
5521 SelectionDAG &DAG) {
5522
5523 SDLoc DL(SVN);
5524 MVT VT = SVN->getSimpleValueType(0);
5525 SDValue V1 = SVN->getOperand(0);
5526 assert(SVN->getOperand(1).isUndef());
5527 ArrayRef<int> Mask = SVN->getMask();
5528 const unsigned NumElts = VT.getVectorNumElements();
5529 MVT XLenVT = Subtarget.getXLenVT();
5530
5531 std::optional<int> SplatIdx;
5532 for (auto [I, M] : enumerate(Mask)) {
5533 if (M == -1 || I == (unsigned)M)
5534 continue;
5535 if (SplatIdx && *SplatIdx != M)
5536 return SDValue();
5537 SplatIdx = M;
5538 }
5539
5540 if (!SplatIdx)
5541 return SDValue();
5542
5543 SmallVector<SDValue> MaskVals;
5544 for (int MaskIndex : Mask) {
5545 bool SelectMaskVal = MaskIndex == *SplatIdx;
5546 MaskVals.push_back(DAG.getConstant(SelectMaskVal, DL, XLenVT));
5547 }
5548 assert(MaskVals.size() == NumElts && "Unexpected select-like shuffle");
5549 MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
5550 SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, MaskVals);
5551 SDValue Splat = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT),
5552 SmallVector<int>(NumElts, *SplatIdx));
5553 return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, Splat, V1);
5554}
5555
5556// Lower the following shuffle to vslidedown.
5557// a)
5558// t49: v8i8 = extract_subvector t13, Constant:i64<0>
5559// t109: v8i8 = extract_subvector t13, Constant:i64<8>
5560// t108: v8i8 = vector_shuffle<1,2,3,4,5,6,7,8> t49, t106
5561// b)
5562// t69: v16i16 = extract_subvector t68, Constant:i64<0>
5563// t23: v8i16 = extract_subvector t69, Constant:i64<0>
5564// t29: v4i16 = extract_subvector t23, Constant:i64<4>
5565// t26: v8i16 = extract_subvector t69, Constant:i64<8>
5566// t30: v4i16 = extract_subvector t26, Constant:i64<0>
5567// t54: v4i16 = vector_shuffle<1,2,3,4> t29, t30
5569 SDValue V1, SDValue V2,
5570 ArrayRef<int> Mask,
5571 const RISCVSubtarget &Subtarget,
5572 SelectionDAG &DAG) {
5573 auto findNonEXTRACT_SUBVECTORParent =
5574 [](SDValue Parent) -> std::pair<SDValue, uint64_t> {
5575 uint64_t Offset = 0;
5576 while (Parent.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
5577 // EXTRACT_SUBVECTOR can be used to extract a fixed-width vector from
5578 // a scalable vector. But we don't want to match the case.
5579 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
5580 Offset += Parent.getConstantOperandVal(1);
5581 Parent = Parent.getOperand(0);
5582 }
5583 return std::make_pair(Parent, Offset);
5584 };
5585
5586 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(V1);
5587 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
5588
5589 // Extracting from the same source.
5590 SDValue Src = V1Src;
5591 if (Src != V2Src)
5592 return SDValue();
5593
5594 // Rebuild mask because Src may be from multiple EXTRACT_SUBVECTORs.
5595 SmallVector<int, 16> NewMask(Mask);
5596 for (size_t i = 0; i != NewMask.size(); ++i) {
5597 if (NewMask[i] == -1)
5598 continue;
5599
5600 if (static_cast<size_t>(NewMask[i]) < NewMask.size()) {
5601 NewMask[i] = NewMask[i] + V1IndexOffset;
5602 } else {
5603 // Minus NewMask.size() is needed. Otherwise, the b case would be
5604 // <5,6,7,12> instead of <5,6,7,8>.
5605 NewMask[i] = NewMask[i] - NewMask.size() + V2IndexOffset;
5606 }
5607 }
5608
5609 // First index must be known and non-zero. It will be used as the slidedown
5610 // amount.
5611 if (NewMask[0] <= 0)
5612 return SDValue();
5613
5614 // NewMask is also continuous.
5615 for (unsigned i = 1; i != NewMask.size(); ++i)
5616 if (NewMask[i - 1] + 1 != NewMask[i])
5617 return SDValue();
5618
5619 MVT XLenVT = Subtarget.getXLenVT();
5620 MVT SrcVT = Src.getSimpleValueType();
5621 MVT ContainerVT = getContainerForFixedLengthVector(SrcVT, Subtarget);
5622 auto [TrueMask, VL] = getDefaultVLOps(SrcVT, ContainerVT, DL, DAG, Subtarget);
5623 SDValue Slidedown =
5624 getVSlidedown(DAG, Subtarget, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
5625 convertToScalableVector(ContainerVT, Src, DAG, Subtarget),
5626 DAG.getConstant(NewMask[0], DL, XLenVT), TrueMask, VL);
5627 return DAG.getExtractSubvector(
5628 DL, VT, convertFromScalableVector(SrcVT, Slidedown, DAG, Subtarget), 0);
5629}
5630
5631// Because vslideup leaves the destination elements at the start intact, we can
5632// use it to perform shuffles that insert subvectors:
5633//
5634// vector_shuffle v8:v8i8, v9:v8i8, <0, 1, 2, 3, 8, 9, 10, 11>
5635// ->
5636// vsetvli zero, 8, e8, mf2, ta, ma
5637// vslideup.vi v8, v9, 4
5638//
5639// vector_shuffle v8:v8i8, v9:v8i8 <0, 1, 8, 9, 10, 5, 6, 7>
5640// ->
5641// vsetvli zero, 5, e8, mf2, tu, ma
5642// vslideup.v1 v8, v9, 2
5644 SDValue V1, SDValue V2,
5645 ArrayRef<int> Mask,
5646 const RISCVSubtarget &Subtarget,
5647 SelectionDAG &DAG) {
5648 unsigned NumElts = VT.getVectorNumElements();
5649 int NumSubElts, Index;
5650 if (!ShuffleVectorInst::isInsertSubvectorMask(Mask, NumElts, NumSubElts,
5651 Index))
5652 return SDValue();
5653
5654 bool OpsSwapped = Mask[Index] < (int)NumElts;
5655 SDValue InPlace = OpsSwapped ? V2 : V1;
5656 SDValue ToInsert = OpsSwapped ? V1 : V2;
5657
5658 MVT XLenVT = Subtarget.getXLenVT();
5659 MVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
5660 auto TrueMask = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget).first;
5661 // We slide up by the index that the subvector is being inserted at, and set
5662 // VL to the index + the number of elements being inserted.
5663 unsigned Policy =
5665 // If the we're adding a suffix to the in place vector, i.e. inserting right
5666 // up to the very end of it, then we don't actually care about the tail.
5667 if (NumSubElts + Index >= (int)NumElts)
5668 Policy |= RISCVVType::TAIL_AGNOSTIC;
5669
5670 InPlace = convertToScalableVector(ContainerVT, InPlace, DAG, Subtarget);
5671 ToInsert = convertToScalableVector(ContainerVT, ToInsert, DAG, Subtarget);
5672 SDValue VL = DAG.getConstant(NumSubElts + Index, DL, XLenVT);
5673
5674 SDValue Res;
5675 // If we're inserting into the lowest elements, use a tail undisturbed
5676 // vmv.v.v.
5677 if (Index == 0)
5678 Res = DAG.getNode(RISCVISD::VMV_V_V_VL, DL, ContainerVT, InPlace, ToInsert,
5679 VL);
5680 else
5681 Res = getVSlideup(DAG, Subtarget, DL, ContainerVT, InPlace, ToInsert,
5682 DAG.getConstant(Index, DL, XLenVT), TrueMask, VL, Policy);
5683 return convertFromScalableVector(VT, Res, DAG, Subtarget);
5684}
5685
5686// A shuffle of shuffles where the final data only is drawn from 2 input ops
5687// can be compressed into a single shuffle
5689 const RISCVSubtarget &Subtarget,
5690 SelectionDAG &DAG) {
5691 SDValue V1 = SVN->getOperand(0);
5692 SDValue V2 = SVN->getOperand(1);
5693
5694 if (V1.getOpcode() != ISD::VECTOR_SHUFFLE ||
5696 return SDValue();
5697
5698 if (!V1.hasOneUse() || !V2.hasOneUse())
5699 return SDValue();
5700
5701 ArrayRef<int> Mask = SVN->getMask();
5702 ArrayRef<int> V1Mask = cast<ShuffleVectorSDNode>(V1.getNode())->getMask();
5703 ArrayRef<int> V2Mask = cast<ShuffleVectorSDNode>(V2.getNode())->getMask();
5704 unsigned NumElts = Mask.size();
5705 SmallVector<int> NewMask(NumElts, -1);
5706 for (unsigned Idx : seq<unsigned>(NumElts)) {
5707 int Lane = Mask[Idx];
5708 // Don't assign if poison
5709 if (Lane == -1)
5710 continue;
5711 int OrigLane;
5712 bool SecondOp = false;
5713 if ((unsigned)Lane < NumElts) {
5714 OrigLane = V1Mask[Lane];
5715 } else {
5716 OrigLane = V2Mask[Lane - NumElts];
5717 SecondOp = true;
5718 }
5719 if (OrigLane == -1)
5720 continue;
5721 // Don't handle if shuffling from a second operand
5722 if ((unsigned)OrigLane >= NumElts)
5723 return SDValue();
5724 if (SecondOp)
5725 OrigLane += NumElts;
5726 NewMask[Idx] = OrigLane;
5727 }
5728
5729 EVT VT = SVN->getValueType(0);
5730 SDLoc DL(SVN);
5731
5732 return DAG.getVectorShuffle(VT, DL, V1->getOperand(0), V2->getOperand(0),
5733 NewMask);
5734}
5735
5736/// Match v(f)slide1up/down idioms. These operations involve sliding
5737/// N-1 elements to make room for an inserted scalar at one end.
5739 SDValue V1, SDValue V2,
5740 ArrayRef<int> Mask,
5741 const RISCVSubtarget &Subtarget,
5742 SelectionDAG &DAG) {
5743 bool OpsSwapped = false;
5744 if (!isa<BuildVectorSDNode>(V1)) {
5745 if (!isa<BuildVectorSDNode>(V2))
5746 return SDValue();
5747 std::swap(V1, V2);
5748 OpsSwapped = true;
5749 }
5750 SDValue Splat = cast<BuildVectorSDNode>(V1)->getSplatValue();
5751 if (!Splat)
5752 return SDValue();
5753
5754 // Return true if the mask could describe a slide of Mask.size() - 1
5755 // elements from concat_vector(V1, V2)[Base:] to [Offset:].
5756 auto isSlideMask = [](ArrayRef<int> Mask, unsigned Base, int Offset) {
5757 const unsigned S = (Offset > 0) ? 0 : -Offset;
5758 const unsigned E = Mask.size() - ((Offset > 0) ? Offset : 0);
5759 for (unsigned i = S; i != E; ++i)
5760 if (Mask[i] >= 0 && (unsigned)Mask[i] != Base + i + Offset)
5761 return false;
5762 return true;
5763 };
5764
5765 const unsigned NumElts = VT.getVectorNumElements();
5766 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
5767 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
5768 return SDValue();
5769
5770 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
5771 // Inserted lane must come from splat, undef scalar is legal but not profitable.
5772 if (InsertIdx < 0 || InsertIdx / NumElts != (unsigned)OpsSwapped)
5773 return SDValue();
5774
5775 MVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
5776 auto [TrueMask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
5777
5778 // zvfhmin and zvfbfmin don't have vfslide1{down,up}.vf so use fmv.x.h +
5779 // vslide1{down,up}.vx instead.
5780 if ((VT.getVectorElementType() == MVT::bf16 &&
5781 !Subtarget.hasVInstructionsBF16()) ||
5782 (VT.getVectorElementType() == MVT::f16 &&
5783 !Subtarget.hasVInstructionsF16())) {
5784 MVT IntVT = ContainerVT.changeVectorElementTypeToInteger();
5785 Splat =
5786 DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, Subtarget.getXLenVT(), Splat);
5787 V2 = DAG.getBitcast(
5788 IntVT, convertToScalableVector(ContainerVT, V2, DAG, Subtarget));
5789 SDValue Vec = DAG.getNode(
5790 IsVSlidedown ? RISCVISD::VSLIDE1DOWN_VL : RISCVISD::VSLIDE1UP_VL, DL,
5791 IntVT, DAG.getUNDEF(IntVT), V2, Splat, TrueMask, VL);
5792 Vec = DAG.getBitcast(ContainerVT, Vec);
5793 return convertFromScalableVector(VT, Vec, DAG, Subtarget);
5794 }
5795
5796 auto OpCode = IsVSlidedown ?
5797 (VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL) :
5798 (VT.isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VSLIDE1UP_VL);
5799 if (!VT.isFloatingPoint())
5800 Splat = DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getXLenVT(), Splat);
5801 auto Vec = DAG.getNode(OpCode, DL, ContainerVT,
5802 DAG.getUNDEF(ContainerVT),
5803 convertToScalableVector(ContainerVT, V2, DAG, Subtarget),
5804 Splat, TrueMask, VL);
5805 return convertFromScalableVector(VT, Vec, DAG, Subtarget);
5806}
5807
5808/// Match a mask which "spreads" the leading elements of a vector evenly
5809/// across the result. Factor is the spread amount, and Index is the
5810/// offset applied. (on success, Index < Factor) This is the inverse
5811/// of a deinterleave with the same Factor and Index. This is analogous
5812/// to an interleave, except that all but one lane is undef.
5814 unsigned &Index) {
5815 SmallVector<bool> LaneIsUndef(Factor, true);
5816 for (unsigned i = 0; i < Mask.size(); i++)
5817 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
5818
5819 bool Found = false;
5820 for (unsigned i = 0; i < Factor; i++) {
5821 if (LaneIsUndef[i])
5822 continue;
5823 if (Found)
5824 return false;
5825 Index = i;
5826 Found = true;
5827 }
5828 if (!Found)
5829 return false;
5830
5831 for (unsigned i = 0; i < Mask.size() / Factor; i++) {
5832 unsigned j = i * Factor + Index;
5833 if (Mask[j] != -1 && (unsigned)Mask[j] != i)
5834 return false;
5835 }
5836 return true;
5837}
5838
5839static SDValue lowerZvzipVPAIR(unsigned Opc, SDValue Op0, SDValue Op1,
5840 const SDLoc &DL, SelectionDAG &DAG,
5841 const RISCVSubtarget &Subtarget) {
5842 assert(RISCVISD::VPAIRE_VL == Opc || RISCVISD::VPAIRO_VL == Opc);
5844
5845 MVT VT = Op0.getSimpleValueType();
5847 Op0 = DAG.getBitcast(IntVT, Op0);
5848 Op1 = DAG.getBitcast(IntVT, Op1);
5849
5850 MVT ContainerVT = IntVT;
5851 if (VT.isFixedLengthVector()) {
5852 ContainerVT = getContainerForFixedLengthVector(IntVT, Subtarget);
5853 Op0 = convertToScalableVector(ContainerVT, Op0, DAG, Subtarget);
5854 Op1 = convertToScalableVector(ContainerVT, Op1, DAG, Subtarget);
5855 }
5856
5857 MVT InnerVT = ContainerVT;
5858 auto [Mask, VL] = getDefaultVLOps(IntVT, InnerVT, DL, DAG, Subtarget);
5859
5860 SDValue Passthru = DAG.getUNDEF(InnerVT);
5861 SDValue Res = DAG.getNode(Opc, DL, InnerVT, Op0, Op1, Passthru, Mask, VL);
5862 if (IntVT.isFixedLengthVector())
5863 Res = convertFromScalableVector(IntVT, Res, DAG, Subtarget);
5864 Res = DAG.getBitcast(VT, Res);
5865 return Res;
5866}
5867
5869 SelectionDAG &DAG,
5870 const RISCVSubtarget &Subtarget) {
5872 MVT VT = Op0.getSimpleValueType();
5874 Op0 = DAG.getBitcast(IntVT, Op0);
5875 Op1 = DAG.getBitcast(IntVT, Op1);
5876 MVT ContainerVT = IntVT;
5877 if (VT.isFixedLengthVector()) {
5878 ContainerVT = getContainerForFixedLengthVector(IntVT, Subtarget);
5879 Op0 = convertToScalableVector(ContainerVT, Op0, DAG, Subtarget);
5880 Op1 = convertToScalableVector(ContainerVT, Op1, DAG, Subtarget);
5881 }
5882 MVT ResVT = ContainerVT.getDoubleNumVectorElementsVT();
5883 auto [Mask, VL] = getDefaultVLOps(IntVT, ContainerVT, DL, DAG, Subtarget);
5884 SDValue Passthru = DAG.getUNDEF(ResVT);
5885 SDValue Res =
5886 DAG.getNode(RISCVISD::VZIP_VL, DL, ResVT, Op0, Op1, Passthru, Mask, VL);
5887 if (IntVT.isFixedLengthVector())
5889 DAG, Subtarget);
5890 Res = DAG.getBitcast(VT.getDoubleNumVectorElementsVT(), Res);
5891 return Res;
5892}
5893
5894static SDValue lowerZvzipVUNZIP(unsigned Opc, SDValue Op, const SDLoc &DL,
5895 SelectionDAG &DAG,
5896 const RISCVSubtarget &Subtarget) {
5897 assert(Opc == RISCVISD::VUNZIPE_VL || Opc == RISCVISD::VUNZIPO_VL);
5898 MVT VT = Op.getSimpleValueType();
5900
5902 Op = DAG.getBitcast(IntVT, Op);
5903 MVT ContainerVT = IntVT;
5904 if (VT.isFixedLengthVector()) {
5905 ContainerVT = getContainerForFixedLengthVector(IntVT, Subtarget);
5906 // For E64 with LMUL <= 1, we can't represent a smaller fractional LMUL for
5907 // the result (LMUL <= 1/2 is not valid for E64). We must widen the input
5908 // container to at least LMUL=2 so the result can be LMUL=1.
5909 if (ContainerVT.getVectorElementType() == MVT::i64 &&
5911 ContainerVT = MVT::getScalableVectorVT(MVT::i64, 2);
5912 }
5913 Op = convertToScalableVector(ContainerVT, Op, DAG, Subtarget);
5914 }
5915
5916 MVT ResVT = ContainerVT.getHalfNumVectorElementsVT();
5917 MVT HalfVT = VT.getHalfNumVectorElementsVT();
5918 MVT HalfIntVT = IntVT.getHalfNumVectorElementsVT();
5919 auto [Mask, VL] = getDefaultVLOps(ResVT, ResVT, DL, DAG, Subtarget);
5920 if (VT.isFixedLengthVector())
5921 VL = DAG.getConstant(VT.getVectorNumElements() / 2, DL,
5922 Subtarget.getXLenVT());
5923 SDValue Passthru = DAG.getUNDEF(ResVT);
5924 SDValue Res = DAG.getNode(Opc, DL, ResVT, Op, Passthru, Mask, VL);
5925 if (HalfIntVT.isFixedLengthVector())
5926 Res = convertFromScalableVector(HalfIntVT, Res, DAG, Subtarget);
5927 Res = DAG.getBitcast(HalfVT, Res);
5928 return Res;
5929}
5930
5931// Given a vector a, b, c, d return a vector Factor times longer
5932// with Factor-1 undef's between elements. Ex:
5933// a, undef, b, undef, c, undef, d, undef (Factor=2, Index=0)
5934// undef, a, undef, b, undef, c, undef, d (Factor=2, Index=1)
5935static SDValue getWideningSpread(SDValue V, unsigned Factor, unsigned Index,
5936 const SDLoc &DL, SelectionDAG &DAG) {
5937
5938 MVT VT = V.getSimpleValueType();
5939 unsigned EltBits = VT.getScalarSizeInBits();
5941 V = DAG.getBitcast(VT.changeTypeToInteger(), V);
5942
5943 MVT WideVT = MVT::getVectorVT(MVT::getIntegerVT(EltBits * Factor), EC);
5944
5945 SDValue Result = DAG.getNode(ISD::ZERO_EXTEND, DL, WideVT, V);
5946 // TODO: On rv32, the constant becomes a splat_vector_parts which does not
5947 // allow the SHL to fold away if Index is 0.
5948 if (Index != 0)
5949 Result = DAG.getNode(ISD::SHL, DL, WideVT, Result,
5950 DAG.getConstant(EltBits * Index, DL, WideVT));
5951 // Make sure to use original element type
5953 EC.multiplyCoefficientBy(Factor));
5954 return DAG.getBitcast(ResultVT, Result);
5955}
5956
5957// Given two input vectors of <[vscale x ]n x ty>, use vwaddu.vv and vwmaccu.vx
5958// to create an interleaved vector of <[vscale x] n*2 x ty>.
5959// This requires that the size of ty is less than the subtarget's maximum ELEN.
5961 const SDLoc &DL, SelectionDAG &DAG,
5962 const RISCVSubtarget &Subtarget) {
5963
5964 // FIXME: Not only does this optimize the code, it fixes some correctness
5965 // issues because MIR does not have freeze.
5966 if (EvenV.isUndef())
5967 return getWideningSpread(OddV, 2, 1, DL, DAG);
5968 if (OddV.isUndef())
5969 return getWideningSpread(EvenV, 2, 0, DL, DAG);
5970
5971 MVT VecVT = EvenV.getSimpleValueType();
5972 MVT VecContainerVT = VecVT; // <vscale x n x ty>
5973 // Convert fixed vectors to scalable if needed
5974 if (VecContainerVT.isFixedLengthVector()) {
5975 VecContainerVT = getContainerForFixedLengthVector(VecVT, Subtarget);
5976 EvenV = convertToScalableVector(VecContainerVT, EvenV, DAG, Subtarget);
5977 OddV = convertToScalableVector(VecContainerVT, OddV, DAG, Subtarget);
5978 }
5979
5980 assert(VecVT.getScalarSizeInBits() < Subtarget.getELen());
5981
5982 // We're working with a vector of the same size as the resulting
5983 // interleaved vector, but with half the number of elements and
5984 // twice the SEW (Hence the restriction on not using the maximum
5985 // ELEN)
5986 MVT WideVT =
5988 VecVT.getVectorElementCount());
5989 MVT WideContainerVT = WideVT; // <vscale x n x ty*2>
5990 if (WideContainerVT.isFixedLengthVector())
5991 WideContainerVT = getContainerForFixedLengthVector(WideVT, Subtarget);
5992
5993 // Bitcast the input vectors to integers in case they are FP
5994 VecContainerVT = VecContainerVT.changeTypeToInteger();
5995 EvenV = DAG.getBitcast(VecContainerVT, EvenV);
5996 OddV = DAG.getBitcast(VecContainerVT, OddV);
5997
5998 auto [Mask, VL] = getDefaultVLOps(VecVT, VecContainerVT, DL, DAG, Subtarget);
5999 SDValue Passthru = DAG.getUNDEF(WideContainerVT);
6000
6001 SDValue Interleaved;
6002 if (Subtarget.hasStdExtZvbb()) {
6003 // Interleaved = (OddV << VecVT.getScalarSizeInBits()) + EvenV.
6004 SDValue OffsetVec =
6005 DAG.getConstant(VecVT.getScalarSizeInBits(), DL, VecContainerVT);
6006 Interleaved = DAG.getNode(RISCVISD::VWSLL_VL, DL, WideContainerVT, OddV,
6007 OffsetVec, Passthru, Mask, VL);
6008 Interleaved = DAG.getNode(RISCVISD::VWADDU_W_VL, DL, WideContainerVT,
6009 Interleaved, EvenV, Passthru, Mask, VL);
6010 } else {
6011 // FIXME: We should freeze the odd vector here. We already handled the case
6012 // of provably undef/poison above.
6013
6014 // Widen EvenV and OddV with 0s and add one copy of OddV to EvenV with
6015 // vwaddu.vv
6016 Interleaved = DAG.getNode(RISCVISD::VWADDU_VL, DL, WideContainerVT, EvenV,
6017 OddV, Passthru, Mask, VL);
6018
6019 // Then get OddV * by 2^(VecVT.getScalarSizeInBits() - 1)
6020 SDValue AllOnesVec = DAG.getSplatVector(
6021 VecContainerVT, DL, DAG.getAllOnesConstant(DL, Subtarget.getXLenVT()));
6022 SDValue OddsMul = DAG.getNode(RISCVISD::VWMULU_VL, DL, WideContainerVT,
6023 OddV, AllOnesVec, Passthru, Mask, VL);
6024
6025 // Add the two together so we get
6026 // (OddV * 0xff...ff) + (OddV + EvenV)
6027 // = (OddV * 0x100...00) + EvenV
6028 // = (OddV << VecVT.getScalarSizeInBits()) + EvenV
6029 // Note the ADD_VL and VLMULU_VL should get selected as vwmaccu.vx
6030 Interleaved = DAG.getNode(RISCVISD::ADD_VL, DL, WideContainerVT,
6031 Interleaved, OddsMul, Passthru, Mask, VL);
6032 }
6033
6034 // Bitcast from <vscale x n * ty*2> to <vscale x 2*n x ty>
6035 MVT ResultContainerVT = MVT::getVectorVT(
6036 VecVT.getVectorElementType(), // Make sure to use original type
6037 VecContainerVT.getVectorElementCount().multiplyCoefficientBy(2));
6038 Interleaved = DAG.getBitcast(ResultContainerVT, Interleaved);
6039
6040 // Convert back to a fixed vector if needed
6041 MVT ResultVT =
6044 if (ResultVT.isFixedLengthVector())
6045 Interleaved =
6046 convertFromScalableVector(ResultVT, Interleaved, DAG, Subtarget);
6047
6048 return Interleaved;
6049}
6050
6051// If we have a vector of bits that we want to reverse, we can use a vbrev on a
6052// larger element type, e.g. v32i1 can be reversed with a v1i32 bitreverse.
6054 SelectionDAG &DAG,
6055 const RISCVSubtarget &Subtarget) {
6056 SDLoc DL(SVN);
6057 MVT VT = SVN->getSimpleValueType(0);
6058 SDValue V = SVN->getOperand(0);
6059 unsigned NumElts = VT.getVectorNumElements();
6060
6061 assert(VT.getVectorElementType() == MVT::i1);
6062
6064 SVN->getMask().size()) ||
6065 !SVN->getOperand(1).isUndef())
6066 return SDValue();
6067
6068 unsigned ViaEltSize = std::max((uint64_t)8, PowerOf2Ceil(NumElts));
6069 EVT ViaVT = EVT::getVectorVT(
6070 *DAG.getContext(), EVT::getIntegerVT(*DAG.getContext(), ViaEltSize), 1);
6071 EVT ViaBitVT =
6072 EVT::getVectorVT(*DAG.getContext(), MVT::i1, ViaVT.getScalarSizeInBits());
6073
6074 // If we don't have zvbb or the larger element type > ELEN, the operation will
6075 // be illegal.
6077 ViaVT) ||
6078 !Subtarget.getTargetLowering()->isTypeLegal(ViaBitVT))
6079 return SDValue();
6080
6081 // If the bit vector doesn't fit exactly into the larger element type, we need
6082 // to insert it into the larger vector and then shift up the reversed bits
6083 // afterwards to get rid of the gap introduced.
6084 if (ViaEltSize > NumElts)
6085 V = DAG.getInsertSubvector(DL, DAG.getUNDEF(ViaBitVT), V, 0);
6086
6087 SDValue Res =
6088 DAG.getNode(ISD::BITREVERSE, DL, ViaVT, DAG.getBitcast(ViaVT, V));
6089
6090 // Shift up the reversed bits if the vector didn't exactly fit into the larger
6091 // element type.
6092 if (ViaEltSize > NumElts)
6093 Res = DAG.getNode(ISD::SRL, DL, ViaVT, Res,
6094 DAG.getConstant(ViaEltSize - NumElts, DL, ViaVT));
6095
6096 Res = DAG.getBitcast(ViaBitVT, Res);
6097
6098 if (ViaEltSize > NumElts)
6099 Res = DAG.getExtractSubvector(DL, VT, Res, 0);
6100 return Res;
6101}
6102
6104 const RISCVSubtarget &Subtarget,
6105 MVT &RotateVT, unsigned &RotateAmt) {
6106 unsigned NumElts = VT.getVectorNumElements();
6107 unsigned EltSizeInBits = VT.getScalarSizeInBits();
6108 unsigned NumSubElts;
6109 if (!ShuffleVectorInst::isBitRotateMask(Mask, EltSizeInBits, 2,
6110 NumElts, NumSubElts, RotateAmt))
6111 return false;
6112 RotateVT = MVT::getVectorVT(MVT::getIntegerVT(EltSizeInBits * NumSubElts),
6113 NumElts / NumSubElts);
6114
6115 // We might have a RotateVT that isn't legal, e.g. v4i64 on zve32x.
6116 return Subtarget.getTargetLowering()->isTypeLegal(RotateVT);
6117}
6118
6119// Given a shuffle mask like <3, 0, 1, 2, 7, 4, 5, 6> for v8i8, we can
6120// reinterpret it as a v2i32 and rotate it right by 8 instead. We can lower this
6121// as a vror.vi if we have Zvkb, or otherwise as a vsll, vsrl and vor.
6123 SelectionDAG &DAG,
6124 const RISCVSubtarget &Subtarget) {
6125 SDLoc DL(SVN);
6126
6127 EVT VT = SVN->getValueType(0);
6128 unsigned RotateAmt;
6129 MVT RotateVT;
6130 if (!isLegalBitRotate(SVN->getMask(), VT, Subtarget, RotateVT, RotateAmt))
6131 return SDValue();
6132
6133 SDValue Op = DAG.getBitcast(RotateVT, SVN->getOperand(0));
6134
6135 SDValue Rotate;
6136 // A rotate of an i16 by 8 bits either direction is equivalent to a byteswap,
6137 // so canonicalize to vrev8.
6138 if (RotateVT.getScalarType() == MVT::i16 && RotateAmt == 8)
6139 Rotate = DAG.getNode(ISD::BSWAP, DL, RotateVT, Op);
6140 else
6141 Rotate = DAG.getNode(ISD::ROTL, DL, RotateVT, Op,
6142 DAG.getConstant(RotateAmt, DL, RotateVT));
6143
6144 return DAG.getBitcast(VT, Rotate);
6145}
6146
6147// If compiling with an exactly known VLEN, see if we can split a
6148// shuffle on m2 or larger into a small number of m1 sized shuffles
6149// which write each destination registers exactly once.
6151 SelectionDAG &DAG,
6152 const RISCVSubtarget &Subtarget) {
6153 SDLoc DL(SVN);
6154 MVT VT = SVN->getSimpleValueType(0);
6155 SDValue V1 = SVN->getOperand(0);
6156 SDValue V2 = SVN->getOperand(1);
6157 ArrayRef<int> Mask = SVN->getMask();
6158
6159 // If we don't know exact data layout, not much we can do. If this
6160 // is already m1 or smaller, no point in splitting further.
6161 const auto VLen = Subtarget.getRealVLen();
6162 if (!VLen || VT.getSizeInBits().getFixedValue() <= *VLen)
6163 return SDValue();
6164
6165 // Avoid picking up bitrotate patterns which we have a linear-in-lmul
6166 // expansion for.
6167 unsigned RotateAmt;
6168 MVT RotateVT;
6169 if (isLegalBitRotate(Mask, VT, Subtarget, RotateVT, RotateAmt))
6170 return SDValue();
6171
6172 MVT ElemVT = VT.getVectorElementType();
6173 unsigned ElemsPerVReg = *VLen / ElemVT.getFixedSizeInBits();
6174
6175 EVT ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
6176 MVT OneRegVT = MVT::getVectorVT(ElemVT, ElemsPerVReg);
6177 MVT M1VT = getContainerForFixedLengthVector(OneRegVT, Subtarget);
6178 assert(M1VT == RISCVTargetLowering::getM1VT(M1VT));
6179 unsigned NumOpElts = M1VT.getVectorMinNumElements();
6180 unsigned NumElts = ContainerVT.getVectorMinNumElements();
6181 unsigned NumOfSrcRegs = NumElts / NumOpElts;
6182 unsigned NumOfDestRegs = NumElts / NumOpElts;
6183 // The following semantically builds up a fixed length concat_vector
6184 // of the component shuffle_vectors. We eagerly lower to scalable here
6185 // to avoid DAG combining it back to a large shuffle_vector again.
6186 V1 = convertToScalableVector(ContainerVT, V1, DAG, Subtarget);
6187 V2 = convertToScalableVector(ContainerVT, V2, DAG, Subtarget);
6189 Operands;
6191 Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs,
6192 [&]() { Operands.emplace_back(); },
6193 [&](ArrayRef<int> SrcSubMask, unsigned SrcVecIdx, unsigned DstVecIdx) {
6194 Operands.emplace_back().emplace_back(SrcVecIdx, UINT_MAX,
6195 SmallVector<int>(SrcSubMask));
6196 },
6197 [&](ArrayRef<int> SrcSubMask, unsigned Idx1, unsigned Idx2, bool NewReg) {
6198 if (NewReg)
6199 Operands.emplace_back();
6200 Operands.back().emplace_back(Idx1, Idx2, SmallVector<int>(SrcSubMask));
6201 });
6202 assert(Operands.size() == NumOfDestRegs && "Whole vector must be processed");
6203 // Note: check that we do not emit too many shuffles here to prevent code
6204 // size explosion.
6205 // TODO: investigate, if it can be improved by extra analysis of the masks to
6206 // check if the code is more profitable.
6207 unsigned NumShuffles = std::accumulate(
6208 Operands.begin(), Operands.end(), 0u,
6209 [&](unsigned N,
6210 ArrayRef<std::tuple<unsigned, unsigned, SmallVector<int>>> Data) {
6211 if (Data.empty())
6212 return N;
6213 N += Data.size();
6214 for (const auto &P : Data) {
6215 unsigned Idx2 = std::get<1>(P);
6216 ArrayRef<int> Mask = std::get<2>(P);
6217 if (Idx2 != UINT_MAX)
6218 ++N;
6219 else if (ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
6220 --N;
6221 }
6222 return N;
6223 });
6224 if ((NumOfDestRegs > 2 && NumShuffles > NumOfDestRegs) ||
6225 (NumOfDestRegs <= 2 && NumShuffles >= 4))
6226 return SDValue();
6227 auto ExtractValue = [&, &DAG = DAG](SDValue SrcVec, unsigned ExtractIdx) {
6228 SDValue SubVec = DAG.getExtractSubvector(DL, M1VT, SrcVec, ExtractIdx);
6229 SubVec = convertFromScalableVector(OneRegVT, SubVec, DAG, Subtarget);
6230 return SubVec;
6231 };
6232 auto PerformShuffle = [&, &DAG = DAG](SDValue SubVec1, SDValue SubVec2,
6234 SDValue SubVec = DAG.getVectorShuffle(OneRegVT, DL, SubVec1, SubVec2, Mask);
6235 return SubVec;
6236 };
6237 SDValue Vec = DAG.getUNDEF(ContainerVT);
6238 for (auto [I, Data] : enumerate(Operands)) {
6239 if (Data.empty())
6240 continue;
6242 for (unsigned I : seq<unsigned>(Data.size())) {
6243 const auto &[Idx1, Idx2, _] = Data[I];
6244 // If the shuffle contains permutation of odd number of elements,
6245 // Idx1 might be used already in the first iteration.
6246 //
6247 // Idx1 = shuffle Idx1, Idx2
6248 // Idx1 = shuffle Idx1, Idx3
6249 SDValue &V = Values.try_emplace(Idx1).first->getSecond();
6250 if (!V)
6251 V = ExtractValue(Idx1 >= NumOfSrcRegs ? V2 : V1,
6252 (Idx1 % NumOfSrcRegs) * NumOpElts);
6253 if (Idx2 != UINT_MAX) {
6254 SDValue &V = Values.try_emplace(Idx2).first->getSecond();
6255 if (!V)
6256 V = ExtractValue(Idx2 >= NumOfSrcRegs ? V2 : V1,
6257 (Idx2 % NumOfSrcRegs) * NumOpElts);
6258 }
6259 }
6260 SDValue V;
6261 for (const auto &[Idx1, Idx2, Mask] : Data) {
6262 SDValue V1 = Values.at(Idx1);
6263 SDValue V2 = Idx2 == UINT_MAX ? V1 : Values.at(Idx2);
6264 V = PerformShuffle(V1, V2, Mask);
6265 Values[Idx1] = V;
6266 }
6267
6268 unsigned InsertIdx = I * NumOpElts;
6269 V = convertToScalableVector(M1VT, V, DAG, Subtarget);
6270 Vec = DAG.getInsertSubvector(DL, Vec, V, InsertIdx);
6271 }
6272 return convertFromScalableVector(VT, Vec, DAG, Subtarget);
6273}
6274
6275// Matches a subset of compress masks with a contiguous prefix of output
6276// elements. This could be extended to allow gaps by deciding which
6277// source elements to spuriously demand.
6279 int Last = -1;
6280 bool SawUndef = false;
6281 for (const auto &[Idx, M] : enumerate(Mask)) {
6282 if (M == -1) {
6283 SawUndef = true;
6284 continue;
6285 }
6286 if (SawUndef)
6287 return false;
6288 if (Idx > (unsigned)M)
6289 return false;
6290 if (M <= Last)
6291 return false;
6292 Last = M;
6293 }
6294 return true;
6295}
6296
6297/// Given a shuffle where the indices are disjoint between the two sources,
6298/// e.g.:
6299///
6300/// t2:v4i8 = vector_shuffle t0:v4i8, t1:v4i8, <2, 7, 1, 4>
6301///
6302/// Merge the two sources into one and do a single source shuffle:
6303///
6304/// t2:v4i8 = vselect t1:v4i8, t0:v4i8, <0, 1, 0, 1>
6305/// t3:v4i8 = vector_shuffle t2:v4i8, undef, <2, 3, 1, 0>
6306///
6307/// A vselect will either be merged into a masked instruction or be lowered as a
6308/// vmerge.vvm, which is cheaper than a vrgather.vv.
6310 SelectionDAG &DAG,
6311 const RISCVSubtarget &Subtarget) {
6312 MVT VT = SVN->getSimpleValueType(0);
6313 MVT XLenVT = Subtarget.getXLenVT();
6314 SDLoc DL(SVN);
6315
6316 const ArrayRef<int> Mask = SVN->getMask();
6317
6318 // Work out which source each lane will come from.
6319 SmallVector<int, 16> Srcs(Mask.size(), -1);
6320
6321 for (int Idx : Mask) {
6322 if (Idx == -1)
6323 continue;
6324 unsigned SrcIdx = Idx % Mask.size();
6325 int Src = (uint32_t)Idx < Mask.size() ? 0 : 1;
6326 if (Srcs[SrcIdx] == -1)
6327 // Mark this source as using this lane.
6328 Srcs[SrcIdx] = Src;
6329 else if (Srcs[SrcIdx] != Src)
6330 // The other source is using this lane: not disjoint.
6331 return SDValue();
6332 }
6333
6334 SmallVector<SDValue> SelectMaskVals;
6335 for (int Lane : Srcs) {
6336 if (Lane == -1)
6337 SelectMaskVals.push_back(DAG.getUNDEF(XLenVT));
6338 else
6339 SelectMaskVals.push_back(DAG.getConstant(Lane ? 0 : 1, DL, XLenVT));
6340 }
6341 MVT MaskVT = VT.changeVectorElementType(MVT::i1);
6342 SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, SelectMaskVals);
6343 SDValue Select = DAG.getNode(ISD::VSELECT, DL, VT, SelectMask,
6344 SVN->getOperand(0), SVN->getOperand(1));
6345
6346 // Move all indices relative to the first source.
6347 SmallVector<int> NewMask(Mask.size());
6348 for (unsigned I = 0; I < Mask.size(); I++) {
6349 if (Mask[I] == -1)
6350 NewMask[I] = -1;
6351 else
6352 NewMask[I] = Mask[I] % Mask.size();
6353 }
6354
6355 return DAG.getVectorShuffle(VT, DL, Select, DAG.getUNDEF(VT), NewMask);
6356}
6357
6358/// Is this mask local (i.e. elements only move within their local span), and
6359/// repeating (that is, the same rearrangement is being done within each span)?
6360static bool isLocalRepeatingShuffle(ArrayRef<int> Mask, int Span) {
6361 // Require a prefix from the original mask until the consumer code
6362 // is adjusted to rewrite the mask instead of just taking a prefix.
6363 for (auto [I, M] : enumerate(Mask)) {
6364 if (M == -1)
6365 continue;
6366 if ((M / Span) != (int)(I / Span))
6367 return false;
6368 int SpanIdx = I % Span;
6369 int Expected = M % Span;
6370 if (Mask[SpanIdx] != Expected)
6371 return false;
6372 }
6373 return true;
6374}
6375
6376/// Is this mask only using elements from the first span of the input?
6377static bool isLowSourceShuffle(ArrayRef<int> Mask, int Span) {
6378 return all_of(Mask, [&](const auto &Idx) { return Idx == -1 || Idx < Span; });
6379}
6380
6381/// Return true for a mask which performs an arbitrary shuffle within the first
6382/// span, and then repeats that same result across all remaining spans. Note
6383/// that this doesn't check if all the inputs come from a single span!
6384static bool isSpanSplatShuffle(ArrayRef<int> Mask, int Span) {
6385 // Require a prefix from the original mask until the consumer code
6386 // is adjusted to rewrite the mask instead of just taking a prefix.
6387 for (auto [I, M] : enumerate(Mask)) {
6388 if (M == -1)
6389 continue;
6390 int SpanIdx = I % Span;
6391 if (Mask[SpanIdx] != M)
6392 return false;
6393 }
6394 return true;
6395}
6396
6397/// Try to widen element type to get a new mask value for a better permutation
6398/// sequence. This doesn't try to inspect the widened mask for profitability;
6399/// we speculate the widened form is equal or better. This has the effect of
6400/// reducing mask constant sizes - allowing cheaper materialization sequences
6401/// - and index sequence sizes - reducing register pressure and materialization
6402/// cost, at the cost of (possibly) an extra VTYPE toggle.
6404 SDLoc DL(Op);
6405 MVT VT = Op.getSimpleValueType();
6406 MVT ScalarVT = VT.getVectorElementType();
6407 unsigned ElementSize = ScalarVT.getFixedSizeInBits();
6408 SDValue V0 = Op.getOperand(0);
6409 SDValue V1 = Op.getOperand(1);
6410 ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op)->getMask();
6411
6412 // Avoid wasted work leading to isTypeLegal check failing below
6413 if (ElementSize > 32)
6414 return SDValue();
6415
6416 SmallVector<int, 8> NewMask;
6417 if (!widenShuffleMaskElts(Mask, NewMask))
6418 return SDValue();
6419
6420 MVT NewEltVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(ElementSize * 2)
6421 : MVT::getIntegerVT(ElementSize * 2);
6422 MVT NewVT = MVT::getVectorVT(NewEltVT, VT.getVectorNumElements() / 2);
6423 if (!DAG.getTargetLoweringInfo().isTypeLegal(NewVT))
6424 return SDValue();
6425 V0 = DAG.getBitcast(NewVT, V0);
6426 V1 = DAG.getBitcast(NewVT, V1);
6427 return DAG.getBitcast(VT, DAG.getVectorShuffle(NewVT, DL, V0, V1, NewMask));
6428}
6429
6430// Match an interleave shuffle that forms a P-extension packed zip:
6431// <a0, b0, a1, b1, ...> -> zip*p/wzip*p
6433 const RISCVSubtarget &Subtarget,
6434 SelectionDAG &DAG) {
6435 SDValue V1 = SVN->getOperand(0);
6436 SDValue V2 = SVN->getOperand(1);
6437 SDLoc DL(SVN);
6438 MVT VT = SVN->getSimpleValueType(0);
6439 unsigned NumElts = VT.getVectorNumElements();
6440 ArrayRef<int> Mask = SVN->getMask();
6441
6442 if (VT != MVT::v8i8 && VT != MVT::v4i16)
6443 return SDValue();
6444
6445 SmallVector<unsigned, 2> StartIndexes;
6446 if (!V2.isUndef() &&
6447 ShuffleVectorInst::isInterleaveMask(Mask, 2, NumElts * 2, StartIndexes)) {
6448 unsigned EvenSrc = StartIndexes[0];
6449 unsigned OddSrc = StartIndexes[1];
6450 if (EvenSrc == 0 && OddSrc == NumElts) {
6451 if (Subtarget.is64Bit())
6452 return DAG.getNode(RISCVISD::PZIP, DL, VT, V1, V2);
6453 EVT HalfVT = VT.getHalfNumVectorElementsVT();
6454 V1 = DAG.getExtractSubvector(DL, HalfVT, V1, 0);
6455 V2 = DAG.getExtractSubvector(DL, HalfVT, V2, 0);
6456 return DAG.getNode(RISCVISD::PWZIP, DL, VT, V1, V2);
6457 }
6458 if (EvenSrc == NumElts && OddSrc == 0) {
6459 if (Subtarget.is64Bit())
6460 return DAG.getNode(RISCVISD::PZIP, DL, VT, V2, V1);
6461 EVT HalfVT = VT.getHalfNumVectorElementsVT();
6462 V1 = DAG.getExtractSubvector(DL, HalfVT, V1, 0);
6463 V2 = DAG.getExtractSubvector(DL, HalfVT, V2, 0);
6464 return DAG.getNode(RISCVISD::PWZIP, DL, VT, V2, V1);
6465 }
6466 }
6467
6468 return SDValue();
6469}
6470
6471// Match a deinterleave shuffle that forms a P-extension packed unzip:
6472// <a0, a2, ..., b0, b2, ...> -> unzip*p
6473// <a1, a3, ..., b1, b3, ...> -> unzip*hp
6475 SelectionDAG &DAG, bool IsRV64) {
6476 MVT VT = SVN->getSimpleValueType(0);
6477 if (!IsRV64 || (VT != MVT::v8i8 && VT != MVT::v4i16))
6478 return SDValue();
6479
6480 SDValue V1 = SVN->getOperand(0);
6481 SDValue V2 = SVN->getOperand(1);
6482 SDLoc DL(SVN);
6483 ArrayRef<int> Mask = SVN->getMask();
6484
6485 unsigned Index = 0;
6487 return SDValue();
6488
6489 unsigned Opc = Index == 0 ? RISCVISD::PUNZIPE : RISCVISD::PUNZIPO;
6490 return DAG.getNode(Opc, DL, VT, V1, V2);
6491}
6492
6493// Match the packed zero-extend shuffle mask <0, N, 2, N+2, ...>: even result
6494// lanes keep operand 0's even lanes and odd result lanes come from operand 1.
6495// The odd lanes may select any element of operand 1, which is looser than a
6496// strict pair-even mask; DAGCombiner::XformToShuffleWithZero forms exactly this
6497// from a packed zero-extend `and`, leaving each zeroed lane at its own
6498// position, and lowerVECTOR_SHUFFLEAsPPair then forms the PPAIRE. Undef lanes
6499// always match.
6501 unsigned NumElts = Mask.size();
6502 if (NumElts % 2 != 0)
6503 return false;
6504 for (unsigned I = 0; I != NumElts / 2; ++I)
6505 if ((Mask[2 * I] >= 0 && Mask[2 * I] != (int)(2 * I)) ||
6506 (Mask[2 * I + 1] >= 0 && Mask[2 * I + 1] < (int)NumElts))
6507 return false;
6508 return true;
6509}
6510
6511// Match a legalized deinterleave shuffle on two RV32 vector halves and lower
6512// it to an RV32 P narrowing shift on the concatenated source.
6513static SDValue
6515 const RISCVSubtarget &Subtarget,
6516 SelectionDAG &DAG) {
6517 MVT VT = SVN->getSimpleValueType(0);
6518 if (Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16))
6519 return SDValue();
6520
6521 SDValue V1 = SVN->getOperand(0);
6522 SDValue V2 = SVN->getOperand(1);
6523 SDLoc DL(SVN);
6524 unsigned NumElts = VT.getVectorNumElements();
6525
6526 SDValue Src = foldConcatVector(V1, V2);
6527 if (!Src) {
6528 MVT SrcVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
6529 Src = DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, V1, V2);
6530 }
6531
6532 // The source vector should be twice the size.
6533 if (Src.getValueType().getVectorNumElements() != 2 * NumElts)
6534 return SDValue();
6535
6536 unsigned Index = 0;
6538 return SDValue();
6539
6540 unsigned EltBits = VT.getVectorElementType().getSizeInBits();
6541 return DAG.getNode(RISCVISD::PNSRL, DL, VT, Src,
6542 DAG.getConstant(Index * EltBits, DL, MVT::i32));
6543}
6544
6545// Match a strided-interleave shuffle that forms a P-extension packed pair:
6546// <a0, b0, a2, b2, ...> -> ppaire.*
6547// <a0, b1, a2, b3, ...> -> ppaireo.*
6548// <a1, b0, a3, b2, ...> -> ppairoe.*
6549// <a1, b1, a3, b3, ...> -> ppairo.*
6551 SelectionDAG &DAG) {
6552 MVT VT = SVN->getSimpleValueType(0);
6553 if (VT != MVT::v4i8 && VT != MVT::v8i8 && VT != MVT::v4i16)
6554 return SDValue();
6555
6556 SDValue V1 = SVN->getOperand(0);
6557 SDValue V2 = SVN->getOperand(1);
6558 SDLoc DL(SVN);
6559 unsigned NumElts = VT.getVectorNumElements();
6560 ArrayRef<int> Mask = SVN->getMask();
6561
6562 // A splat operand's lanes are all equal, so a lane selecting from it matches
6563 // any of its positions. This covers the zero operand XformToShuffleWithZero
6564 // forms for a packed zero-extend, which keeps each zeroed lane at its own
6565 // position rather than the strided one.
6566 bool V1IsSplat = DAG.isSplatValue(V1);
6567 bool V2IsSplat = DAG.isSplatValue(V2);
6568
6569 // Walk the mask once, tracking the operand feeding the destination's even
6570 // lanes (index 0) and the operand feeding its odd lanes (index 1) — either
6571 // may turn out to be V1 or V2 — along with whether each pulls the even or
6572 // odd element out of its pair. All even (resp. odd) lanes must agree on
6573 // both the operand and the parity used; a splat operand's lanes are all
6574 // equal so it never constrains the parity.
6575 SDValue Src[2];
6576 std::optional<bool> Parity[2];
6577 for (unsigned I = 0; I != NumElts; ++I) {
6578 int M = Mask[I];
6579 if (M < 0)
6580 continue;
6581 unsigned Lane = I % 2;
6582 bool FromV1 = (unsigned)M < NumElts;
6583 SDValue Cand = FromV1 ? V1 : V2;
6584 unsigned Local = (unsigned)M % NumElts;
6585 if (!Src[Lane])
6586 Src[Lane] = Cand;
6587 else if (Src[Lane] != Cand)
6588 return SDValue();
6589
6590 // Splats don't constrain parity.
6591 if (FromV1 ? V1IsSplat : V2IsSplat)
6592 continue;
6593
6594 // The index must be from the even/odd element of its pair.
6595 if (Local / 2 != I / 2)
6596 return SDValue();
6597
6598 bool P = Local % 2;
6599 if (!Parity[Lane])
6600 Parity[Lane] = P;
6601 else if (*Parity[Lane] != P)
6602 return SDValue();
6603 }
6604
6605 // Make sure we have a source for both lanes.
6606 if (!Src[0] || !Src[1])
6607 return SDValue();
6608
6609 bool EvenIsOdd = Parity[0].value_or(false);
6610 bool OddIsOdd = Parity[1].value_or(false);
6611 unsigned Opc;
6612 if (!EvenIsOdd && !OddIsOdd)
6613 Opc = RISCVISD::PPAIRE;
6614 else if (EvenIsOdd && OddIsOdd)
6615 Opc = RISCVISD::PPAIRO;
6616 else if (!EvenIsOdd && OddIsOdd)
6617 Opc = RISCVISD::PPAIREO;
6618 else
6619 Opc = RISCVISD::PPAIROE;
6620
6621 return DAG.getNode(Opc, DL, VT, Src[0], Src[1]);
6622}
6623
6624SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
6625 SelectionDAG &DAG) const {
6626 SDValue V1 = Op.getOperand(0);
6627 SDValue V2 = Op.getOperand(1);
6628 SDLoc DL(Op);
6629 MVT XLenVT = Subtarget.getXLenVT();
6630 MVT VT = Op.getSimpleValueType();
6631 unsigned NumElts = VT.getVectorNumElements();
6632 ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op.getNode());
6633
6634 // Select RVP-specific packed shuffles before falling back to the generic
6635 // fixed/scalable-vector lowering below.
6636 if (Subtarget.hasStdExtP() && !Subtarget.hasVInstructions()) {
6637 ArrayRef<int> Mask = SVN->getMask();
6638
6639 // Select an element reverse shuffle to VECTOR_REVERSE. The tablegen
6640 // patterns select rev8/rev16/ppairoe.* from VECTOR_REVERSE.
6641 // Reverse of the low L lanes, higher lanes poison. L == NumElts is a plain
6642 // reverse; L == NumElts/2 is a widened RV64 v4i8/v2i16 reverse.
6643 auto IsLowReverse = [&](unsigned L) {
6644 return V2.isUndef() &&
6645 ShuffleVectorInst::isReverseMask(Mask.take_front(L), L) &&
6646 all_of(Mask.drop_front(L), [](int M) { return M < 0; });
6647 };
6648 if (IsLowReverse(NumElts))
6649 return DAG.getNode(ISD::VECTOR_REVERSE, DL, VT, V1);
6650 if (Subtarget.is64Bit() && VT == MVT::v4i16 && IsLowReverse(/*L=*/2))
6651 return DAG.getNode(RISCVISD::PPAIROE_H, DL, VT, V1, V1);
6652 // Widened: reversing sends the low-half lanes to the top half, so shift
6653 // them back down by half the register. Only the 64-bit packed types are
6654 // legal here, so the register is XLen (i64).
6655 if (Subtarget.is64Bit() && VT.getSizeInBits() == 64 &&
6656 IsLowReverse(NumElts / 2)) {
6657 SDValue Rev = DAG.getBitcast(
6658 MVT::i64, DAG.getNode(ISD::VECTOR_REVERSE, DL, VT, V1));
6659 SDValue Srl =
6660 DAG.getNode(ISD::SRL, DL, MVT::i64, Rev,
6661 DAG.getConstant(VT.getSizeInBits() / 2, DL, MVT::i64));
6662 return DAG.getBitcast(VT, Srl);
6663 }
6664
6665 if (SDValue V = lowerVECTOR_SHUFFLEAsPUnzip(SVN, DAG, Subtarget.is64Bit()))
6666 return V;
6667 if (SDValue V = lowerVECTOR_SHUFFLEAsPZip(SVN, Subtarget, DAG))
6668 return V;
6669 if (SDValue V =
6670 lowerVECTOR_SHUFFLEAsRV32PNarrowingShift(SVN, Subtarget, DAG))
6671 return V;
6672 if (SDValue V = lowerVECTOR_SHUFFLEAsPPair(SVN, DAG))
6673 return V;
6674 return SDValue();
6675 }
6676
6677 if (VT.getVectorElementType() == MVT::i1) {
6678 // Lower to a vror.vi of a larger element type if possible before we promote
6679 // i1s to i8s.
6680 if (SDValue V = lowerVECTOR_SHUFFLEAsRotate(SVN, DAG, Subtarget))
6681 return V;
6682 if (SDValue V = lowerBitreverseShuffle(SVN, DAG, Subtarget))
6683 return V;
6684
6685 // Promote i1 shuffle to i8 shuffle.
6686 MVT WidenVT = MVT::getVectorVT(MVT::i8, VT.getVectorElementCount());
6687 V1 = DAG.getNode(ISD::ZERO_EXTEND, DL, WidenVT, V1);
6688 V2 = V2.isUndef() ? DAG.getUNDEF(WidenVT)
6689 : DAG.getNode(ISD::ZERO_EXTEND, DL, WidenVT, V2);
6690 SDValue Shuffled = DAG.getVectorShuffle(WidenVT, DL, V1, V2, SVN->getMask());
6691 return DAG.getSetCC(DL, VT, Shuffled, DAG.getConstant(0, DL, WidenVT),
6692 ISD::SETNE);
6693 }
6694
6695 MVT ContainerVT = getContainerForFixedLengthVector(VT);
6696
6697 // Store the return value in a single variable instead of structured bindings
6698 // so that we can pass it to GetSlide below, which cannot capture structured
6699 // bindings until C++20.
6700 auto TrueMaskVL = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
6701 auto [TrueMask, VL] = TrueMaskVL;
6702
6703 if (SVN->isSplat()) {
6704 const int Lane = SVN->getSplatIndex();
6705 if (Lane >= 0) {
6706 MVT SVT = VT.getVectorElementType();
6707
6708 // Turn splatted vector load into a strided load with an X0 stride.
6709 SDValue V = V1;
6710 // Peek through CONCAT_VECTORS as VectorCombine can concat a vector
6711 // with undef.
6712 // FIXME: Peek through INSERT_SUBVECTOR, EXTRACT_SUBVECTOR, bitcasts?
6713 int Offset = Lane;
6714 if (V.getOpcode() == ISD::CONCAT_VECTORS) {
6715 int OpElements =
6716 V.getOperand(0).getSimpleValueType().getVectorNumElements();
6717 V = V.getOperand(Offset / OpElements);
6718 Offset %= OpElements;
6719 }
6720
6721 // We need to ensure the load isn't atomic or volatile.
6722 if (ISD::isNormalLoad(V.getNode()) && cast<LoadSDNode>(V)->isSimple()) {
6723 auto *Ld = cast<LoadSDNode>(V);
6724 Offset *= SVT.getStoreSize();
6725 SDValue NewAddr = DAG.getMemBasePlusOffset(
6726 Ld->getBasePtr(), TypeSize::getFixed(Offset), DL);
6727
6728 // If this is SEW=64 on RV32, use a strided load with a stride of x0.
6729 if (SVT.isInteger() && SVT.bitsGT(XLenVT)) {
6730 SDVTList VTs = DAG.getVTList({ContainerVT, MVT::Other});
6731 SDValue IntID =
6732 DAG.getTargetConstant(Intrinsic::riscv_vlse, DL, XLenVT);
6733 SDValue Ops[] = {Ld->getChain(),
6734 IntID,
6735 DAG.getUNDEF(ContainerVT),
6736 NewAddr,
6737 DAG.getRegister(RISCV::X0, XLenVT),
6738 VL};
6739 SDValue NewLoad = DAG.getMemIntrinsicNode(
6740 ISD::INTRINSIC_W_CHAIN, DL, VTs, Ops, SVT,
6742 Ld->getMemOperand(), Offset, SVT.getStoreSize()));
6743 DAG.makeEquivalentMemoryOrdering(Ld, NewLoad);
6744 return convertFromScalableVector(VT, NewLoad, DAG, Subtarget);
6745 }
6746
6747 MVT SplatVT = ContainerVT;
6748
6749 // f16 with zvfhmin and bf16 need to use an integer scalar load.
6750 if (SVT == MVT::bf16 ||
6751 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
6752 SVT = MVT::i16;
6753 SplatVT = ContainerVT.changeVectorElementType(SVT);
6754 }
6755
6756 // Otherwise use a scalar load and splat. This will give the best
6757 // opportunity to fold a splat into the operation. ISel can turn it into
6758 // the x0 strided load if we aren't able to fold away the select.
6759 if (SVT.isFloatingPoint())
6760 V = DAG.getLoad(SVT, DL, Ld->getChain(), NewAddr,
6761 Ld->getPointerInfo().getWithOffset(Offset),
6762 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
6763 else
6764 V = DAG.getExtLoad(ISD::EXTLOAD, DL, XLenVT, Ld->getChain(), NewAddr,
6765 Ld->getPointerInfo().getWithOffset(Offset), SVT,
6766 Ld->getBaseAlign(),
6767 Ld->getMemOperand()->getFlags());
6769
6770 unsigned Opc = SplatVT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL
6771 : RISCVISD::VMV_V_X_VL;
6772 SDValue Splat =
6773 DAG.getNode(Opc, DL, SplatVT, DAG.getUNDEF(ContainerVT), V, VL);
6774 Splat = DAG.getBitcast(ContainerVT, Splat);
6775 return convertFromScalableVector(VT, Splat, DAG, Subtarget);
6776 }
6777
6778 V1 = convertToScalableVector(ContainerVT, V1, DAG, Subtarget);
6779 assert(Lane < (int)NumElts && "Unexpected lane!");
6780 SDValue Gather = DAG.getNode(RISCVISD::VRGATHER_VX_VL, DL, ContainerVT,
6781 V1, DAG.getConstant(Lane, DL, XLenVT),
6782 DAG.getUNDEF(ContainerVT), TrueMask, VL);
6783 return convertFromScalableVector(VT, Gather, DAG, Subtarget);
6784 }
6785 }
6786
6787 // For exact VLEN m2 or greater, try to split to m1 operations if we
6788 // can split cleanly.
6789 if (SDValue V = lowerShuffleViaVRegSplitting(SVN, DAG, Subtarget))
6790 return V;
6791
6792 ArrayRef<int> Mask = SVN->getMask();
6793
6794 if (SDValue V =
6795 lowerVECTOR_SHUFFLEAsVSlide1(DL, VT, V1, V2, Mask, Subtarget, DAG))
6796 return V;
6797
6798 if (SDValue V =
6799 lowerVECTOR_SHUFFLEAsVSlidedown(DL, VT, V1, V2, Mask, Subtarget, DAG))
6800 return V;
6801
6802 // A bitrotate will be one instruction on Zvkb, so try to lower to it first if
6803 // available.
6804 if (Subtarget.hasStdExtZvkb())
6805 if (SDValue V = lowerVECTOR_SHUFFLEAsRotate(SVN, DAG, Subtarget))
6806 return V;
6807
6808 if (ShuffleVectorInst::isReverseMask(Mask, NumElts) && V2.isUndef() &&
6809 NumElts != 2)
6810 return DAG.getNode(ISD::VECTOR_REVERSE, DL, VT, V1);
6811
6812 // If this is a deinterleave(2,4,8) and we can widen the vector, then we can
6813 // use shift and truncate to perform the shuffle.
6814 // TODO: For Factor=6, we can perform the first step of the deinterleave via
6815 // shift-and-trunc reducing total cost for everything except an mf8 result.
6816 // TODO: For Factor=4,8, we can do the same when the ratio isn't high enough
6817 // to do the entire operation.
6818 if (VT.getScalarSizeInBits() < Subtarget.getELen()) {
6819 const unsigned MaxFactor = Subtarget.getELen() / VT.getScalarSizeInBits();
6820 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6821 for (unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
6822 unsigned Index = 0;
6823 if (ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, Factor, Index) &&
6824 1 < count_if(Mask, [](int Idx) { return Idx != -1; })) {
6825 if (SDValue Src = getSingleShuffleSrc(VT, V1, V2))
6826 return getDeinterleaveShiftAndTrunc(DL, VT, Src, Factor, Index, DAG);
6827 if (1 < count_if(Mask,
6828 [&Mask](int Idx) { return Idx < (int)Mask.size(); }) &&
6829 1 < count_if(Mask, [&Mask](int Idx) {
6830 return Idx >= (int)Mask.size();
6831 })) {
6832 // Narrow each source and concatenate them.
6833 // FIXME: For small LMUL it is better to concatenate first.
6834 MVT EltVT = VT.getVectorElementType();
6835 auto EltCnt = VT.getVectorElementCount();
6836 MVT SubVT =
6837 MVT::getVectorVT(EltVT, EltCnt.divideCoefficientBy(Factor));
6838
6839 SDValue Lo =
6840 getDeinterleaveShiftAndTrunc(DL, SubVT, V1, Factor, Index, DAG);
6841 SDValue Hi =
6842 getDeinterleaveShiftAndTrunc(DL, SubVT, V2, Factor, Index, DAG);
6843
6844 SDValue Concat =
6847 if (Factor == 2)
6848 return Concat;
6849
6850 SDValue Vec = DAG.getUNDEF(VT);
6851 return DAG.getInsertSubvector(DL, Vec, Concat, 0);
6852 }
6853 }
6854 }
6855 }
6856
6857 // If this is a deinterleave(2), try using vunzip{e,o}. This mostly catches
6858 // e64 which can't match above.
6859 unsigned Index = 0;
6860 if (Subtarget.hasStdExtZvzip() &&
6862 1 < count_if(Mask, [](int Idx) { return Idx != -1; })) {
6863 bool UsesBothSources =
6864 1 < count_if(Mask,
6865 [&Mask](int Idx) { return Idx < (int)Mask.size(); }) &&
6866 1 < count_if(Mask,
6867 [&Mask](int Idx) { return Idx >= (int)Mask.size(); });
6868
6869 if (isLegalVTForZvzipOperand(VT, Subtarget)) {
6870 unsigned Opc = Index == 0 ? RISCVISD::VUNZIPE_VL : RISCVISD::VUNZIPO_VL;
6871 MVT NewVT = VT.getDoubleNumVectorElementsVT();
6872 if (isTypeLegal(NewVT)) {
6873 SDValue Op;
6874 if (V2.isUndef()) {
6875 Op = DAG.getNode(ISD::CONCAT_VECTORS, DL, NewVT, V1, V2);
6876 } else if (auto VLEN = Subtarget.getRealVLen();
6877 VLEN && VT.getSizeInBits().getKnownMinValue() % *VLEN == 0) {
6878 Op = DAG.getNode(ISD::CONCAT_VECTORS, DL, NewVT, V1, V2);
6879 } else if (SDValue Src = foldConcatVector(V1, V2)) {
6880 Op = DAG.getExtractSubvector(DL, NewVT, Src, 0);
6881 }
6882 if (Op)
6883 return lowerZvzipVUNZIP(Opc, Op, DL, DAG, Subtarget);
6884 }
6885
6886 if (UsesBothSources &&
6887 V1.getSimpleValueType().getVectorMinNumElements() >= 2 &&
6889 SDValue Lo = lowerZvzipVUNZIP(Opc, V1, DL, DAG, Subtarget);
6890 SDValue Hi = lowerZvzipVUNZIP(Opc, V2, DL, DAG, Subtarget);
6891 return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
6892 }
6893 }
6894 }
6895
6896 if (SDValue V =
6897 lowerVECTOR_SHUFFLEAsVSlideup(DL, VT, V1, V2, Mask, Subtarget, DAG))
6898 return V;
6899
6900 // Detect an interleave shuffle and lower to
6901 // (vmaccu.vx (vwaddu.vx lohalf(V1), lohalf(V2)), lohalf(V2), (2^eltbits - 1))
6902 int EvenSrc, OddSrc;
6903 if (isInterleaveShuffle(Mask, VT, EvenSrc, OddSrc, Subtarget) &&
6904 !(NumElts == 2 &&
6906 // Extract the halves of the vectors.
6907 MVT HalfVT = VT.getHalfNumVectorElementsVT();
6908
6909 // Recognize if one half is actually undef; the matching above will
6910 // otherwise reuse the even stream for the undef one. This improves
6911 // spread(2) shuffles.
6912 bool LaneIsUndef[2] = { true, true};
6913 for (const auto &[Idx, M] : enumerate(Mask))
6914 LaneIsUndef[Idx % 2] &= (M == -1);
6915
6916 int Size = Mask.size();
6917 SDValue EvenV, OddV;
6918 if (LaneIsUndef[0]) {
6919 EvenV = DAG.getUNDEF(HalfVT);
6920 } else {
6921 assert(EvenSrc >= 0 && "Undef source?");
6922 EvenV = (EvenSrc / Size) == 0 ? V1 : V2;
6923 EvenV = DAG.getExtractSubvector(DL, HalfVT, EvenV, EvenSrc % Size);
6924 }
6925
6926 if (LaneIsUndef[1]) {
6927 OddV = DAG.getUNDEF(HalfVT);
6928 } else {
6929 assert(OddSrc >= 0 && "Undef source?");
6930 OddV = (OddSrc / Size) == 0 ? V1 : V2;
6931 OddV = DAG.getExtractSubvector(DL, HalfVT, OddV, OddSrc % Size);
6932 }
6933
6934 // Prefer vzip if available.
6935 // TODO: Extend to matching vzip if EvenSrc and OddSrc allow.
6936 if (Subtarget.hasStdExtZvzip() && isLegalVTForZvzipOperand(VT, Subtarget))
6937 return lowerZvzipVZIP(EvenV, OddV, DL, DAG, Subtarget);
6938 return getWideningInterleave(EvenV, OddV, DL, DAG, Subtarget);
6939 }
6940
6941 // Recognize a pattern which can handled via a pair of vslideup/vslidedown
6942 // instructions (in any combination) with masking on the second instruction.
6943 // Also handles masked slides into an identity source, and single slides
6944 // without masking. Avoid matching bit rotates (which are not also element
6945 // rotates) as slide pairs. This is a performance heuristic, not a
6946 // functional check.
6947 std::array<std::pair<int, int>, 2> SrcInfo;
6948 unsigned RotateAmt;
6949 MVT RotateVT;
6950 if (::isMaskedSlidePair(Mask, SrcInfo) &&
6951 (isElementRotate(SrcInfo, NumElts) ||
6952 !isLegalBitRotate(Mask, VT, Subtarget, RotateVT, RotateAmt))) {
6953 SDValue Sources[2];
6954 auto GetSourceFor = [&](const std::pair<int, int> &Info) {
6955 int SrcIdx = Info.first;
6956 assert(SrcIdx == 0 || SrcIdx == 1);
6957 SDValue &Src = Sources[SrcIdx];
6958 if (!Src) {
6959 SDValue SrcV = SrcIdx == 0 ? V1 : V2;
6960 Src = convertToScalableVector(ContainerVT, SrcV, DAG, Subtarget);
6961 }
6962 return Src;
6963 };
6964 auto GetSlide = [&](const std::pair<int, int> &Src, SDValue Mask,
6965 SDValue Passthru) {
6966 auto [TrueMask, VL] = TrueMaskVL;
6967 SDValue SrcV = GetSourceFor(Src);
6968 int SlideAmt = Src.second;
6969 if (SlideAmt == 0) {
6970 // Should never be second operation
6971 assert(Mask == TrueMask);
6972 return SrcV;
6973 }
6974 if (SlideAmt < 0)
6975 return getVSlidedown(DAG, Subtarget, DL, ContainerVT, Passthru, SrcV,
6976 DAG.getConstant(-SlideAmt, DL, XLenVT), Mask, VL,
6978 return getVSlideup(DAG, Subtarget, DL, ContainerVT, Passthru, SrcV,
6979 DAG.getConstant(SlideAmt, DL, XLenVT), Mask, VL,
6981 };
6982
6983 if (SrcInfo[1].first == -1) {
6984 SDValue Res = DAG.getUNDEF(ContainerVT);
6985 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6986 return convertFromScalableVector(VT, Res, DAG, Subtarget);
6987 }
6988
6989 if (Subtarget.hasStdExtZvzip()) {
6990 bool TryWiden = false;
6991 unsigned Factor;
6992 if (isPairEven(SrcInfo, Mask, Factor)) {
6993 if (Factor == 1) {
6994 SDValue Src1 = SrcInfo[0].first == 0 ? V1 : V2;
6995 SDValue Src2 = SrcInfo[1].first == 0 ? V1 : V2;
6996 return lowerZvzipVPAIR(RISCVISD::VPAIRE_VL, Src1, Src2, DL, DAG,
6997 Subtarget);
6998 }
6999 TryWiden = true;
7000 }
7001 if (isPairOdd(SrcInfo, Mask, Factor)) {
7002 if (Factor == 1) {
7003 SDValue Src1 = SrcInfo[1].first == 0 ? V1 : V2;
7004 SDValue Src2 = SrcInfo[0].first == 0 ? V1 : V2;
7005 return lowerZvzipVPAIR(RISCVISD::VPAIRO_VL, Src1, Src2, DL, DAG,
7006 Subtarget);
7007 }
7008 TryWiden = true;
7009 }
7010 // If we found a widening oppurtunity which would let us form a
7011 // pair-even or pair-odd, use the generic code to widen the shuffle
7012 // and recurse through this logic.
7013 if (TryWiden)
7014 if (SDValue V = tryWidenMaskForShuffle(Op, DAG))
7015 return V;
7016 }
7017
7018 // Build the mask. Note that vslideup unconditionally preserves elements
7019 // below the slide amount in the destination, and thus those elements are
7020 // undefined in the mask. If the mask ends up all true (or undef), it
7021 // will be folded away by general logic.
7022 SmallVector<SDValue> MaskVals;
7023 for (const auto &[Idx, M] : enumerate(Mask)) {
7024 if (M < 0 ||
7025 (SrcInfo[1].second > 0 && Idx < (unsigned)SrcInfo[1].second)) {
7026 MaskVals.push_back(DAG.getUNDEF(XLenVT));
7027 continue;
7028 }
7029 int Src = M >= (int)NumElts;
7030 int Diff = (int)Idx - (M % NumElts);
7031 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
7032 assert(C ^ (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
7033 "Must match exactly one of the two slides");
7034 MaskVals.push_back(DAG.getConstant(C, DL, XLenVT));
7035 }
7036 assert(MaskVals.size() == NumElts && "Unexpected select-like shuffle");
7037 MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
7038 SDValue SelectMask = convertToScalableVector(
7039 ContainerVT.changeVectorElementType(MVT::i1),
7040 DAG.getBuildVector(MaskVT, DL, MaskVals), DAG, Subtarget);
7041
7042 SDValue Res = DAG.getUNDEF(ContainerVT);
7043 Res = GetSlide(SrcInfo[0], TrueMask, Res);
7044 Res = GetSlide(SrcInfo[1], SelectMask, Res);
7045 return convertFromScalableVector(VT, Res, DAG, Subtarget);
7046 }
7047
7048 // Handle any remaining single source shuffles
7049 assert(!V1.isUndef() && "Unexpected shuffle canonicalization");
7050 if (V2.isUndef()) {
7051 // We might be able to express the shuffle as a bitrotate. But even if we
7052 // don't have Zvkb and have to expand, the expanded sequence of approx. 2
7053 // shifts and a vor will have a higher throughput than a vrgather.
7054 if (SDValue V = lowerVECTOR_SHUFFLEAsRotate(SVN, DAG, Subtarget))
7055 return V;
7056
7057 if (SDValue V = lowerVECTOR_SHUFFLEAsVRGatherVX(SVN, Subtarget, DAG))
7058 return V;
7059
7060 // Match a spread(4,8) which can be done via extend and shift. Spread(2)
7061 // is fully covered in interleave(2) above, so it is ignored here.
7062 if (VT.getScalarSizeInBits() < Subtarget.getELen()) {
7063 unsigned MaxFactor = Subtarget.getELen() / VT.getScalarSizeInBits();
7064 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
7065 for (unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
7066 unsigned Index;
7067 if (RISCVTargetLowering::isSpreadMask(Mask, Factor, Index)) {
7068 MVT NarrowVT =
7069 MVT::getVectorVT(VT.getVectorElementType(), NumElts / Factor);
7070 SDValue Src = DAG.getExtractSubvector(DL, NarrowVT, V1, 0);
7071 return getWideningSpread(Src, Factor, Index, DL, DAG);
7072 }
7073 }
7074 }
7075
7076 // If only a prefix of the source elements influence a prefix of the
7077 // destination elements, try to see if we can reduce the required LMUL
7078 unsigned MinVLen = Subtarget.getRealMinVLen();
7079 unsigned MinVLMAX = MinVLen / VT.getScalarSizeInBits();
7080 if (NumElts > MinVLMAX) {
7081 unsigned MaxIdx = 0;
7082 for (auto [I, M] : enumerate(Mask)) {
7083 if (M == -1)
7084 continue;
7085 MaxIdx = std::max({(unsigned)I, (unsigned)M, MaxIdx});
7086 }
7087 unsigned NewNumElts =
7088 std::max((uint64_t)MinVLMAX, PowerOf2Ceil(MaxIdx + 1));
7089 if (NewNumElts != NumElts) {
7090 MVT NewVT = MVT::getVectorVT(VT.getVectorElementType(), NewNumElts);
7091 V1 = DAG.getExtractSubvector(DL, NewVT, V1, 0);
7092 SDValue Res = DAG.getVectorShuffle(NewVT, DL, V1, DAG.getUNDEF(NewVT),
7093 Mask.take_front(NewNumElts));
7094 return DAG.getInsertSubvector(DL, DAG.getUNDEF(VT), Res, 0);
7095 }
7096 }
7097
7098 // Before hitting generic lowering fallbacks, try to widen the mask
7099 // to a wider SEW.
7100 if (SDValue V = tryWidenMaskForShuffle(Op, DAG))
7101 return V;
7102
7103 // Can we generate a vcompress instead of a vrgather? These scale better
7104 // at high LMUL, at the cost of not being able to fold a following select
7105 // into them. The mask constants are also smaller than the index vector
7106 // constants, and thus easier to materialize.
7107 if (isCompressMask(Mask)) {
7108 SmallVector<SDValue> MaskVals(NumElts,
7109 DAG.getConstant(false, DL, XLenVT));
7110 for (auto Idx : Mask) {
7111 if (Idx == -1)
7112 break;
7113 assert(Idx >= 0 && (unsigned)Idx < NumElts);
7114 MaskVals[Idx] = DAG.getConstant(true, DL, XLenVT);
7115 }
7116 MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
7117 SDValue CompressMask = DAG.getBuildVector(MaskVT, DL, MaskVals);
7118 return DAG.getNode(ISD::VECTOR_COMPRESS, DL, VT, V1, CompressMask,
7119 DAG.getUNDEF(VT));
7120 }
7121
7122 if (VT.getScalarSizeInBits() == 8 &&
7123 any_of(Mask, [&](const auto &Idx) { return Idx > 255; })) {
7124 // On such a vector we're unable to use i8 as the index type.
7125 // FIXME: We could promote the index to i16 and use vrgatherei16, but that
7126 // may involve vector splitting if we're already at LMUL=8, or our
7127 // user-supplied maximum fixed-length LMUL.
7128 return SDValue();
7129 }
7130
7131 // Base case for the two operand recursion below - handle the worst case
7132 // single source shuffle.
7133 unsigned GatherVVOpc = RISCVISD::VRGATHER_VV_VL;
7134 MVT IndexVT = VT.changeTypeToInteger();
7135 // Since we can't introduce illegal index types at this stage, use i16 and
7136 // vrgatherei16 if the corresponding index type for plain vrgather is greater
7137 // than XLenVT.
7138 if (IndexVT.getScalarType().bitsGT(XLenVT)) {
7139 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
7140 IndexVT = IndexVT.changeVectorElementType(MVT::i16);
7141 }
7142
7143 // If the mask allows, we can do all the index computation in 16 bits. This
7144 // requires less work and less register pressure at high LMUL, and creates
7145 // smaller constants which may be cheaper to materialize.
7146 if (IndexVT.getScalarType().bitsGT(MVT::i16) && isUInt<16>(NumElts - 1) &&
7147 (IndexVT.getSizeInBits() / Subtarget.getRealMinVLen()) > 1) {
7148 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
7149 IndexVT = IndexVT.changeVectorElementType(MVT::i16);
7150 }
7151
7152 MVT IndexContainerVT =
7153 ContainerVT.changeVectorElementType(IndexVT.getScalarType());
7154
7155 V1 = convertToScalableVector(ContainerVT, V1, DAG, Subtarget);
7156 SmallVector<SDValue> GatherIndicesLHS;
7157 for (int MaskIndex : Mask) {
7158 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
7159 GatherIndicesLHS.push_back(IsLHSIndex
7160 ? DAG.getConstant(MaskIndex, DL, XLenVT)
7161 : DAG.getUNDEF(XLenVT));
7162 }
7163 SDValue LHSIndices = DAG.getBuildVector(IndexVT, DL, GatherIndicesLHS);
7164 LHSIndices =
7165 convertToScalableVector(IndexContainerVT, LHSIndices, DAG, Subtarget);
7166 // At m1 and less, there's no point trying any of the high LMUL splitting
7167 // techniques. TODO: Should we reconsider this for DLEN < VLEN?
7168 if (NumElts <= MinVLMAX) {
7169 SDValue Gather = DAG.getNode(GatherVVOpc, DL, ContainerVT, V1, LHSIndices,
7170 DAG.getUNDEF(ContainerVT), TrueMask, VL);
7171 return convertFromScalableVector(VT, Gather, DAG, Subtarget);
7172 }
7173
7174 const MVT M1VT = RISCVTargetLowering::getM1VT(ContainerVT);
7175 EVT SubIndexVT = M1VT.changeVectorElementType(IndexVT.getScalarType());
7176 auto [InnerTrueMask, InnerVL] =
7177 getDefaultScalableVLOps(M1VT, DL, DAG, Subtarget);
7178 int N =
7179 ContainerVT.getVectorMinNumElements() / M1VT.getVectorMinNumElements();
7180 assert(isPowerOf2_32(N) && N <= 8);
7181
7182 // If we have a locally repeating mask, then we can reuse the first
7183 // register in the index register group for all registers within the
7184 // source register group. TODO: This generalizes to m2, and m4.
7185 if (isLocalRepeatingShuffle(Mask, MinVLMAX)) {
7186 SDValue SubIndex = DAG.getExtractSubvector(DL, SubIndexVT, LHSIndices, 0);
7187 SDValue Gather = DAG.getUNDEF(ContainerVT);
7188 for (int i = 0; i < N; i++) {
7189 unsigned SubIdx = M1VT.getVectorMinNumElements() * i;
7190 SDValue SubV1 = DAG.getExtractSubvector(DL, M1VT, V1, SubIdx);
7191 SDValue SubVec =
7192 DAG.getNode(GatherVVOpc, DL, M1VT, SubV1, SubIndex,
7193 DAG.getUNDEF(M1VT), InnerTrueMask, InnerVL);
7194 Gather = DAG.getInsertSubvector(DL, Gather, SubVec, SubIdx);
7195 }
7196 return convertFromScalableVector(VT, Gather, DAG, Subtarget);
7197 }
7198
7199 // If we have a shuffle which only uses the first register in our source
7200 // register group, and repeats the same index across all spans, we can
7201 // use a single vrgather (and possibly some register moves).
7202 // TODO: This can be generalized for m2 or m4, or for any shuffle for
7203 // which we can do a linear number of shuffles to form an m1 which
7204 // contains all the output elements.
7205 if (isLowSourceShuffle(Mask, MinVLMAX) &&
7206 isSpanSplatShuffle(Mask, MinVLMAX)) {
7207 SDValue SubV1 = DAG.getExtractSubvector(DL, M1VT, V1, 0);
7208 SDValue SubIndex = DAG.getExtractSubvector(DL, SubIndexVT, LHSIndices, 0);
7209 SDValue SubVec = DAG.getNode(GatherVVOpc, DL, M1VT, SubV1, SubIndex,
7210 DAG.getUNDEF(M1VT), InnerTrueMask, InnerVL);
7211 SDValue Gather = DAG.getUNDEF(ContainerVT);
7212 for (int i = 0; i < N; i++)
7213 Gather = DAG.getInsertSubvector(DL, Gather, SubVec,
7214 M1VT.getVectorMinNumElements() * i);
7215 return convertFromScalableVector(VT, Gather, DAG, Subtarget);
7216 }
7217
7218 // If we have a shuffle which only uses the first register in our
7219 // source register group, we can do a linear number of m1 vrgathers
7220 // reusing the same source register (but with different indices)
7221 // TODO: This can be generalized for m2 or m4, or for any shuffle
7222 // for which we can do a vslidedown followed by this expansion.
7223 if (isLowSourceShuffle(Mask, MinVLMAX)) {
7224 SDValue SlideAmt =
7225 DAG.getElementCount(DL, XLenVT, M1VT.getVectorElementCount());
7226 SDValue SubV1 = DAG.getExtractSubvector(DL, M1VT, V1, 0);
7227 SDValue Gather = DAG.getUNDEF(ContainerVT);
7228 for (int i = 0; i < N; i++) {
7229 if (i != 0)
7230 LHSIndices = getVSlidedown(DAG, Subtarget, DL, IndexContainerVT,
7231 DAG.getUNDEF(IndexContainerVT), LHSIndices,
7232 SlideAmt, TrueMask, VL);
7233 SDValue SubIndex =
7234 DAG.getExtractSubvector(DL, SubIndexVT, LHSIndices, 0);
7235 SDValue SubVec =
7236 DAG.getNode(GatherVVOpc, DL, M1VT, SubV1, SubIndex,
7237 DAG.getUNDEF(M1VT), InnerTrueMask, InnerVL);
7238 Gather = DAG.getInsertSubvector(DL, Gather, SubVec,
7239 M1VT.getVectorMinNumElements() * i);
7240 }
7241 return convertFromScalableVector(VT, Gather, DAG, Subtarget);
7242 }
7243
7244 // Fallback to generic vrgather if we can't find anything better.
7245 // On many machines, this will be O(LMUL^2)
7246 SDValue Gather = DAG.getNode(GatherVVOpc, DL, ContainerVT, V1, LHSIndices,
7247 DAG.getUNDEF(ContainerVT), TrueMask, VL);
7248 return convertFromScalableVector(VT, Gather, DAG, Subtarget);
7249 }
7250
7251 // As a backup, shuffles can be lowered via a vrgather instruction, possibly
7252 // merged with a second vrgather.
7253 SmallVector<int> ShuffleMaskLHS, ShuffleMaskRHS;
7254
7255 // Now construct the mask that will be used by the blended vrgather operation.
7256 // Construct the appropriate indices into each vector.
7257 for (int MaskIndex : Mask) {
7258 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
7259 ShuffleMaskLHS.push_back(IsLHSOrUndefIndex && MaskIndex >= 0
7260 ? MaskIndex : -1);
7261 ShuffleMaskRHS.push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
7262 }
7263
7264 // If the mask indices are disjoint between the two sources, we can lower it
7265 // as a vselect + a single source vrgather.vv. Don't do this if we think the
7266 // operands may end up being lowered to something cheaper than a vrgather.vv.
7267 if (!DAG.isSplatValue(V2) && !DAG.isSplatValue(V1) &&
7268 !ShuffleVectorSDNode::isSplatMask(ShuffleMaskLHS) &&
7269 !ShuffleVectorSDNode::isSplatMask(ShuffleMaskRHS) &&
7270 !ShuffleVectorInst::isIdentityMask(ShuffleMaskLHS, NumElts) &&
7271 !ShuffleVectorInst::isIdentityMask(ShuffleMaskRHS, NumElts))
7272 if (SDValue V = lowerDisjointIndicesShuffle(SVN, DAG, Subtarget))
7273 return V;
7274
7275 // Before hitting generic lowering fallbacks, try to widen the mask
7276 // to a wider SEW.
7277 if (SDValue V = tryWidenMaskForShuffle(Op, DAG))
7278 return V;
7279
7280 // Try to pick a profitable operand order.
7281 bool SwapOps = DAG.isSplatValue(V2) && !DAG.isSplatValue(V1);
7282 SwapOps = SwapOps ^ ShuffleVectorInst::isIdentityMask(ShuffleMaskRHS, NumElts);
7283
7284 // Recursively invoke lowering for each operand if we had two
7285 // independent single source shuffles, and then combine the result via a
7286 // vselect. Note that the vselect will likely be folded back into the
7287 // second permute (vrgather, or other) by the post-isel combine.
7288 V1 = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), ShuffleMaskLHS);
7289 V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), ShuffleMaskRHS);
7290
7291 SmallVector<SDValue> MaskVals;
7292 for (int MaskIndex : Mask) {
7293 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
7294 MaskVals.push_back(DAG.getConstant(SelectMaskVal, DL, XLenVT));
7295 }
7296
7297 assert(MaskVals.size() == NumElts && "Unexpected select-like shuffle");
7298 MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
7299 SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, MaskVals);
7300
7301 if (SwapOps)
7302 return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, V1, V2);
7303 return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, V2, V1);
7304}
7305
7307 EVT VT) const {
7308 // Enable DAGCombiner::XformToShuffleWithZero to rewrite a packed zero-extend
7309 // `and` into shuffle(src, zero, ...), which lowerVECTOR_SHUFFLE turns into
7310 // RISCVISD::PPAIRE. Accept the packed byte/halfword views that lowering
7311 // handles; the 32-bit views are illegal on RV64 but reachable before type
7312 // legalization widens them to the legal 64-bit view.
7313 if (!Subtarget.hasStdExtP() || !VT.isSimple())
7314 return false;
7315 MVT SVT = VT.getSimpleVT();
7316 return (SVT == MVT::v4i8 || SVT == MVT::v8i8 || SVT == MVT::v4i16) &&
7318}
7319
7321 // Only support legal VTs for other shuffles for now.
7322 if (!isTypeLegal(VT) || !Subtarget.hasVInstructions())
7323 return false;
7324
7325 // Support splats for any type. These should type legalize well.
7327 return true;
7328
7329 const unsigned NumElts = M.size();
7330 MVT SVT = VT.getSimpleVT();
7331
7332 // Not for i1 vectors.
7333 if (SVT.getScalarType() == MVT::i1)
7334 return false;
7335
7336 std::array<std::pair<int, int>, 2> SrcInfo;
7337 int Dummy1, Dummy2;
7338 return ShuffleVectorInst::isReverseMask(M, NumElts) ||
7339 (::isMaskedSlidePair(M, SrcInfo) &&
7340 isElementRotate(SrcInfo, NumElts)) ||
7341 isInterleaveShuffle(M, SVT, Dummy1, Dummy2, Subtarget);
7342}
7343
7344// Lower CTLZ_ZERO_POISON or CTTZ_ZERO_POISON by converting to FP and extracting
7345// the exponent.
7346SDValue
7347RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_POISON(SDValue Op,
7348 SelectionDAG &DAG) const {
7349 MVT VT = Op.getSimpleValueType();
7350 unsigned EltSize = VT.getScalarSizeInBits();
7351 SDValue Src = Op.getOperand(0);
7352 SDLoc DL(Op);
7353 MVT ContainerVT = VT;
7354
7355 // We choose FP type that can represent the value if possible. Otherwise, we
7356 // use rounding to zero conversion for correct exponent of the result.
7357 // TODO: Use f16 for i8 when possible?
7358 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 : MVT::f32;
7359 if (!isTypeLegal(MVT::getVectorVT(FloatEltVT, VT.getVectorElementCount())))
7360 FloatEltVT = MVT::f32;
7361 MVT FloatVT = MVT::getVectorVT(FloatEltVT, VT.getVectorElementCount());
7362
7363 // Legal types should have been checked in the RISCVTargetLowering
7364 // constructor.
7365 // TODO: Splitting may make sense in some cases.
7366 assert(DAG.getTargetLoweringInfo().isTypeLegal(FloatVT) &&
7367 "Expected legal float type!");
7368
7369 // For CTTZ_ZERO_POISON, we need to extract the lowest set bit using X & -X.
7370 // The trailing zero count is equal to log2 of this single bit value.
7371 if (Op.getOpcode() == ISD::CTTZ_ZERO_POISON) {
7372 SDValue Neg = DAG.getNegative(Src, DL, VT);
7373 Src = DAG.getNode(ISD::AND, DL, VT, Src, Neg);
7374 }
7375
7376 // We have a legal FP type, convert to it.
7377 SDValue FloatVal;
7378 if (FloatVT.bitsGT(VT)) {
7379 FloatVal = DAG.getNode(ISD::UINT_TO_FP, DL, FloatVT, Src);
7380 } else {
7381 // Use RTZ to avoid rounding influencing exponent of FloatVal.
7382 if (VT.isFixedLengthVector()) {
7383 ContainerVT = getContainerForFixedLengthVector(VT);
7384 Src = convertToScalableVector(ContainerVT, Src, DAG, Subtarget);
7385 }
7386 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
7387 SDValue RTZRM =
7388 DAG.getTargetConstant(RISCVFPRndMode::RTZ, DL, Subtarget.getXLenVT());
7389 MVT ContainerFloatVT =
7390 MVT::getVectorVT(FloatEltVT, ContainerVT.getVectorElementCount());
7391 FloatVal = DAG.getNode(RISCVISD::VFCVT_RM_F_XU_VL, DL, ContainerFloatVT,
7392 Src, Mask, RTZRM, VL);
7393 if (VT.isFixedLengthVector())
7394 FloatVal = convertFromScalableVector(FloatVT, FloatVal, DAG, Subtarget);
7395 }
7396 // Bitcast to integer and shift the exponent to the LSB.
7397 EVT IntVT = FloatVT.changeVectorElementTypeToInteger();
7398 SDValue Bitcast = DAG.getBitcast(IntVT, FloatVal);
7399 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
7400
7401 // Restore back to original type. Truncation after SRL is to generate vnsrl.
7402 SDValue Exp = DAG.getNode(ISD::SRL, DL, IntVT, Bitcast,
7403 DAG.getConstant(ShiftAmt, DL, IntVT));
7404 if (IntVT.bitsLT(VT))
7405 Exp = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Exp);
7406 else if (IntVT.bitsGT(VT))
7407 Exp = DAG.getNode(ISD::TRUNCATE, DL, VT, Exp);
7408
7409 // The exponent contains log2 of the value in biased form.
7410 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
7411 // For trailing zeros, we just need to subtract the bias.
7412 if (Op.getOpcode() == ISD::CTTZ_ZERO_POISON)
7413 return DAG.getNode(ISD::SUB, DL, VT, Exp,
7414 DAG.getConstant(ExponentBias, DL, VT));
7415
7416 // For leading zeros, we need to remove the bias and convert from log2 to
7417 // leading zeros. We can do this by subtracting from (Bias + (EltSize - 1)).
7418 unsigned Adjust = ExponentBias + (EltSize - 1);
7419 SDValue Res =
7420 DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(Adjust, DL, VT), Exp);
7421
7422 // The above result with zero input equals to Adjust which is greater than
7423 // EltSize. Hence, we can do min(Res, EltSize) for CTLZ.
7424 if (Op.getOpcode() == ISD::CTLZ)
7425 Res = DAG.getNode(ISD::UMIN, DL, VT, Res, DAG.getConstant(EltSize, DL, VT));
7426
7427 return Res;
7428}
7429
7430SDValue RISCVTargetLowering::lowerVPCttzElements(SDValue Op,
7431 SelectionDAG &DAG) const {
7432 SDLoc DL(Op);
7433 MVT XLenVT = Subtarget.getXLenVT();
7434 SDValue Source = Op->getOperand(0);
7435 MVT SrcVT = Source.getSimpleValueType();
7436 SDValue Mask = Op->getOperand(1);
7437 SDValue EVL = Op->getOperand(2);
7438
7439 if (SrcVT.isFixedLengthVector()) {
7440 MVT ContainerVT = getContainerForFixedLengthVector(SrcVT);
7441 Source = convertToScalableVector(ContainerVT, Source, DAG, Subtarget);
7442 Mask = convertToScalableVector(getMaskTypeFor(ContainerVT), Mask, DAG,
7443 Subtarget);
7444 SrcVT = ContainerVT;
7445 }
7446
7447 // Convert to boolean vector.
7448 if (SrcVT.getScalarType() != MVT::i1) {
7449 SDValue AllZero = DAG.getConstant(0, DL, SrcVT);
7450 SrcVT = MVT::getVectorVT(MVT::i1, SrcVT.getVectorElementCount());
7451 Source = DAG.getNode(RISCVISD::SETCC_VL, DL, SrcVT,
7452 {Source, AllZero, DAG.getCondCode(ISD::SETNE),
7453 DAG.getUNDEF(SrcVT), Mask, EVL});
7454 }
7455
7456 SDValue Res = DAG.getNode(RISCVISD::VFIRST_VL, DL, XLenVT, Source, Mask, EVL);
7457 if (Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_POISON)
7458 // In this case, we can interpret poison as -1, so nothing to do further.
7459 return Res;
7460
7461 // Convert -1 to VL.
7462 SDValue SetCC =
7463 DAG.getSetCC(DL, XLenVT, Res, DAG.getConstant(0, DL, XLenVT), ISD::SETLT);
7464 Res = DAG.getSelect(DL, XLenVT, SetCC, EVL, Res);
7465 return DAG.getNode(ISD::TRUNCATE, DL, Op.getValueType(), Res);
7466}
7467
7468// While RVV has alignment restrictions, we should always be able to load as a
7469// legal equivalently-sized byte-typed vector instead. This method is
7470// responsible for re-expressing a ISD::LOAD via a correctly-aligned type. If
7471// the load is already correctly-aligned, it returns SDValue().
7472SDValue RISCVTargetLowering::expandUnalignedRVVLoad(SDValue Op,
7473 SelectionDAG &DAG) const {
7474 auto *Load = cast<LoadSDNode>(Op);
7475 assert(Load && Load->getMemoryVT().isVector() && "Expected vector load");
7476
7478 Load->getMemoryVT(),
7479 *Load->getMemOperand()))
7480 return SDValue();
7481
7482 SDLoc DL(Op);
7483 MVT VT = Op.getSimpleValueType();
7484 unsigned EltSizeBits = VT.getScalarSizeInBits();
7485 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7486 "Unexpected unaligned RVV load type");
7487 MVT NewVT =
7488 MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
7489 assert(NewVT.isValid() &&
7490 "Expecting equally-sized RVV vector types to be legal");
7491 SDValue L = DAG.getLoad(NewVT, DL, Load->getChain(), Load->getBasePtr(),
7492 Load->getPointerInfo(), Load->getBaseAlign(),
7493 Load->getMemOperand()->getFlags());
7494 return DAG.getMergeValues({DAG.getBitcast(VT, L), L.getValue(1)}, DL);
7495}
7496
7497// While RVV has alignment restrictions, we should always be able to store as a
7498// legal equivalently-sized byte-typed vector instead. This method is
7499// responsible for re-expressing a ISD::STORE via a correctly-aligned type. It
7500// returns SDValue() if the store is already correctly aligned.
7501SDValue RISCVTargetLowering::expandUnalignedRVVStore(SDValue Op,
7502 SelectionDAG &DAG) const {
7503 auto *Store = cast<StoreSDNode>(Op);
7504 assert(Store && Store->getValue().getValueType().isVector() &&
7505 "Expected vector store");
7506
7508 Store->getMemoryVT(),
7509 *Store->getMemOperand()))
7510 return SDValue();
7511
7512 SDLoc DL(Op);
7513 SDValue StoredVal = Store->getValue();
7514 MVT VT = StoredVal.getSimpleValueType();
7515 unsigned EltSizeBits = VT.getScalarSizeInBits();
7516 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7517 "Unexpected unaligned RVV store type");
7518 MVT NewVT =
7519 MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
7520 assert(NewVT.isValid() &&
7521 "Expecting equally-sized RVV vector types to be legal");
7522 StoredVal = DAG.getBitcast(NewVT, StoredVal);
7523 return DAG.getStore(Store->getChain(), DL, StoredVal, Store->getBasePtr(),
7524 Store->getPointerInfo(), Store->getBaseAlign(),
7525 Store->getMemOperand()->getFlags());
7526}
7527
7528// While RVV has alignment restrictions, we should always be able to load as a
7529// legal equivalently-sized byte-typed vector instead. This method is
7530// responsible for re-expressing a ISD::VP_LOAD via a correctly-aligned type. If
7531// the load is already correctly-aligned, it returns SDValue().
7532SDValue RISCVTargetLowering::expandUnalignedVPLoad(SDValue Op,
7533 SelectionDAG &DAG) const {
7534 auto *Load = cast<VPLoadSDNode>(Op);
7535 assert(Load && Load->getMemoryVT().isVector() && "Expected vector load");
7536
7538 Load->getMemoryVT(),
7539 *Load->getMemOperand()))
7540 return SDValue();
7541
7542 SDValue Mask = Load->getMask();
7543
7544 // FIXME: Handled masked loads somehow.
7546 return SDValue();
7547
7548 SDLoc DL(Op);
7549 MVT VT = Op.getSimpleValueType();
7550 unsigned EltSizeBits = VT.getScalarSizeInBits();
7551 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7552 "Unexpected unaligned RVV load type");
7553 MVT NewVT =
7554 MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
7555 assert(NewVT.isValid() &&
7556 "Expecting equally-sized RVV vector types to be legal");
7557
7558 SDValue VL = Load->getVectorLength();
7559 VL = DAG.getNode(ISD::MUL, DL, VL.getValueType(), VL,
7560 DAG.getConstant((EltSizeBits / 8), DL, VL.getValueType()));
7561
7562 MVT MaskVT = MVT::getVectorVT(MVT::i1, NewVT.getVectorElementCount());
7563 SDValue L = DAG.getLoadVP(NewVT, DL, Load->getChain(), Load->getBasePtr(),
7564 DAG.getAllOnesConstant(DL, MaskVT), VL,
7565 Load->getPointerInfo(), Load->getBaseAlign(),
7566 Load->getMemOperand()->getFlags(), AAMDNodes());
7567 return DAG.getMergeValues({DAG.getBitcast(VT, L), L.getValue(1)}, DL);
7568}
7569
7570// While RVV has alignment restrictions, we should always be able to store as a
7571// legal equivalently-sized byte-typed vector instead. This method is
7572// responsible for re-expressing a ISD::VP STORE via a correctly-aligned type.
7573// It returns SDValue() if the store is already correctly aligned.
7574SDValue RISCVTargetLowering::expandUnalignedVPStore(SDValue Op,
7575 SelectionDAG &DAG) const {
7576 auto *Store = cast<VPStoreSDNode>(Op);
7577 assert(Store && Store->getValue().getValueType().isVector() &&
7578 "Expected vector store");
7579
7581 Store->getMemoryVT(),
7582 *Store->getMemOperand()))
7583 return SDValue();
7584
7585 SDValue Mask = Store->getMask();
7586
7587 // FIXME: Handled masked stores somehow.
7589 return SDValue();
7590
7591 SDLoc DL(Op);
7592 SDValue StoredVal = Store->getValue();
7593 MVT VT = StoredVal.getSimpleValueType();
7594 unsigned EltSizeBits = VT.getScalarSizeInBits();
7595 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7596 "Unexpected unaligned RVV store type");
7597 MVT NewVT =
7598 MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
7599 assert(NewVT.isValid() &&
7600 "Expecting equally-sized RVV vector types to be legal");
7601
7602 SDValue VL = Store->getVectorLength();
7603 VL = DAG.getNode(ISD::MUL, DL, VL.getValueType(), VL,
7604 DAG.getConstant((EltSizeBits / 8), DL, VL.getValueType()));
7605
7606 StoredVal = DAG.getBitcast(NewVT, StoredVal);
7607
7608 LocationSize Size = LocationSize::precise(NewVT.getStoreSize());
7610 MachineMemOperand *MMO = MF.getMachineMemOperand(
7611 Store->getPointerInfo(), Store->getMemOperand()->getFlags(), Size,
7612 Store->getBaseAlign());
7613
7614 MVT MaskVT = MVT::getVectorVT(MVT::i1, NewVT.getVectorElementCount());
7615 return DAG.getStoreVP(Store->getChain(), DL, StoredVal, Store->getBasePtr(),
7616 DAG.getPOISON(Store->getBasePtr().getValueType()),
7617 DAG.getAllOnesConstant(DL, MaskVT), VL, NewVT, MMO,
7619}
7620
7622 const RISCVSubtarget &Subtarget) {
7623 assert(Op.getValueType() == MVT::i64 && "Unexpected VT");
7624
7625 int64_t Imm = cast<ConstantSDNode>(Op)->getSExtValue();
7626
7627 // All simm32 constants should be handled by isel.
7628 // NOTE: The getMaxBuildIntsCost call below should return a value >= 2 making
7629 // this check redundant, but small immediates are common so this check
7630 // should have better compile time.
7631 if (isInt<32>(Imm))
7632 return Op;
7633
7634 // We only need to cost the immediate, if constant pool lowering is enabled.
7635 if (!Subtarget.useConstantPoolForLargeInts())
7636 return Op;
7637
7639 if (Seq.size() <= Subtarget.getMaxBuildIntsCost())
7640 return Op;
7641
7642 // Optimizations below are disabled for opt size. If we're optimizing for
7643 // size, use a constant pool.
7644 if (DAG.shouldOptForSize())
7645 return SDValue();
7646
7647 // Special case. See if we can build the constant as (ADD (SLLI X, C), X) do
7648 // that if it will avoid a constant pool.
7649 // It will require an extra temporary register though.
7650 // If we have Zba we can use (ADD_UW X, (SLLI X, 32)) to handle cases where
7651 // low and high 32 bits are the same and bit 31 and 63 are set.
7652 unsigned ShiftAmt, AddOpc;
7653 RISCVMatInt::InstSeq SeqLo =
7654 RISCVMatInt::generateTwoRegInstSeq(Imm, Subtarget, ShiftAmt, AddOpc);
7655 if (!SeqLo.empty() && (SeqLo.size() + 2) <= Subtarget.getMaxBuildIntsCost())
7656 return Op;
7657
7658 return SDValue();
7659}
7660
7661SDValue RISCVTargetLowering::lowerConstantFP(SDValue Op,
7662 SelectionDAG &DAG) const {
7663 MVT VT = Op.getSimpleValueType();
7664 const APFloat &Imm = cast<ConstantFPSDNode>(Op)->getValueAPF();
7665
7666 // Can this constant be selected by a Zfa FLI instruction?
7667 bool Negate = false;
7668 int Index = getLegalZfaFPImm(Imm, VT);
7669
7670 // If the constant is negative, try negating.
7671 if (Index < 0 && Imm.isNegative()) {
7672 Index = getLegalZfaFPImm(-Imm, VT);
7673 Negate = true;
7674 }
7675
7676 // If we couldn't find a FLI lowering, fall back to generic code.
7677 if (Index < 0)
7678 return SDValue();
7679
7680 // Emit an FLI+FNEG. We use a custom node to hide from constant folding.
7681 SDLoc DL(Op);
7682 SDValue Const =
7683 DAG.getNode(RISCVISD::FLI, DL, VT,
7684 DAG.getTargetConstant(Index, DL, Subtarget.getXLenVT()));
7685 if (!Negate)
7686 return Const;
7687
7688 return DAG.getNode(ISD::FNEG, DL, VT, Const);
7689}
7690
7692 SelectionDAG &DAG) {
7693
7694 unsigned IsData = Op.getConstantOperandVal(4);
7695
7696 // mips-p8700 we support data prefetch for now.
7697 if (Subtarget.hasVendorXMIPSCBOP() && !IsData)
7698 return Op.getOperand(0);
7699 return Op;
7700}
7701
7703 const RISCVSubtarget &Subtarget) {
7704 SDLoc dl(Op);
7705 AtomicOrdering FenceOrdering =
7706 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
7707 SyncScope::ID FenceSSID =
7708 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
7709
7710 if (Subtarget.hasStdExtZtso()) {
7711 // The only fence that needs an instruction is a sequentially-consistent
7712 // cross-thread fence.
7713 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
7714 FenceSSID == SyncScope::System)
7715 return Op;
7716
7717 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
7718 return DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0));
7719 }
7720
7721 // singlethread fences only synchronize with signal handlers on the same
7722 // thread and thus only need to preserve instruction order, not actually
7723 // enforce memory ordering.
7724 if (FenceSSID == SyncScope::SingleThread)
7725 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
7726 return DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0));
7727
7728 return Op;
7729}
7730
7731SDValue RISCVTargetLowering::LowerIS_FPCLASS(SDValue Op,
7732 SelectionDAG &DAG) const {
7733 SDLoc DL(Op);
7734 MVT VT = Op.getSimpleValueType();
7735 MVT XLenVT = Subtarget.getXLenVT();
7736 unsigned Check = Op.getConstantOperandVal(1);
7737 unsigned TDCMask = 0;
7738 if (Check & fcSNan)
7739 TDCMask |= RISCV::FPMASK_Signaling_NaN;
7740 if (Check & fcQNan)
7741 TDCMask |= RISCV::FPMASK_Quiet_NaN;
7742 if (Check & fcPosInf)
7744 if (Check & fcNegInf)
7746 if (Check & fcPosNormal)
7748 if (Check & fcNegNormal)
7750 if (Check & fcPosSubnormal)
7752 if (Check & fcNegSubnormal)
7754 if (Check & fcPosZero)
7755 TDCMask |= RISCV::FPMASK_Positive_Zero;
7756 if (Check & fcNegZero)
7757 TDCMask |= RISCV::FPMASK_Negative_Zero;
7758
7759 bool IsOneBitMask = isPowerOf2_32(TDCMask);
7760
7761 SDValue TDCMaskV = DAG.getConstant(TDCMask, DL, XLenVT);
7762
7763 if (VT.isVector()) {
7764 SDValue Op0 = Op.getOperand(0);
7765 MVT VT0 = Op.getOperand(0).getSimpleValueType();
7766
7767 if (VT.isScalableVector()) {
7768 MVT DstVT = VT0.changeVectorElementTypeToInteger();
7769 auto [Mask, VL] = getDefaultScalableVLOps(VT0, DL, DAG, Subtarget);
7770 SDValue FPCLASS = DAG.getNode(RISCVISD::FCLASS_VL, DL, DstVT, Op0, Mask,
7771 VL, Op->getFlags());
7772 if (IsOneBitMask)
7773 return DAG.getSetCC(DL, VT, FPCLASS,
7774 DAG.getConstant(TDCMask, DL, DstVT),
7776 SDValue AND = DAG.getNode(ISD::AND, DL, DstVT, FPCLASS,
7777 DAG.getConstant(TDCMask, DL, DstVT));
7778 return DAG.getSetCC(DL, VT, AND, DAG.getConstant(0, DL, DstVT),
7779 ISD::SETNE);
7780 }
7781
7782 MVT ContainerVT0 = getContainerForFixedLengthVector(VT0);
7783 MVT ContainerVT = getContainerForFixedLengthVector(VT);
7784 MVT ContainerDstVT = ContainerVT0.changeVectorElementTypeToInteger();
7785 auto [Mask, VL] = getDefaultVLOps(VT0, ContainerVT0, DL, DAG, Subtarget);
7786 Op0 = convertToScalableVector(ContainerVT0, Op0, DAG, Subtarget);
7787
7788 SDValue FPCLASS = DAG.getNode(RISCVISD::FCLASS_VL, DL, ContainerDstVT, Op0,
7789 Mask, VL, Op->getFlags());
7790
7791 TDCMaskV = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerDstVT,
7792 DAG.getUNDEF(ContainerDstVT), TDCMaskV, VL);
7793 if (IsOneBitMask) {
7794 SDValue VMSEQ =
7795 DAG.getNode(RISCVISD::SETCC_VL, DL, ContainerVT,
7796 {FPCLASS, TDCMaskV, DAG.getCondCode(ISD::SETEQ),
7797 DAG.getUNDEF(ContainerVT), Mask, VL});
7798 return convertFromScalableVector(VT, VMSEQ, DAG, Subtarget);
7799 }
7800 SDValue AND = DAG.getNode(RISCVISD::AND_VL, DL, ContainerDstVT, FPCLASS,
7801 TDCMaskV, DAG.getUNDEF(ContainerDstVT), Mask, VL);
7802
7803 SDValue SplatZero = DAG.getConstant(0, DL, XLenVT);
7804 SplatZero = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerDstVT,
7805 DAG.getUNDEF(ContainerDstVT), SplatZero, VL);
7806
7807 SDValue VMSNE = DAG.getNode(RISCVISD::SETCC_VL, DL, ContainerVT,
7808 {AND, SplatZero, DAG.getCondCode(ISD::SETNE),
7809 DAG.getUNDEF(ContainerVT), Mask, VL});
7810 return convertFromScalableVector(VT, VMSNE, DAG, Subtarget);
7811 }
7812
7813 SDValue FCLASS = DAG.getNode(RISCVISD::FCLASS, DL, XLenVT, Op.getOperand(0));
7814 SDValue AND = DAG.getNode(ISD::AND, DL, XLenVT, FCLASS, TDCMaskV);
7815 SDValue Res = DAG.getSetCC(DL, XLenVT, AND, DAG.getConstant(0, DL, XLenVT),
7817 return DAG.getNode(ISD::TRUNCATE, DL, VT, Res);
7818}
7819
7820// Lower fmaximum and fminimum. Unlike our fmax and fmin instructions, these
7821// operations propagate nans.
7823 const RISCVSubtarget &Subtarget) {
7824 SDLoc DL(Op);
7825 MVT VT = Op.getSimpleValueType();
7826
7827 SDValue X = Op.getOperand(0);
7828 SDValue Y = Op.getOperand(1);
7829
7830 if (!VT.isVector()) {
7831 MVT XLenVT = Subtarget.getXLenVT();
7832
7833 // If X is a nan, replace Y with X. If Y is a nan, replace X with Y. This
7834 // ensures that when one input is a nan, the other will also be a nan
7835 // allowing the nan to propagate. If both inputs are nan, this will swap the
7836 // inputs which is harmless.
7837
7838 SDValue NewY = Y;
7839 if (!Op->getFlags().hasNoNaNs() && !DAG.isKnownNeverNaN(X)) {
7840 SDValue XIsNonNan = DAG.getSetCC(DL, XLenVT, X, X, ISD::SETOEQ);
7841 NewY = DAG.getSelect(DL, VT, XIsNonNan, Y, X);
7842 }
7843
7844 SDValue NewX = X;
7845 if (!Op->getFlags().hasNoNaNs() && !DAG.isKnownNeverNaN(Y)) {
7846 SDValue YIsNonNan = DAG.getSetCC(DL, XLenVT, Y, Y, ISD::SETOEQ);
7847 NewX = DAG.getSelect(DL, VT, YIsNonNan, X, Y);
7848 }
7849
7850 unsigned Opc =
7851 Op.getOpcode() == ISD::FMAXIMUM ? RISCVISD::FMAX : RISCVISD::FMIN;
7852 return DAG.getNode(Opc, DL, VT, NewX, NewY);
7853 }
7854
7855 // Check no NaNs before converting to fixed vector scalable.
7856 bool XIsNeverNan = Op->getFlags().hasNoNaNs() || DAG.isKnownNeverNaN(X);
7857 bool YIsNeverNan = Op->getFlags().hasNoNaNs() || DAG.isKnownNeverNaN(Y);
7858
7859 MVT ContainerVT = VT;
7860 if (VT.isFixedLengthVector()) {
7861 ContainerVT = getContainerForFixedLengthVector(VT, Subtarget);
7862 X = convertToScalableVector(ContainerVT, X, DAG, Subtarget);
7863 Y = convertToScalableVector(ContainerVT, Y, DAG, Subtarget);
7864 }
7865
7866 auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
7867
7868 SDValue NewY = Y;
7869 if (!XIsNeverNan) {
7870 SDValue XIsNonNan = DAG.getNode(RISCVISD::SETCC_VL, DL, Mask.getValueType(),
7871 {X, X, DAG.getCondCode(ISD::SETOEQ),
7872 DAG.getUNDEF(ContainerVT), Mask, VL});
7873 NewY = DAG.getNode(RISCVISD::VMERGE_VL, DL, ContainerVT, XIsNonNan, Y, X,
7874 DAG.getUNDEF(ContainerVT), VL);
7875 }
7876
7877 SDValue NewX = X;
7878 if (!YIsNeverNan) {
7879 SDValue YIsNonNan = DAG.getNode(RISCVISD::SETCC_VL, DL, Mask.getValueType(),
7880 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
7881 DAG.getUNDEF(ContainerVT), Mask, VL});
7882 NewX = DAG.getNode(RISCVISD::VMERGE_VL, DL, ContainerVT, YIsNonNan, X, Y,
7883 DAG.getUNDEF(ContainerVT), VL);
7884 }
7885
7886 unsigned Opc =
7887 Op.getOpcode() == ISD::FMAXIMUM ? RISCVISD::VFMAX_VL : RISCVISD::VFMIN_VL;
7888 SDValue Res = DAG.getNode(Opc, DL, ContainerVT, NewX, NewY,
7889 DAG.getUNDEF(ContainerVT), Mask, VL);
7890 if (VT.isFixedLengthVector())
7891 Res = convertFromScalableVector(VT, Res, DAG, Subtarget);
7892 return Res;
7893}
7894
7896 const RISCVSubtarget &Subtarget) {
7897 bool IsFABS = Op.getOpcode() == ISD::FABS;
7898 assert((IsFABS || Op.getOpcode() == ISD::FNEG) &&
7899 "Wrong opcode for lowering FABS or FNEG.");
7900
7901 MVT XLenVT = Subtarget.getXLenVT();
7902 MVT VT = Op.getSimpleValueType();
7903 assert((VT == MVT::f16 || VT == MVT::bf16) && "Unexpected type");
7904
7905 SDLoc DL(Op);
7906 SDValue Fmv =
7907 DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Op.getOperand(0));
7908
7909 APInt Mask = IsFABS ? APInt::getSignedMaxValue(16) : APInt::getSignMask(16);
7910 Mask = Mask.sext(Subtarget.getXLen());
7911
7912 unsigned LogicOpc = IsFABS ? ISD::AND : ISD::XOR;
7913 SDValue Logic =
7914 DAG.getNode(LogicOpc, DL, XLenVT, Fmv, DAG.getConstant(Mask, DL, XLenVT));
7915 return DAG.getNode(RISCVISD::FMV_H_X, DL, VT, Logic);
7916}
7917
7919 const RISCVSubtarget &Subtarget) {
7920 assert(Op.getOpcode() == ISD::FCOPYSIGN && "Unexpected opcode");
7921
7922 MVT XLenVT = Subtarget.getXLenVT();
7923 MVT VT = Op.getSimpleValueType();
7924 assert((VT == MVT::f16 || VT == MVT::bf16) && "Unexpected type");
7925
7926 SDValue Mag = Op.getOperand(0);
7927 SDValue Sign = Op.getOperand(1);
7928
7929 SDLoc DL(Op);
7930
7931 // Get sign bit into an integer value.
7932 unsigned SignSize = Sign.getValueSizeInBits();
7933 SDValue SignAsInt = [&]() {
7934 if (SignSize == Subtarget.getXLen())
7935 return DAG.getNode(ISD::BITCAST, DL, XLenVT, Sign);
7936 switch (SignSize) {
7937 case 16:
7938 return DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Sign);
7939 case 32:
7940 return DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, XLenVT, Sign);
7941 case 64: {
7942 assert(XLenVT == MVT::i32 && "Unexpected type");
7943 // Copy the upper word to integer.
7944 SignSize = 32;
7945 return DAG.getNode(RISCVISD::SplitF64, DL, {MVT::i32, MVT::i32}, Sign)
7946 .getValue(1);
7947 }
7948 default:
7949 llvm_unreachable("Unexpected sign size");
7950 }
7951 }();
7952
7953 // Get the signbit at the right position for MagAsInt.
7954 if (int ShiftAmount = (int)SignSize - (int)Mag.getValueSizeInBits())
7955 SignAsInt = DAG.getNode(ShiftAmount > 0 ? ISD::SRL : ISD::SHL, DL, XLenVT,
7956 SignAsInt,
7957 DAG.getConstant(std::abs(ShiftAmount), DL, XLenVT));
7958
7959 // Mask the sign bit and any bits above it. The extra bits will be dropped
7960 // when we convert back to FP.
7961 SDValue SignMask = DAG.getConstant(
7962 APInt::getSignMask(16).sext(Subtarget.getXLen()), DL, XLenVT);
7963 SDValue SignBit = DAG.getNode(ISD::AND, DL, XLenVT, SignAsInt, SignMask);
7964
7965 // Transform Mag value to integer, and clear the sign bit.
7966 SDValue MagAsInt = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Mag);
7967 SDValue ClearSignMask = DAG.getConstant(
7968 APInt::getSignedMaxValue(16).sext(Subtarget.getXLen()), DL, XLenVT);
7969 SDValue ClearedSign =
7970 DAG.getNode(ISD::AND, DL, XLenVT, MagAsInt, ClearSignMask);
7971
7972 SDValue CopiedSign = DAG.getNode(ISD::OR, DL, XLenVT, ClearedSign, SignBit,
7974
7975 return DAG.getNode(RISCVISD::FMV_H_X, DL, VT, CopiedSign);
7976}
7977
7978/// Get a RISC-V target specified VL op for a given SDNode.
7979static unsigned getRISCVVLOp(SDValue Op) {
7980#define OP_CASE(NODE) \
7981 case ISD::NODE: \
7982 return RISCVISD::NODE##_VL;
7983#define VP_CASE(NODE) \
7984 case ISD::VP_##NODE: \
7985 return RISCVISD::NODE##_VL;
7986 // clang-format off
7987 switch (Op.getOpcode()) {
7988 default:
7989 llvm_unreachable("don't have RISC-V specified VL op for this SDNode");
7990 OP_CASE(ADD)
7991 OP_CASE(SUB)
7992 OP_CASE(MUL)
7993 OP_CASE(MULHS)
7994 OP_CASE(MULHU)
7995 OP_CASE(SDIV)
7996 OP_CASE(SREM)
7997 OP_CASE(UDIV)
7998 OP_CASE(UREM)
7999 OP_CASE(SHL)
8000 OP_CASE(SRA)
8001 OP_CASE(SRL)
8002 OP_CASE(ROTL)
8003 OP_CASE(ROTR)
8004 OP_CASE(BSWAP)
8005 OP_CASE(CTTZ)
8006 OP_CASE(CTLZ)
8007 OP_CASE(CTPOP)
8008 OP_CASE(BITREVERSE)
8009 OP_CASE(CLMUL)
8010 OP_CASE(CLMULH)
8011 OP_CASE(SADDSAT)
8012 OP_CASE(UADDSAT)
8013 OP_CASE(SSUBSAT)
8014 OP_CASE(USUBSAT)
8015 OP_CASE(AVGFLOORS)
8016 OP_CASE(AVGFLOORU)
8017 OP_CASE(AVGCEILS)
8018 OP_CASE(AVGCEILU)
8019 OP_CASE(FADD)
8020 OP_CASE(FSUB)
8021 OP_CASE(FMUL)
8022 OP_CASE(FDIV)
8023 OP_CASE(FNEG)
8024 OP_CASE(FABS)
8025 OP_CASE(FCOPYSIGN)
8026 OP_CASE(FSQRT)
8027 OP_CASE(SMIN)
8028 OP_CASE(SMAX)
8029 OP_CASE(UMIN)
8030 OP_CASE(UMAX)
8031 OP_CASE(ABDS)
8032 OP_CASE(ABDU)
8033 OP_CASE(STRICT_FADD)
8034 OP_CASE(STRICT_FSUB)
8035 OP_CASE(STRICT_FMUL)
8036 OP_CASE(STRICT_FDIV)
8037 OP_CASE(STRICT_FSQRT)
8038 VP_CASE(SDIV) // VP_SDIV
8039 VP_CASE(SREM) // VP_SREM
8040 VP_CASE(UDIV) // VP_UDIV
8041 VP_CASE(UREM) // VP_UREM
8043 return RISCVISD::CTLZ_VL;
8045 return RISCVISD::CTTZ_VL;
8046 case ISD::FMA:
8047 return RISCVISD::VFMADD_VL;
8048 case ISD::STRICT_FMA:
8049 return RISCVISD::STRICT_VFMADD_VL;
8050 case ISD::AND:
8051 if (Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8052 return RISCVISD::VMAND_VL;
8053 return RISCVISD::AND_VL;
8054 case ISD::OR:
8055 if (Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8056 return RISCVISD::VMOR_VL;
8057 return RISCVISD::OR_VL;
8058 case ISD::XOR:
8059 if (Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8060 return RISCVISD::VMXOR_VL;
8061 return RISCVISD::XOR_VL;
8062 case ISD::ANY_EXTEND:
8063 case ISD::ZERO_EXTEND:
8064 return RISCVISD::VZEXT_VL;
8065 case ISD::SIGN_EXTEND:
8066 return RISCVISD::VSEXT_VL;
8067 case ISD::SETCC:
8068 return RISCVISD::SETCC_VL;
8069 case ISD::VSELECT:
8070 return RISCVISD::VMERGE_VL;
8071 case ISD::VP_MERGE:
8072 return RISCVISD::VMERGE_VL;
8073 case ISD::FMINNUM:
8074 case ISD::FMINIMUMNUM:
8075 return RISCVISD::VFMIN_VL;
8076 case ISD::FMAXNUM:
8077 case ISD::FMAXIMUMNUM:
8078 return RISCVISD::VFMAX_VL;
8079 case ISD::LRINT:
8080 case ISD::LLRINT:
8081 return RISCVISD::VFCVT_RM_X_F_VL;
8082 case ISD::MASKED_UDIV:
8083 return RISCVISD::UDIV_VL;
8084 case ISD::MASKED_UREM:
8085 return RISCVISD::UREM_VL;
8086 case ISD::MASKED_SDIV:
8087 return RISCVISD::SDIV_VL;
8088 case ISD::MASKED_SREM:
8089 return RISCVISD::SREM_VL;
8090 }
8091 // clang-format on
8092#undef OP_CASE
8093#undef VP_CASE
8094}
8095
8097 const RISCVSubtarget &Subtarget,
8098 const TargetLowering &TLI) {
8099 MVT OpVT = Op.getSimpleValueType();
8100 if (!OpVT.isVector())
8101 return false;
8102 MVT EltVT = OpVT.getVectorElementType();
8103 if (!(EltVT == MVT::f16 && Subtarget.hasVInstructionsF16Minimal() &&
8104 !Subtarget.hasVInstructionsF16()) &&
8105 !(EltVT == MVT::bf16 && Subtarget.hasVInstructionsBF16Minimal() &&
8106 (!Subtarget.hasVInstructionsBF16() ||
8107 !llvm::is_contained(ZvfbfaOps, Op.getOpcode()))))
8108 return false;
8109 // Need to split when the same width f32 vector type isn't legal.
8110 return !TLI.isTypeLegal(
8111 MVT::getVectorVT(MVT::f32, OpVT.getVectorElementCount()));
8112}
8113
8115 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(Op.getValueType());
8116 SDLoc DL(Op);
8117
8118 SmallVector<SDValue, 4> LoOperands(Op.getNumOperands());
8119 SmallVector<SDValue, 4> HiOperands(Op.getNumOperands());
8120
8121 for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
8122 if (!Op.getOperand(j).getValueType().isVector()) {
8123 LoOperands[j] = Op.getOperand(j);
8124 HiOperands[j] = Op.getOperand(j);
8125 continue;
8126 }
8127 std::tie(LoOperands[j], HiOperands[j]) =
8128 DAG.SplitVector(Op.getOperand(j), DL);
8129 }
8130
8131 SDValue LoRes =
8132 DAG.getNode(Op.getOpcode(), DL, LoVT, LoOperands, Op->getFlags());
8133 SDValue HiRes =
8134 DAG.getNode(Op.getOpcode(), DL, HiVT, HiOperands, Op->getFlags());
8135
8136 return DAG.getNode(ISD::CONCAT_VECTORS, DL, Op.getValueType(), LoRes, HiRes);
8137}
8138
8140 bool IsVP) {
8141 SDLoc DL(Op);
8142
8143 if (IsVP) {
8144 auto [Lo, Hi] = DAG.SplitVector(Op.getOperand(1), DL);
8145 auto [MaskLo, MaskHi] = DAG.SplitVector(Op.getOperand(2), DL);
8146 auto [EVLLo, EVLHi] =
8147 DAG.SplitEVL(Op.getOperand(3), Op.getOperand(1).getValueType(), DL);
8148
8149 SDValue ResLo =
8150 DAG.getNode(Op.getOpcode(), DL, Op.getValueType(),
8151 {Op.getOperand(0), Lo, MaskLo, EVLLo}, Op->getFlags());
8152 return DAG.getNode(Op.getOpcode(), DL, Op.getValueType(),
8153 {ResLo, Hi, MaskHi, EVLHi}, Op->getFlags());
8154 }
8155
8156 unsigned Opcode = Op.getOpcode();
8157 unsigned OpNo = Opcode == ISD::VECREDUCE_SEQ_FADD ? 1 : 0;
8158
8159 auto [Lo, Hi] = DAG.SplitVector(Op.getOperand(OpNo), DL);
8160 if (Opcode == ISD::VECREDUCE_SEQ_FADD) {
8161 SDValue ResLo = DAG.getNode(Op.getOpcode(), DL, Op.getValueType(),
8162 Op.getOperand(0), Lo, Op->getFlags());
8163 return DAG.getNode(Op.getOpcode(), DL, Op.getValueType(), ResLo, Hi,
8164 Op->getFlags());
8165 }
8166
8167 SDValue ResLo =
8168 DAG.getNode(Op.getOpcode(), DL, Op.getValueType(), Lo, Op->getFlags());
8169 SDValue ResHi =
8170 DAG.getNode(Op.getOpcode(), DL, Op.getValueType(), Hi, Op->getFlags());
8171 unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Op.getOpcode());
8172 return DAG.getNode(BaseOpc, DL, Op.getValueType(), ResLo, ResHi,
8173 Op->getFlags());
8174}
8175
8177
8178 assert(Op->isStrictFPOpcode());
8179
8180 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(Op->getValueType(0));
8181
8182 SDVTList LoVTs = DAG.getVTList(LoVT, Op->getValueType(1));
8183 SDVTList HiVTs = DAG.getVTList(HiVT, Op->getValueType(1));
8184
8185 SDLoc DL(Op);
8186
8187 SmallVector<SDValue, 4> LoOperands(Op.getNumOperands());
8188 SmallVector<SDValue, 4> HiOperands(Op.getNumOperands());
8189
8190 for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
8191 if (!Op.getOperand(j).getValueType().isVector()) {
8192 LoOperands[j] = Op.getOperand(j);
8193 HiOperands[j] = Op.getOperand(j);
8194 continue;
8195 }
8196 std::tie(LoOperands[j], HiOperands[j]) =
8197 DAG.SplitVector(Op.getOperand(j), DL);
8198 }
8199
8200 SDValue LoRes =
8201 DAG.getNode(Op.getOpcode(), DL, LoVTs, LoOperands, Op->getFlags());
8202 HiOperands[0] = LoRes.getValue(1);
8203 SDValue HiRes =
8204 DAG.getNode(Op.getOpcode(), DL, HiVTs, HiOperands, Op->getFlags());
8205
8206 SDValue V = DAG.getNode(ISD::CONCAT_VECTORS, DL, Op->getValueType(0),
8207 LoRes.getValue(0), HiRes.getValue(0));
8208 return DAG.getMergeValues({V, HiRes.getValue(1)}, DL);
8209}
8210
8211SDValue
8212RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Load(SDValue Op,
8213 SelectionDAG &DAG) const {
8214 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
8215 "Unexpected bfloat16 load lowering");
8216
8217 SDLoc DL(Op);
8218 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
8219 EVT MemVT = LD->getMemoryVT();
8220 SDValue Load = DAG.getExtLoad(
8221 ISD::ZEXTLOAD, DL, Subtarget.getXLenVT(), LD->getChain(),
8222 LD->getBasePtr(),
8224 LD->getMemOperand());
8225 // Using mask to make bf16 nan-boxing valid when we don't have flh
8226 // instruction. -65536 would be treat as a small number and thus it can be
8227 // directly used lui to get the constant.
8228 SDValue mask = DAG.getSignedConstant(-65536, DL, Subtarget.getXLenVT());
8229 SDValue OrSixteenOne =
8230 DAG.getNode(ISD::OR, DL, Load.getValueType(), {Load, mask});
8231 SDValue ConvertedResult =
8232 DAG.getNode(RISCVISD::NDS_FMV_BF16_X, DL, MVT::bf16, OrSixteenOne);
8233 return DAG.getMergeValues({ConvertedResult, Load.getValue(1)}, DL);
8234}
8235
8236SDValue
8237RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Store(SDValue Op,
8238 SelectionDAG &DAG) const {
8239 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
8240 "Unexpected bfloat16 store lowering");
8241
8242 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
8243 SDLoc DL(Op);
8244 SDValue FMV = DAG.getNode(RISCVISD::NDS_FMV_X_ANYEXTBF16, DL,
8245 Subtarget.getXLenVT(), ST->getValue());
8246 return DAG.getTruncStore(
8247 ST->getChain(), DL, FMV, ST->getBasePtr(),
8248 EVT::getIntegerVT(*DAG.getContext(), ST->getMemoryVT().getSizeInBits()),
8249 ST->getMemOperand());
8250}
8251
8253 const RISCVSubtarget &Subtarget);
8254
8256 SelectionDAG &DAG) const {
8257 switch (Op.getOpcode()) {
8258 default:
8260 "Unimplemented RISCVTargetLowering::LowerOperation Case");
8261 case ISD::PREFETCH:
8262 return LowerPREFETCH(Op, Subtarget, DAG);
8263 case ISD::ATOMIC_FENCE:
8264 return LowerATOMIC_FENCE(Op, DAG, Subtarget);
8265 case ISD::GlobalAddress:
8266 return lowerGlobalAddress(Op, DAG);
8267 case ISD::BlockAddress:
8268 return lowerBlockAddress(Op, DAG);
8269 case ISD::ConstantPool:
8270 return lowerConstantPool(Op, DAG);
8271 case ISD::JumpTable:
8272 return lowerJumpTable(Op, DAG);
8274 return lowerGlobalTLSAddress(Op, DAG);
8275 case ISD::Constant:
8276 return lowerConstant(Op, DAG, Subtarget);
8277 case ISD::ConstantFP:
8278 return lowerConstantFP(Op, DAG);
8279 case ISD::SELECT:
8280 return lowerSELECT(Op, DAG);
8281 case ISD::BRCOND:
8282 return lowerBRCOND(Op, DAG);
8283 case ISD::VASTART:
8284 return lowerVASTART(Op, DAG);
8285 case ISD::FRAMEADDR:
8286 return lowerFRAMEADDR(Op, DAG);
8287 case ISD::RETURNADDR:
8288 return lowerRETURNADDR(Op, DAG);
8289 case ISD::SHL_PARTS:
8290 return lowerShiftLeftParts(Op, DAG);
8291 case ISD::SRA_PARTS:
8292 return lowerShiftRightParts(Op, DAG, true);
8293 case ISD::SRL_PARTS:
8294 return lowerShiftRightParts(Op, DAG, false);
8295 case ISD::ROTL:
8296 case ISD::ROTR:
8297 if (Op.getValueType().isFixedLengthVector()) {
8298 assert(Subtarget.hasStdExtZvkb());
8299 return lowerToScalableOp(Op, DAG);
8300 }
8301 assert(Subtarget.hasVendorXTHeadBb() &&
8302 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
8303 "Unexpected custom legalization");
8304 // XTHeadBb only supports rotate by constant.
8305 if (!isa<ConstantSDNode>(Op.getOperand(1)))
8306 return