LLVM 22.0.0git
RISCVISelDAGToDAG.cpp
Go to the documentation of this file.
1//===-- RISCVISelDAGToDAG.cpp - A dag to dag inst selector for RISC-V -----===//
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 an instruction selector for the RISC-V target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVISelDAGToDAG.h"
17#include "RISCVISelLowering.h"
18#include "RISCVInstrInfo.h"
22#include "llvm/IR/IntrinsicsRISCV.h"
24#include "llvm/Support/Debug.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE "riscv-isel"
31#define PASS_NAME "RISC-V DAG->DAG Pattern Instruction Selection"
32
34 "riscv-use-rematerializable-movimm", cl::Hidden,
35 cl::desc("Use a rematerializable pseudoinstruction for 2 instruction "
36 "constant materialization"),
37 cl::init(false));
38
39#define GET_DAGISEL_BODY RISCVDAGToDAGISel
40#include "RISCVGenDAGISel.inc"
41
43 SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end();
44
45 bool MadeChange = false;
46 while (Position != CurDAG->allnodes_begin()) {
47 SDNode *N = &*--Position;
48 if (N->use_empty())
49 continue;
50
51 SDValue Result;
52 switch (N->getOpcode()) {
53 case ISD::SPLAT_VECTOR: {
54 // Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
55 // SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
56 MVT VT = N->getSimpleValueType(0);
57 unsigned Opc =
58 VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL;
59 SDLoc DL(N);
60 SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
61 SDValue Src = N->getOperand(0);
62 if (VT.isInteger())
63 Src = CurDAG->getNode(ISD::ANY_EXTEND, DL, Subtarget->getXLenVT(),
64 N->getOperand(0));
65 Result = CurDAG->getNode(Opc, DL, VT, CurDAG->getUNDEF(VT), Src, VL);
66 break;
67 }
68 case RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL: {
69 // Lower SPLAT_VECTOR_SPLIT_I64 to two scalar stores and a stride 0 vector
70 // load. Done after lowering and combining so that we have a chance to
71 // optimize this to VMV_V_X_VL when the upper bits aren't needed.
72 assert(N->getNumOperands() == 4 && "Unexpected number of operands");
73 MVT VT = N->getSimpleValueType(0);
74 SDValue Passthru = N->getOperand(0);
75 SDValue Lo = N->getOperand(1);
76 SDValue Hi = N->getOperand(2);
77 SDValue VL = N->getOperand(3);
78 assert(VT.getVectorElementType() == MVT::i64 && VT.isScalableVector() &&
79 Lo.getValueType() == MVT::i32 && Hi.getValueType() == MVT::i32 &&
80 "Unexpected VTs!");
81 MachineFunction &MF = CurDAG->getMachineFunction();
82 SDLoc DL(N);
83
84 // Create temporary stack for each expanding node.
85 SDValue StackSlot =
86 CurDAG->CreateStackTemporary(TypeSize::getFixed(8), Align(8));
87 int FI = cast<FrameIndexSDNode>(StackSlot.getNode())->getIndex();
89
90 SDValue Chain = CurDAG->getEntryNode();
91 Lo = CurDAG->getStore(Chain, DL, Lo, StackSlot, MPI, Align(8));
92
93 SDValue OffsetSlot =
94 CurDAG->getMemBasePlusOffset(StackSlot, TypeSize::getFixed(4), DL);
95 Hi = CurDAG->getStore(Chain, DL, Hi, OffsetSlot, MPI.getWithOffset(4),
96 Align(8));
97
98 Chain = CurDAG->getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
99
100 SDVTList VTs = CurDAG->getVTList({VT, MVT::Other});
101 SDValue IntID =
102 CurDAG->getTargetConstant(Intrinsic::riscv_vlse, DL, MVT::i64);
103 SDValue Ops[] = {Chain,
104 IntID,
105 Passthru,
106 StackSlot,
107 CurDAG->getRegister(RISCV::X0, MVT::i64),
108 VL};
109
110 Result = CurDAG->getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, DL, VTs, Ops,
111 MVT::i64, MPI, Align(8),
113 break;
114 }
115 case ISD::FP_EXTEND: {
116 // We only have vector patterns for riscv_fpextend_vl in isel.
117 SDLoc DL(N);
118 MVT VT = N->getSimpleValueType(0);
119 if (!VT.isVector())
120 break;
121 SDValue VLMAX = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
122 SDValue TrueMask = CurDAG->getNode(
123 RISCVISD::VMSET_VL, DL, VT.changeVectorElementType(MVT::i1), VLMAX);
124 Result = CurDAG->getNode(RISCVISD::FP_EXTEND_VL, DL, VT, N->getOperand(0),
125 TrueMask, VLMAX);
126 break;
127 }
128 }
129
130 if (Result) {
131 LLVM_DEBUG(dbgs() << "RISC-V DAG preprocessing replacing:\nOld: ");
132 LLVM_DEBUG(N->dump(CurDAG));
133 LLVM_DEBUG(dbgs() << "\nNew: ");
134 LLVM_DEBUG(Result->dump(CurDAG));
135 LLVM_DEBUG(dbgs() << "\n");
136
137 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Result);
138 MadeChange = true;
139 }
140 }
141
142 if (MadeChange)
143 CurDAG->RemoveDeadNodes();
144}
145
147 HandleSDNode Dummy(CurDAG->getRoot());
148 SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end();
149
150 bool MadeChange = false;
151 while (Position != CurDAG->allnodes_begin()) {
152 SDNode *N = &*--Position;
153 // Skip dead nodes and any non-machine opcodes.
154 if (N->use_empty() || !N->isMachineOpcode())
155 continue;
156
157 MadeChange |= doPeepholeSExtW(N);
158
159 // FIXME: This is here only because the VMerge transform doesn't
160 // know how to handle masked true inputs. Once that has been moved
161 // to post-ISEL, this can be deleted as well.
162 MadeChange |= doPeepholeMaskedRVV(cast<MachineSDNode>(N));
163 }
164
165 CurDAG->setRoot(Dummy.getValue());
166
167 // After we're done with everything else, convert IMPLICIT_DEF
168 // passthru operands to NoRegister. This is required to workaround
169 // an optimization deficiency in MachineCSE. This really should
170 // be merged back into each of the patterns (i.e. there's no good
171 // reason not to go directly to NoReg), but is being done this way
172 // to allow easy backporting.
173 MadeChange |= doPeepholeNoRegPassThru();
174
175 if (MadeChange)
176 CurDAG->RemoveDeadNodes();
177}
178
179static SDValue selectImmSeq(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
181 SDValue SrcReg = CurDAG->getRegister(RISCV::X0, VT);
182 for (const RISCVMatInt::Inst &Inst : Seq) {
183 SDValue SDImm = CurDAG->getSignedTargetConstant(Inst.getImm(), DL, VT);
184 SDNode *Result = nullptr;
185 switch (Inst.getOpndKind()) {
186 case RISCVMatInt::Imm:
187 Result = CurDAG->getMachineNode(Inst.getOpcode(), DL, VT, SDImm);
188 break;
190 Result = CurDAG->getMachineNode(Inst.getOpcode(), DL, VT, SrcReg,
191 CurDAG->getRegister(RISCV::X0, VT));
192 break;
194 Result = CurDAG->getMachineNode(Inst.getOpcode(), DL, VT, SrcReg, SrcReg);
195 break;
197 Result = CurDAG->getMachineNode(Inst.getOpcode(), DL, VT, SrcReg, SDImm);
198 break;
199 }
200
201 // Only the first instruction has X0 as its source.
202 SrcReg = SDValue(Result, 0);
203 }
204
205 return SrcReg;
206}
207
208static SDValue selectImm(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
209 int64_t Imm, const RISCVSubtarget &Subtarget) {
211
212 // Use a rematerializable pseudo instruction for short sequences if enabled.
213 if (Seq.size() == 2 && UsePseudoMovImm)
214 return SDValue(
215 CurDAG->getMachineNode(RISCV::PseudoMovImm, DL, VT,
216 CurDAG->getSignedTargetConstant(Imm, DL, VT)),
217 0);
218
219 // See if we can create this constant as (ADD (SLLI X, C), X) where X is at
220 // worst an LUI+ADDIW. This will require an extra register, but avoids a
221 // constant pool.
222 // If we have Zba we can use (ADD_UW X, (SLLI X, 32)) to handle cases where
223 // low and high 32 bits are the same and bit 31 and 63 are set.
224 if (Seq.size() > 3) {
225 unsigned ShiftAmt, AddOpc;
227 RISCVMatInt::generateTwoRegInstSeq(Imm, Subtarget, ShiftAmt, AddOpc);
228 if (!SeqLo.empty() && (SeqLo.size() + 2) < Seq.size()) {
229 SDValue Lo = selectImmSeq(CurDAG, DL, VT, SeqLo);
230
231 SDValue SLLI = SDValue(
232 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, Lo,
233 CurDAG->getTargetConstant(ShiftAmt, DL, VT)),
234 0);
235 return SDValue(CurDAG->getMachineNode(AddOpc, DL, VT, Lo, SLLI), 0);
236 }
237 }
238
239 // Otherwise, use the original sequence.
240 return selectImmSeq(CurDAG, DL, VT, Seq);
241}
242
244 SDNode *Node, unsigned Log2SEW, const SDLoc &DL, unsigned CurOp,
245 bool IsMasked, bool IsStridedOrIndexed, SmallVectorImpl<SDValue> &Operands,
246 bool IsLoad, MVT *IndexVT) {
247 SDValue Chain = Node->getOperand(0);
248
249 Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
250
251 if (IsStridedOrIndexed) {
252 Operands.push_back(Node->getOperand(CurOp++)); // Index.
253 if (IndexVT)
254 *IndexVT = Operands.back()->getSimpleValueType(0);
255 }
256
257 if (IsMasked) {
258 SDValue Mask = Node->getOperand(CurOp++);
259 Operands.push_back(Mask);
260 }
261 SDValue VL;
262 selectVLOp(Node->getOperand(CurOp++), VL);
263 Operands.push_back(VL);
264
265 MVT XLenVT = Subtarget->getXLenVT();
266 SDValue SEWOp = CurDAG->getTargetConstant(Log2SEW, DL, XLenVT);
267 Operands.push_back(SEWOp);
268
269 // At the IR layer, all the masked load intrinsics have policy operands,
270 // none of the others do. All have passthru operands. For our pseudos,
271 // all loads have policy operands.
272 if (IsLoad) {
274 if (IsMasked)
275 Policy = Node->getConstantOperandVal(CurOp++);
276 SDValue PolicyOp = CurDAG->getTargetConstant(Policy, DL, XLenVT);
277 Operands.push_back(PolicyOp);
278 }
279
280 Operands.push_back(Chain); // Chain.
281}
282
283void RISCVDAGToDAGISel::selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked,
284 bool IsStrided) {
285 SDLoc DL(Node);
286 MVT VT = Node->getSimpleValueType(0);
287 unsigned Log2SEW = Node->getConstantOperandVal(Node->getNumOperands() - 1);
289
290 unsigned CurOp = 2;
292
293 Operands.push_back(Node->getOperand(CurOp++));
294
295 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
296 Operands, /*IsLoad=*/true);
297
298 const RISCV::VLSEGPseudo *P =
299 RISCV::getVLSEGPseudo(NF, IsMasked, IsStrided, /*FF*/ false, Log2SEW,
300 static_cast<unsigned>(LMUL));
301 MachineSDNode *Load =
302 CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands);
303
304 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
305
306 ReplaceUses(SDValue(Node, 0), SDValue(Load, 0));
307 ReplaceUses(SDValue(Node, 1), SDValue(Load, 1));
308 CurDAG->RemoveDeadNode(Node);
309}
310
312 bool IsMasked) {
313 SDLoc DL(Node);
314 MVT VT = Node->getSimpleValueType(0);
315 MVT XLenVT = Subtarget->getXLenVT();
316 unsigned Log2SEW = Node->getConstantOperandVal(Node->getNumOperands() - 1);
318
319 unsigned CurOp = 2;
321
322 Operands.push_back(Node->getOperand(CurOp++));
323
324 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
325 /*IsStridedOrIndexed*/ false, Operands,
326 /*IsLoad=*/true);
327
328 const RISCV::VLSEGPseudo *P =
329 RISCV::getVLSEGPseudo(NF, IsMasked, /*Strided*/ false, /*FF*/ true,
330 Log2SEW, static_cast<unsigned>(LMUL));
331 MachineSDNode *Load = CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped,
332 XLenVT, MVT::Other, Operands);
333
334 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
335
336 ReplaceUses(SDValue(Node, 0), SDValue(Load, 0)); // Result
337 ReplaceUses(SDValue(Node, 1), SDValue(Load, 1)); // VL
338 ReplaceUses(SDValue(Node, 2), SDValue(Load, 2)); // Chain
339 CurDAG->RemoveDeadNode(Node);
340}
341
342void RISCVDAGToDAGISel::selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked,
343 bool IsOrdered) {
344 SDLoc DL(Node);
345 MVT VT = Node->getSimpleValueType(0);
346 unsigned Log2SEW = Node->getConstantOperandVal(Node->getNumOperands() - 1);
348
349 unsigned CurOp = 2;
351
352 Operands.push_back(Node->getOperand(CurOp++));
353
354 MVT IndexVT;
355 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
356 /*IsStridedOrIndexed*/ true, Operands,
357 /*IsLoad=*/true, &IndexVT);
358
359#ifndef NDEBUG
360 // Number of element = RVVBitsPerBlock * LMUL / SEW
361 unsigned ContainedTyNumElts = RISCV::RVVBitsPerBlock >> Log2SEW;
362 auto DecodedLMUL = RISCVVType::decodeVLMUL(LMUL);
363 if (DecodedLMUL.second)
364 ContainedTyNumElts /= DecodedLMUL.first;
365 else
366 ContainedTyNumElts *= DecodedLMUL.first;
367 assert(ContainedTyNumElts == IndexVT.getVectorMinNumElements() &&
368 "Element count mismatch");
369#endif
370
372 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
373 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
374 report_fatal_error("The V extension does not support EEW=64 for index "
375 "values when XLEN=32");
376 }
377 const RISCV::VLXSEGPseudo *P = RISCV::getVLXSEGPseudo(
378 NF, IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
379 static_cast<unsigned>(IndexLMUL));
380 MachineSDNode *Load =
381 CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands);
382
383 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
384
385 ReplaceUses(SDValue(Node, 0), SDValue(Load, 0));
386 ReplaceUses(SDValue(Node, 1), SDValue(Load, 1));
387 CurDAG->RemoveDeadNode(Node);
388}
389
390void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked,
391 bool IsStrided) {
392 SDLoc DL(Node);
393 MVT VT = Node->getOperand(2)->getSimpleValueType(0);
394 unsigned Log2SEW = Node->getConstantOperandVal(Node->getNumOperands() - 1);
396
397 unsigned CurOp = 2;
399
400 Operands.push_back(Node->getOperand(CurOp++));
401
402 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
403 Operands);
404
405 const RISCV::VSSEGPseudo *P = RISCV::getVSSEGPseudo(
406 NF, IsMasked, IsStrided, Log2SEW, static_cast<unsigned>(LMUL));
407 MachineSDNode *Store =
408 CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
409
410 CurDAG->setNodeMemRefs(Store, {cast<MemSDNode>(Node)->getMemOperand()});
411
412 ReplaceNode(Node, Store);
413}
414
415void RISCVDAGToDAGISel::selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked,
416 bool IsOrdered) {
417 SDLoc DL(Node);
418 MVT VT = Node->getOperand(2)->getSimpleValueType(0);
419 unsigned Log2SEW = Node->getConstantOperandVal(Node->getNumOperands() - 1);
421
422 unsigned CurOp = 2;
424
425 Operands.push_back(Node->getOperand(CurOp++));
426
427 MVT IndexVT;
428 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
429 /*IsStridedOrIndexed*/ true, Operands,
430 /*IsLoad=*/false, &IndexVT);
431
432#ifndef NDEBUG
433 // Number of element = RVVBitsPerBlock * LMUL / SEW
434 unsigned ContainedTyNumElts = RISCV::RVVBitsPerBlock >> Log2SEW;
435 auto DecodedLMUL = RISCVVType::decodeVLMUL(LMUL);
436 if (DecodedLMUL.second)
437 ContainedTyNumElts /= DecodedLMUL.first;
438 else
439 ContainedTyNumElts *= DecodedLMUL.first;
440 assert(ContainedTyNumElts == IndexVT.getVectorMinNumElements() &&
441 "Element count mismatch");
442#endif
443
445 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
446 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
447 report_fatal_error("The V extension does not support EEW=64 for index "
448 "values when XLEN=32");
449 }
450 const RISCV::VSXSEGPseudo *P = RISCV::getVSXSEGPseudo(
451 NF, IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
452 static_cast<unsigned>(IndexLMUL));
453 MachineSDNode *Store =
454 CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
455
456 CurDAG->setNodeMemRefs(Store, {cast<MemSDNode>(Node)->getMemOperand()});
457
458 ReplaceNode(Node, Store);
459}
460
462 if (!Subtarget->hasVInstructions())
463 return;
464
465 assert(Node->getOpcode() == ISD::INTRINSIC_WO_CHAIN && "Unexpected opcode");
466
467 SDLoc DL(Node);
468 MVT XLenVT = Subtarget->getXLenVT();
469
470 unsigned IntNo = Node->getConstantOperandVal(0);
471
472 assert((IntNo == Intrinsic::riscv_vsetvli ||
473 IntNo == Intrinsic::riscv_vsetvlimax) &&
474 "Unexpected vsetvli intrinsic");
475
476 bool VLMax = IntNo == Intrinsic::riscv_vsetvlimax;
477 unsigned Offset = (VLMax ? 1 : 2);
478
479 assert(Node->getNumOperands() == Offset + 2 &&
480 "Unexpected number of operands");
481
482 unsigned SEW =
483 RISCVVType::decodeVSEW(Node->getConstantOperandVal(Offset) & 0x7);
484 RISCVVType::VLMUL VLMul = static_cast<RISCVVType::VLMUL>(
485 Node->getConstantOperandVal(Offset + 1) & 0x7);
486
487 unsigned VTypeI = RISCVVType::encodeVTYPE(VLMul, SEW, /*TailAgnostic*/ true,
488 /*MaskAgnostic*/ true);
489 SDValue VTypeIOp = CurDAG->getTargetConstant(VTypeI, DL, XLenVT);
490
491 SDValue VLOperand;
492 unsigned Opcode = RISCV::PseudoVSETVLI;
493 if (auto *C = dyn_cast<ConstantSDNode>(Node->getOperand(1))) {
494 if (auto VLEN = Subtarget->getRealVLen())
495 if (*VLEN / RISCVVType::getSEWLMULRatio(SEW, VLMul) == C->getZExtValue())
496 VLMax = true;
497 }
498 if (VLMax || isAllOnesConstant(Node->getOperand(1))) {
499 VLOperand = CurDAG->getRegister(RISCV::X0, XLenVT);
500 Opcode = RISCV::PseudoVSETVLIX0;
501 } else {
502 VLOperand = Node->getOperand(1);
503
504 if (auto *C = dyn_cast<ConstantSDNode>(VLOperand)) {
505 uint64_t AVL = C->getZExtValue();
506 if (isUInt<5>(AVL)) {
507 SDValue VLImm = CurDAG->getTargetConstant(AVL, DL, XLenVT);
508 ReplaceNode(Node, CurDAG->getMachineNode(RISCV::PseudoVSETIVLI, DL,
509 XLenVT, VLImm, VTypeIOp));
510 return;
511 }
512 }
513 }
514
516 CurDAG->getMachineNode(Opcode, DL, XLenVT, VLOperand, VTypeIOp));
517}
518
520 MVT VT = Node->getSimpleValueType(0);
521 unsigned Opcode = Node->getOpcode();
522 assert((Opcode == ISD::AND || Opcode == ISD::OR || Opcode == ISD::XOR) &&
523 "Unexpected opcode");
524 SDLoc DL(Node);
525
526 // For operations of the form (x << C1) op C2, check if we can use
527 // ANDI/ORI/XORI by transforming it into (x op (C2>>C1)) << C1.
528 SDValue N0 = Node->getOperand(0);
529 SDValue N1 = Node->getOperand(1);
530
532 if (!Cst)
533 return false;
534
535 int64_t Val = Cst->getSExtValue();
536
537 // Check if immediate can already use ANDI/ORI/XORI.
538 if (isInt<12>(Val))
539 return false;
540
541 SDValue Shift = N0;
542
543 // If Val is simm32 and we have a sext_inreg from i32, then the binop
544 // produces at least 33 sign bits. We can peek through the sext_inreg and use
545 // a SLLIW at the end.
546 bool SignExt = false;
547 if (isInt<32>(Val) && N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
548 N0.hasOneUse() && cast<VTSDNode>(N0.getOperand(1))->getVT() == MVT::i32) {
549 SignExt = true;
550 Shift = N0.getOperand(0);
551 }
552
553 if (Shift.getOpcode() != ISD::SHL || !Shift.hasOneUse())
554 return false;
555
557 if (!ShlCst)
558 return false;
559
560 uint64_t ShAmt = ShlCst->getZExtValue();
561
562 // Make sure that we don't change the operation by removing bits.
563 // This only matters for OR and XOR, AND is unaffected.
564 uint64_t RemovedBitsMask = maskTrailingOnes<uint64_t>(ShAmt);
565 if (Opcode != ISD::AND && (Val & RemovedBitsMask) != 0)
566 return false;
567
568 int64_t ShiftedVal = Val >> ShAmt;
569 if (!isInt<12>(ShiftedVal))
570 return false;
571
572 // If we peeked through a sext_inreg, make sure the shift is valid for SLLIW.
573 if (SignExt && ShAmt >= 32)
574 return false;
575
576 // Ok, we can reorder to get a smaller immediate.
577 unsigned BinOpc;
578 switch (Opcode) {
579 default: llvm_unreachable("Unexpected opcode");
580 case ISD::AND: BinOpc = RISCV::ANDI; break;
581 case ISD::OR: BinOpc = RISCV::ORI; break;
582 case ISD::XOR: BinOpc = RISCV::XORI; break;
583 }
584
585 unsigned ShOpc = SignExt ? RISCV::SLLIW : RISCV::SLLI;
586
587 SDNode *BinOp = CurDAG->getMachineNode(
588 BinOpc, DL, VT, Shift.getOperand(0),
589 CurDAG->getSignedTargetConstant(ShiftedVal, DL, VT));
590 SDNode *SLLI =
591 CurDAG->getMachineNode(ShOpc, DL, VT, SDValue(BinOp, 0),
592 CurDAG->getTargetConstant(ShAmt, DL, VT));
593 ReplaceNode(Node, SLLI);
594 return true;
595}
596
598 unsigned Opc;
599
600 if (Subtarget->hasVendorXTHeadBb())
601 Opc = RISCV::TH_EXT;
602 else if (Subtarget->hasVendorXAndesPerf())
603 Opc = RISCV::NDS_BFOS;
604 else if (Subtarget->hasVendorXqcibm())
605 Opc = RISCV::QC_EXT;
606 else
607 // Only supported with XTHeadBb/XAndesPerf/Xqcibm at the moment.
608 return false;
609
610 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
611 if (!N1C)
612 return false;
613
614 SDValue N0 = Node->getOperand(0);
615 if (!N0.hasOneUse())
616 return false;
617
618 auto BitfieldExtract = [&](SDValue N0, unsigned Msb, unsigned Lsb,
619 const SDLoc &DL, MVT VT) {
620 if (Opc == RISCV::QC_EXT) {
621 // QC.EXT X, width, shamt
622 // shamt is the same as Lsb
623 // width is the number of bits to extract from the Lsb
624 Msb = Msb - Lsb + 1;
625 }
626 return CurDAG->getMachineNode(Opc, DL, VT, N0.getOperand(0),
627 CurDAG->getTargetConstant(Msb, DL, VT),
628 CurDAG->getTargetConstant(Lsb, DL, VT));
629 };
630
631 SDLoc DL(Node);
632 MVT VT = Node->getSimpleValueType(0);
633 const unsigned RightShAmt = N1C->getZExtValue();
634
635 // Transform (sra (shl X, C1) C2) with C1 < C2
636 // -> (SignedBitfieldExtract X, msb, lsb)
637 if (N0.getOpcode() == ISD::SHL) {
638 auto *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
639 if (!N01C)
640 return false;
641
642 const unsigned LeftShAmt = N01C->getZExtValue();
643 // Make sure that this is a bitfield extraction (i.e., the shift-right
644 // amount can not be less than the left-shift).
645 if (LeftShAmt > RightShAmt)
646 return false;
647
648 const unsigned MsbPlusOne = VT.getSizeInBits() - LeftShAmt;
649 const unsigned Msb = MsbPlusOne - 1;
650 const unsigned Lsb = RightShAmt - LeftShAmt;
651
652 SDNode *Sbe = BitfieldExtract(N0, Msb, Lsb, DL, VT);
653 ReplaceNode(Node, Sbe);
654 return true;
655 }
656
657 // Transform (sra (sext_inreg X, _), C) ->
658 // (SignedBitfieldExtract X, msb, lsb)
659 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) {
660 unsigned ExtSize =
661 cast<VTSDNode>(N0.getOperand(1))->getVT().getSizeInBits();
662
663 // ExtSize of 32 should use sraiw via tablegen pattern.
664 if (ExtSize == 32)
665 return false;
666
667 const unsigned Msb = ExtSize - 1;
668 // If the shift-right amount is greater than Msb, it means that extracts
669 // the X[Msb] bit and sign-extend it.
670 const unsigned Lsb = RightShAmt > Msb ? Msb : RightShAmt;
671
672 SDNode *Sbe = BitfieldExtract(N0, Msb, Lsb, DL, VT);
673 ReplaceNode(Node, Sbe);
674 return true;
675 }
676
677 return false;
678}
679
681 // Only supported with XAndesPerf at the moment.
682 if (!Subtarget->hasVendorXAndesPerf())
683 return false;
684
685 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
686 if (!N1C)
687 return false;
688
689 SDValue N0 = Node->getOperand(0);
690 if (!N0.hasOneUse())
691 return false;
692
693 auto BitfieldInsert = [&](SDValue N0, unsigned Msb, unsigned Lsb,
694 const SDLoc &DL, MVT VT) {
695 unsigned Opc = RISCV::NDS_BFOS;
696 // If the Lsb is equal to the Msb, then the Lsb should be 0.
697 if (Lsb == Msb)
698 Lsb = 0;
699 return CurDAG->getMachineNode(Opc, DL, VT, N0.getOperand(0),
700 CurDAG->getTargetConstant(Lsb, DL, VT),
701 CurDAG->getTargetConstant(Msb, DL, VT));
702 };
703
704 SDLoc DL(Node);
705 MVT VT = Node->getSimpleValueType(0);
706 const unsigned RightShAmt = N1C->getZExtValue();
707
708 // Transform (sra (shl X, C1) C2) with C1 > C2
709 // -> (NDS.BFOS X, lsb, msb)
710 if (N0.getOpcode() == ISD::SHL) {
711 auto *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
712 if (!N01C)
713 return false;
714
715 const unsigned LeftShAmt = N01C->getZExtValue();
716 // Make sure that this is a bitfield insertion (i.e., the shift-right
717 // amount should be less than the left-shift).
718 if (LeftShAmt <= RightShAmt)
719 return false;
720
721 const unsigned MsbPlusOne = VT.getSizeInBits() - RightShAmt;
722 const unsigned Msb = MsbPlusOne - 1;
723 const unsigned Lsb = LeftShAmt - RightShAmt;
724
725 SDNode *Sbi = BitfieldInsert(N0, Msb, Lsb, DL, VT);
726 ReplaceNode(Node, Sbi);
727 return true;
728 }
729
730 return false;
731}
732
734 const SDLoc &DL, MVT VT,
735 SDValue X, unsigned Msb,
736 unsigned Lsb) {
737 unsigned Opc;
738
739 if (Subtarget->hasVendorXTHeadBb()) {
740 Opc = RISCV::TH_EXTU;
741 } else if (Subtarget->hasVendorXAndesPerf()) {
742 Opc = RISCV::NDS_BFOZ;
743 } else if (Subtarget->hasVendorXqcibm()) {
744 Opc = RISCV::QC_EXTU;
745 // QC.EXTU X, width, shamt
746 // shamt is the same as Lsb
747 // width is the number of bits to extract from the Lsb
748 Msb = Msb - Lsb + 1;
749 } else {
750 // Only supported with XTHeadBb/XAndesPerf/Xqcibm at the moment.
751 return false;
752 }
753
754 SDNode *Ube = CurDAG->getMachineNode(Opc, DL, VT, X,
755 CurDAG->getTargetConstant(Msb, DL, VT),
756 CurDAG->getTargetConstant(Lsb, DL, VT));
757 ReplaceNode(Node, Ube);
758 return true;
759}
760
762 const SDLoc &DL, MVT VT,
763 SDValue X, unsigned Msb,
764 unsigned Lsb) {
765 // Only supported with XAndesPerf at the moment.
766 if (!Subtarget->hasVendorXAndesPerf())
767 return false;
768
769 unsigned Opc = RISCV::NDS_BFOZ;
770
771 // If the Lsb is equal to the Msb, then the Lsb should be 0.
772 if (Lsb == Msb)
773 Lsb = 0;
774 SDNode *Ubi = CurDAG->getMachineNode(Opc, DL, VT, X,
775 CurDAG->getTargetConstant(Lsb, DL, VT),
776 CurDAG->getTargetConstant(Msb, DL, VT));
777 ReplaceNode(Node, Ubi);
778 return true;
779}
780
782 // Target does not support indexed loads.
783 if (!Subtarget->hasVendorXTHeadMemIdx())
784 return false;
785
788 if (AM == ISD::UNINDEXED)
789 return false;
790
792 if (!C)
793 return false;
794
795 EVT LoadVT = Ld->getMemoryVT();
796 assert((AM == ISD::PRE_INC || AM == ISD::POST_INC) &&
797 "Unexpected addressing mode");
798 bool IsPre = AM == ISD::PRE_INC;
799 bool IsPost = AM == ISD::POST_INC;
800 int64_t Offset = C->getSExtValue();
801
802 // The constants that can be encoded in the THeadMemIdx instructions
803 // are of the form (sign_extend(imm5) << imm2).
804 unsigned Shift;
805 for (Shift = 0; Shift < 4; Shift++)
806 if (isInt<5>(Offset >> Shift) && ((Offset % (1LL << Shift)) == 0))
807 break;
808
809 // Constant cannot be encoded.
810 if (Shift == 4)
811 return false;
812
813 bool IsZExt = (Ld->getExtensionType() == ISD::ZEXTLOAD);
814 unsigned Opcode;
815 if (LoadVT == MVT::i8 && IsPre)
816 Opcode = IsZExt ? RISCV::TH_LBUIB : RISCV::TH_LBIB;
817 else if (LoadVT == MVT::i8 && IsPost)
818 Opcode = IsZExt ? RISCV::TH_LBUIA : RISCV::TH_LBIA;
819 else if (LoadVT == MVT::i16 && IsPre)
820 Opcode = IsZExt ? RISCV::TH_LHUIB : RISCV::TH_LHIB;
821 else if (LoadVT == MVT::i16 && IsPost)
822 Opcode = IsZExt ? RISCV::TH_LHUIA : RISCV::TH_LHIA;
823 else if (LoadVT == MVT::i32 && IsPre)
824 Opcode = IsZExt ? RISCV::TH_LWUIB : RISCV::TH_LWIB;
825 else if (LoadVT == MVT::i32 && IsPost)
826 Opcode = IsZExt ? RISCV::TH_LWUIA : RISCV::TH_LWIA;
827 else if (LoadVT == MVT::i64 && IsPre)
828 Opcode = RISCV::TH_LDIB;
829 else if (LoadVT == MVT::i64 && IsPost)
830 Opcode = RISCV::TH_LDIA;
831 else
832 return false;
833
834 EVT Ty = Ld->getOffset().getValueType();
835 SDValue Ops[] = {
836 Ld->getBasePtr(),
837 CurDAG->getSignedTargetConstant(Offset >> Shift, SDLoc(Node), Ty),
838 CurDAG->getTargetConstant(Shift, SDLoc(Node), Ty), Ld->getChain()};
839 SDNode *New = CurDAG->getMachineNode(Opcode, SDLoc(Node), Ld->getValueType(0),
840 Ld->getValueType(1), MVT::Other, Ops);
841
842 MachineMemOperand *MemOp = cast<MemSDNode>(Node)->getMemOperand();
843 CurDAG->setNodeMemRefs(cast<MachineSDNode>(New), {MemOp});
844
845 ReplaceNode(Node, New);
846
847 return true;
848}
849
851 if (!Subtarget->hasVInstructions())
852 return;
853
854 assert(Node->getOpcode() == ISD::INTRINSIC_VOID && "Unexpected opcode");
855
856 SDLoc DL(Node);
857 unsigned IntNo = Node->getConstantOperandVal(1);
858
859 assert((IntNo == Intrinsic::riscv_sf_vc_x_se ||
860 IntNo == Intrinsic::riscv_sf_vc_i_se) &&
861 "Unexpected vsetvli intrinsic");
862
863 // imm, imm, imm, simm5/scalar, sew, log2lmul, vl
864 unsigned Log2SEW = Log2_32(Node->getConstantOperandVal(6));
865 SDValue SEWOp =
866 CurDAG->getTargetConstant(Log2SEW, DL, Subtarget->getXLenVT());
867 SmallVector<SDValue, 8> Operands = {Node->getOperand(2), Node->getOperand(3),
868 Node->getOperand(4), Node->getOperand(5),
869 Node->getOperand(8), SEWOp,
870 Node->getOperand(0)};
871
872 unsigned Opcode;
873 auto *LMulSDNode = cast<ConstantSDNode>(Node->getOperand(7));
874 switch (LMulSDNode->getSExtValue()) {
875 case 5:
876 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_MF8
877 : RISCV::PseudoSF_VC_I_SE_MF8;
878 break;
879 case 6:
880 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_MF4
881 : RISCV::PseudoSF_VC_I_SE_MF4;
882 break;
883 case 7:
884 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_MF2
885 : RISCV::PseudoSF_VC_I_SE_MF2;
886 break;
887 case 0:
888 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M1
889 : RISCV::PseudoSF_VC_I_SE_M1;
890 break;
891 case 1:
892 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M2
893 : RISCV::PseudoSF_VC_I_SE_M2;
894 break;
895 case 2:
896 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M4
897 : RISCV::PseudoSF_VC_I_SE_M4;
898 break;
899 case 3:
900 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M8
901 : RISCV::PseudoSF_VC_I_SE_M8;
902 break;
903 }
904
905 ReplaceNode(Node, CurDAG->getMachineNode(
906 Opcode, DL, Node->getSimpleValueType(0), Operands));
907}
908
909static unsigned getSegInstNF(unsigned Intrinsic) {
910#define INST_NF_CASE(NAME, NF) \
911 case Intrinsic::riscv_##NAME##NF: \
912 return NF;
913#define INST_NF_CASE_MASK(NAME, NF) \
914 case Intrinsic::riscv_##NAME##NF##_mask: \
915 return NF;
916#define INST_NF_CASE_FF(NAME, NF) \
917 case Intrinsic::riscv_##NAME##NF##ff: \
918 return NF;
919#define INST_NF_CASE_FF_MASK(NAME, NF) \
920 case Intrinsic::riscv_##NAME##NF##ff_mask: \
921 return NF;
922#define INST_ALL_NF_CASE_BASE(MACRO_NAME, NAME) \
923 MACRO_NAME(NAME, 2) \
924 MACRO_NAME(NAME, 3) \
925 MACRO_NAME(NAME, 4) \
926 MACRO_NAME(NAME, 5) \
927 MACRO_NAME(NAME, 6) \
928 MACRO_NAME(NAME, 7) \
929 MACRO_NAME(NAME, 8)
930#define INST_ALL_NF_CASE(NAME) \
931 INST_ALL_NF_CASE_BASE(INST_NF_CASE, NAME) \
932 INST_ALL_NF_CASE_BASE(INST_NF_CASE_MASK, NAME)
933#define INST_ALL_NF_CASE_WITH_FF(NAME) \
934 INST_ALL_NF_CASE(NAME) \
935 INST_ALL_NF_CASE_BASE(INST_NF_CASE_FF, NAME) \
936 INST_ALL_NF_CASE_BASE(INST_NF_CASE_FF_MASK, NAME)
937 switch (Intrinsic) {
938 default:
939 llvm_unreachable("Unexpected segment load/store intrinsic");
941 INST_ALL_NF_CASE(vlsseg)
942 INST_ALL_NF_CASE(vloxseg)
943 INST_ALL_NF_CASE(vluxseg)
944 INST_ALL_NF_CASE(vsseg)
945 INST_ALL_NF_CASE(vssseg)
946 INST_ALL_NF_CASE(vsoxseg)
947 INST_ALL_NF_CASE(vsuxseg)
948 }
949}
950
952 // If we have a custom node, we have already selected.
953 if (Node->isMachineOpcode()) {
954 LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
955 Node->setNodeId(-1);
956 return;
957 }
958
959 // Instruction Selection not handled by the auto-generated tablegen selection
960 // should be handled here.
961 unsigned Opcode = Node->getOpcode();
962 MVT XLenVT = Subtarget->getXLenVT();
963 SDLoc DL(Node);
964 MVT VT = Node->getSimpleValueType(0);
965
966 bool HasBitTest = Subtarget->hasBEXTILike();
967
968 switch (Opcode) {
969 case ISD::Constant: {
970 assert((VT == Subtarget->getXLenVT() || VT == MVT::i32) && "Unexpected VT");
971 auto *ConstNode = cast<ConstantSDNode>(Node);
972 if (ConstNode->isZero()) {
973 SDValue New =
974 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, RISCV::X0, VT);
975 ReplaceNode(Node, New.getNode());
976 return;
977 }
978 int64_t Imm = ConstNode->getSExtValue();
979 // If only the lower 8 bits are used, try to convert this to a simm6 by
980 // sign-extending bit 7. This is neutral without the C extension, and
981 // allows C.LI to be used if C is present.
982 if (isUInt<8>(Imm) && isInt<6>(SignExtend64<8>(Imm)) && hasAllBUsers(Node))
983 Imm = SignExtend64<8>(Imm);
984 // If the upper XLen-16 bits are not used, try to convert this to a simm12
985 // by sign extending bit 15.
986 if (isUInt<16>(Imm) && isInt<12>(SignExtend64<16>(Imm)) &&
988 Imm = SignExtend64<16>(Imm);
989 // If the upper 32-bits are not used try to convert this into a simm32 by
990 // sign extending bit 32.
991 if (!isInt<32>(Imm) && isUInt<32>(Imm) && hasAllWUsers(Node))
992 Imm = SignExtend64<32>(Imm);
993
994 ReplaceNode(Node, selectImm(CurDAG, DL, VT, Imm, *Subtarget).getNode());
995 return;
996 }
997 case ISD::ConstantFP: {
998 const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
999
1000 bool Is64Bit = Subtarget->is64Bit();
1001 bool HasZdinx = Subtarget->hasStdExtZdinx();
1002
1003 bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
1004 SDValue Imm;
1005 // For +0.0 or f64 -0.0 we need to start from X0. For all others, we will
1006 // create an integer immediate.
1007 if (APF.isPosZero() || NegZeroF64) {
1008 if (VT == MVT::f64 && HasZdinx && !Is64Bit)
1009 Imm = CurDAG->getRegister(RISCV::X0_Pair, MVT::f64);
1010 else
1011 Imm = CurDAG->getRegister(RISCV::X0, XLenVT);
1012 } else {
1013 Imm = selectImm(CurDAG, DL, XLenVT, APF.bitcastToAPInt().getSExtValue(),
1014 *Subtarget);
1015 }
1016
1017 unsigned Opc;
1018 switch (VT.SimpleTy) {
1019 default:
1020 llvm_unreachable("Unexpected size");
1021 case MVT::bf16:
1022 assert(Subtarget->hasStdExtZfbfmin());
1023 Opc = RISCV::FMV_H_X;
1024 break;
1025 case MVT::f16:
1026 Opc = Subtarget->hasStdExtZhinxmin() ? RISCV::COPY : RISCV::FMV_H_X;
1027 break;
1028 case MVT::f32:
1029 Opc = Subtarget->hasStdExtZfinx() ? RISCV::COPY : RISCV::FMV_W_X;
1030 break;
1031 case MVT::f64:
1032 // For RV32, we can't move from a GPR, we need to convert instead. This
1033 // should only happen for +0.0 and -0.0.
1034 assert((Subtarget->is64Bit() || APF.isZero()) && "Unexpected constant");
1035 if (HasZdinx)
1036 Opc = RISCV::COPY;
1037 else
1038 Opc = Is64Bit ? RISCV::FMV_D_X : RISCV::FCVT_D_W;
1039 break;
1040 }
1041
1042 SDNode *Res;
1043 if (VT.SimpleTy == MVT::f16 && Opc == RISCV::COPY) {
1044 Res =
1045 CurDAG->getTargetExtractSubreg(RISCV::sub_16, DL, VT, Imm).getNode();
1046 } else if (VT.SimpleTy == MVT::f32 && Opc == RISCV::COPY) {
1047 Res =
1048 CurDAG->getTargetExtractSubreg(RISCV::sub_32, DL, VT, Imm).getNode();
1049 } else if (Opc == RISCV::FCVT_D_W_IN32X || Opc == RISCV::FCVT_D_W)
1050 Res = CurDAG->getMachineNode(
1051 Opc, DL, VT, Imm,
1052 CurDAG->getTargetConstant(RISCVFPRndMode::RNE, DL, XLenVT));
1053 else
1054 Res = CurDAG->getMachineNode(Opc, DL, VT, Imm);
1055
1056 // For f64 -0.0, we need to insert a fneg.d idiom.
1057 if (NegZeroF64) {
1058 Opc = RISCV::FSGNJN_D;
1059 if (HasZdinx)
1060 Opc = Is64Bit ? RISCV::FSGNJN_D_INX : RISCV::FSGNJN_D_IN32X;
1061 Res =
1062 CurDAG->getMachineNode(Opc, DL, VT, SDValue(Res, 0), SDValue(Res, 0));
1063 }
1064
1065 ReplaceNode(Node, Res);
1066 return;
1067 }
1068 case RISCVISD::BuildGPRPair:
1069 case RISCVISD::BuildPairF64: {
1070 if (Opcode == RISCVISD::BuildPairF64 && !Subtarget->hasStdExtZdinx())
1071 break;
1072
1073 assert((!Subtarget->is64Bit() || Opcode == RISCVISD::BuildGPRPair) &&
1074 "BuildPairF64 only handled here on rv32i_zdinx");
1075
1076 SDValue Ops[] = {
1077 CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32),
1078 Node->getOperand(0),
1079 CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32),
1080 Node->getOperand(1),
1081 CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
1082
1083 SDNode *N = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, VT, Ops);
1084 ReplaceNode(Node, N);
1085 return;
1086 }
1087 case RISCVISD::SplitGPRPair:
1088 case RISCVISD::SplitF64: {
1089 if (Subtarget->hasStdExtZdinx() || Opcode != RISCVISD::SplitF64) {
1090 assert((!Subtarget->is64Bit() || Opcode == RISCVISD::SplitGPRPair) &&
1091 "SplitF64 only handled here on rv32i_zdinx");
1092
1093 if (!SDValue(Node, 0).use_empty()) {
1094 SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL,
1095 Node->getValueType(0),
1096 Node->getOperand(0));
1097 ReplaceUses(SDValue(Node, 0), Lo);
1098 }
1099
1100 if (!SDValue(Node, 1).use_empty()) {
1101 SDValue Hi = CurDAG->getTargetExtractSubreg(
1102 RISCV::sub_gpr_odd, DL, Node->getValueType(1), Node->getOperand(0));
1103 ReplaceUses(SDValue(Node, 1), Hi);
1104 }
1105
1106 CurDAG->RemoveDeadNode(Node);
1107 return;
1108 }
1109
1110 assert(Opcode != RISCVISD::SplitGPRPair &&
1111 "SplitGPRPair should already be handled");
1112
1113 if (!Subtarget->hasStdExtZfa())
1114 break;
1115 assert(Subtarget->hasStdExtD() && !Subtarget->is64Bit() &&
1116 "Unexpected subtarget");
1117
1118 // With Zfa, lower to fmv.x.w and fmvh.x.d.
1119 if (!SDValue(Node, 0).use_empty()) {
1120 SDNode *Lo = CurDAG->getMachineNode(RISCV::FMV_X_W_FPR64, DL, VT,
1121 Node->getOperand(0));
1122 ReplaceUses(SDValue(Node, 0), SDValue(Lo, 0));
1123 }
1124 if (!SDValue(Node, 1).use_empty()) {
1125 SDNode *Hi = CurDAG->getMachineNode(RISCV::FMVH_X_D, DL, VT,
1126 Node->getOperand(0));
1127 ReplaceUses(SDValue(Node, 1), SDValue(Hi, 0));
1128 }
1129
1130 CurDAG->RemoveDeadNode(Node);
1131 return;
1132 }
1133 case ISD::SHL: {
1134 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1135 if (!N1C)
1136 break;
1137 SDValue N0 = Node->getOperand(0);
1138 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse() ||
1140 break;
1141 unsigned ShAmt = N1C->getZExtValue();
1142 uint64_t Mask = N0.getConstantOperandVal(1);
1143
1144 if (isShiftedMask_64(Mask)) {
1145 unsigned XLen = Subtarget->getXLen();
1146 unsigned LeadingZeros = XLen - llvm::bit_width(Mask);
1147 unsigned TrailingZeros = llvm::countr_zero(Mask);
1148 if (ShAmt <= 32 && TrailingZeros > 0 && LeadingZeros == 32) {
1149 // Optimize (shl (and X, C2), C) -> (slli (srliw X, C3), C3+C)
1150 // where C2 has 32 leading zeros and C3 trailing zeros.
1151 SDNode *SRLIW = CurDAG->getMachineNode(
1152 RISCV::SRLIW, DL, VT, N0.getOperand(0),
1153 CurDAG->getTargetConstant(TrailingZeros, DL, VT));
1154 SDNode *SLLI = CurDAG->getMachineNode(
1155 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1156 CurDAG->getTargetConstant(TrailingZeros + ShAmt, DL, VT));
1157 ReplaceNode(Node, SLLI);
1158 return;
1159 }
1160 if (TrailingZeros == 0 && LeadingZeros > ShAmt &&
1161 XLen - LeadingZeros > 11 && LeadingZeros != 32) {
1162 // Optimize (shl (and X, C2), C) -> (srli (slli X, C4), C4-C)
1163 // where C2 has C4 leading zeros and no trailing zeros.
1164 // This is profitable if the "and" was to be lowered to
1165 // (srli (slli X, C4), C4) and not (andi X, C2).
1166 // For "LeadingZeros == 32":
1167 // - with Zba it's just (slli.uw X, C)
1168 // - without Zba a tablegen pattern applies the very same
1169 // transform as we would have done here
1170 SDNode *SLLI = CurDAG->getMachineNode(
1171 RISCV::SLLI, DL, VT, N0.getOperand(0),
1172 CurDAG->getTargetConstant(LeadingZeros, DL, VT));
1173 SDNode *SRLI = CurDAG->getMachineNode(
1174 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1175 CurDAG->getTargetConstant(LeadingZeros - ShAmt, DL, VT));
1176 ReplaceNode(Node, SRLI);
1177 return;
1178 }
1179 }
1180 break;
1181 }
1182 case ISD::SRL: {
1183 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1184 if (!N1C)
1185 break;
1186 SDValue N0 = Node->getOperand(0);
1187 if (N0.getOpcode() != ISD::AND || !isa<ConstantSDNode>(N0.getOperand(1)))
1188 break;
1189 unsigned ShAmt = N1C->getZExtValue();
1190 uint64_t Mask = N0.getConstantOperandVal(1);
1191
1192 // Optimize (srl (and X, C2), C) -> (slli (srliw X, C3), C3-C) where C2 has
1193 // 32 leading zeros and C3 trailing zeros.
1194 if (isShiftedMask_64(Mask) && N0.hasOneUse()) {
1195 unsigned XLen = Subtarget->getXLen();
1196 unsigned LeadingZeros = XLen - llvm::bit_width(Mask);
1197 unsigned TrailingZeros = llvm::countr_zero(Mask);
1198 if (LeadingZeros == 32 && TrailingZeros > ShAmt) {
1199 SDNode *SRLIW = CurDAG->getMachineNode(
1200 RISCV::SRLIW, DL, VT, N0.getOperand(0),
1201 CurDAG->getTargetConstant(TrailingZeros, DL, VT));
1202 SDNode *SLLI = CurDAG->getMachineNode(
1203 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1204 CurDAG->getTargetConstant(TrailingZeros - ShAmt, DL, VT));
1205 ReplaceNode(Node, SLLI);
1206 return;
1207 }
1208 }
1209
1210 // Optimize (srl (and X, C2), C) ->
1211 // (srli (slli X, (XLen-C3), (XLen-C3) + C)
1212 // Where C2 is a mask with C3 trailing ones.
1213 // Taking into account that the C2 may have had lower bits unset by
1214 // SimplifyDemandedBits. This avoids materializing the C2 immediate.
1215 // This pattern occurs when type legalizing right shifts for types with
1216 // less than XLen bits.
1217 Mask |= maskTrailingOnes<uint64_t>(ShAmt);
1218 if (!isMask_64(Mask))
1219 break;
1220 unsigned TrailingOnes = llvm::countr_one(Mask);
1221 if (ShAmt >= TrailingOnes)
1222 break;
1223 // If the mask has 32 trailing ones, use SRLI on RV32 or SRLIW on RV64.
1224 if (TrailingOnes == 32) {
1225 SDNode *SRLI = CurDAG->getMachineNode(
1226 Subtarget->is64Bit() ? RISCV::SRLIW : RISCV::SRLI, DL, VT,
1227 N0.getOperand(0), CurDAG->getTargetConstant(ShAmt, DL, VT));
1228 ReplaceNode(Node, SRLI);
1229 return;
1230 }
1231
1232 // Only do the remaining transforms if the AND has one use.
1233 if (!N0.hasOneUse())
1234 break;
1235
1236 // If C2 is (1 << ShAmt) use bexti or th.tst if possible.
1237 if (HasBitTest && ShAmt + 1 == TrailingOnes) {
1238 SDNode *BEXTI = CurDAG->getMachineNode(
1239 Subtarget->hasStdExtZbs() ? RISCV::BEXTI : RISCV::TH_TST, DL, VT,
1240 N0.getOperand(0), CurDAG->getTargetConstant(ShAmt, DL, VT));
1241 ReplaceNode(Node, BEXTI);
1242 return;
1243 }
1244
1245 const unsigned Msb = TrailingOnes - 1;
1246 const unsigned Lsb = ShAmt;
1247 if (tryUnsignedBitfieldExtract(Node, DL, VT, N0.getOperand(0), Msb, Lsb))
1248 return;
1249
1250 unsigned LShAmt = Subtarget->getXLen() - TrailingOnes;
1251 SDNode *SLLI =
1252 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0.getOperand(0),
1253 CurDAG->getTargetConstant(LShAmt, DL, VT));
1254 SDNode *SRLI = CurDAG->getMachineNode(
1255 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1256 CurDAG->getTargetConstant(LShAmt + ShAmt, DL, VT));
1257 ReplaceNode(Node, SRLI);
1258 return;
1259 }
1260 case ISD::SRA: {
1262 return;
1263
1265 return;
1266
1267 // Optimize (sra (sext_inreg X, i16), C) ->
1268 // (srai (slli X, (XLen-16), (XLen-16) + C)
1269 // And (sra (sext_inreg X, i8), C) ->
1270 // (srai (slli X, (XLen-8), (XLen-8) + C)
1271 // This can occur when Zbb is enabled, which makes sext_inreg i16/i8 legal.
1272 // This transform matches the code we get without Zbb. The shifts are more
1273 // compressible, and this can help expose CSE opportunities in the sdiv by
1274 // constant optimization.
1275 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1276 if (!N1C)
1277 break;
1278 SDValue N0 = Node->getOperand(0);
1279 if (N0.getOpcode() != ISD::SIGN_EXTEND_INREG || !N0.hasOneUse())
1280 break;
1281 unsigned ShAmt = N1C->getZExtValue();
1282 unsigned ExtSize =
1283 cast<VTSDNode>(N0.getOperand(1))->getVT().getSizeInBits();
1284 // ExtSize of 32 should use sraiw via tablegen pattern.
1285 if (ExtSize >= 32 || ShAmt >= ExtSize)
1286 break;
1287 unsigned LShAmt = Subtarget->getXLen() - ExtSize;
1288 SDNode *SLLI =
1289 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0.getOperand(0),
1290 CurDAG->getTargetConstant(LShAmt, DL, VT));
1291 SDNode *SRAI = CurDAG->getMachineNode(
1292 RISCV::SRAI, DL, VT, SDValue(SLLI, 0),
1293 CurDAG->getTargetConstant(LShAmt + ShAmt, DL, VT));
1294 ReplaceNode(Node, SRAI);
1295 return;
1296 }
1297 case ISD::OR: {
1299 return;
1300
1301 break;
1302 }
1303 case ISD::XOR:
1305 return;
1306
1307 break;
1308 case ISD::AND: {
1309 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1310 if (!N1C)
1311 break;
1312
1313 SDValue N0 = Node->getOperand(0);
1314
1315 bool LeftShift = N0.getOpcode() == ISD::SHL;
1316 if (LeftShift || N0.getOpcode() == ISD::SRL) {
1317 auto *C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
1318 if (!C)
1319 break;
1320 unsigned C2 = C->getZExtValue();
1321 unsigned XLen = Subtarget->getXLen();
1322 assert((C2 > 0 && C2 < XLen) && "Unexpected shift amount!");
1323
1324 // Keep track of whether this is a c.andi. If we can't use c.andi, the
1325 // shift pair might offer more compression opportunities.
1326 // TODO: We could check for C extension here, but we don't have many lit
1327 // tests with the C extension enabled so not checking gets better
1328 // coverage.
1329 // TODO: What if ANDI faster than shift?
1330 bool IsCANDI = isInt<6>(N1C->getSExtValue());
1331
1332 uint64_t C1 = N1C->getZExtValue();
1333
1334 // Clear irrelevant bits in the mask.
1335 if (LeftShift)
1337 else
1338 C1 &= maskTrailingOnes<uint64_t>(XLen - C2);
1339
1340 // Some transforms should only be done if the shift has a single use or
1341 // the AND would become (srli (slli X, 32), 32)
1342 bool OneUseOrZExtW = N0.hasOneUse() || C1 == UINT64_C(0xFFFFFFFF);
1343
1344 SDValue X = N0.getOperand(0);
1345
1346 // Turn (and (srl x, c2) c1) -> (srli (slli x, c3-c2), c3) if c1 is a mask
1347 // with c3 leading zeros.
1348 if (!LeftShift && isMask_64(C1)) {
1349 unsigned Leading = XLen - llvm::bit_width(C1);
1350 if (C2 < Leading) {
1351 // If the number of leading zeros is C2+32 this can be SRLIW.
1352 if (C2 + 32 == Leading) {
1353 SDNode *SRLIW = CurDAG->getMachineNode(
1354 RISCV::SRLIW, DL, VT, X, CurDAG->getTargetConstant(C2, DL, VT));
1355 ReplaceNode(Node, SRLIW);
1356 return;
1357 }
1358
1359 // (and (srl (sexti32 Y), c2), c1) -> (srliw (sraiw Y, 31), c3 - 32)
1360 // if c1 is a mask with c3 leading zeros and c2 >= 32 and c3-c2==1.
1361 //
1362 // This pattern occurs when (i32 (srl (sra 31), c3 - 32)) is type
1363 // legalized and goes through DAG combine.
1364 if (C2 >= 32 && (Leading - C2) == 1 && N0.hasOneUse() &&
1365 X.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1366 cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i32) {
1367 SDNode *SRAIW =
1368 CurDAG->getMachineNode(RISCV::SRAIW, DL, VT, X.getOperand(0),
1369 CurDAG->getTargetConstant(31, DL, VT));
1370 SDNode *SRLIW = CurDAG->getMachineNode(
1371 RISCV::SRLIW, DL, VT, SDValue(SRAIW, 0),
1372 CurDAG->getTargetConstant(Leading - 32, DL, VT));
1373 ReplaceNode(Node, SRLIW);
1374 return;
1375 }
1376
1377 // Try to use an unsigned bitfield extract (e.g., th.extu) if
1378 // available.
1379 // Transform (and (srl x, C2), C1)
1380 // -> (<bfextract> x, msb, lsb)
1381 //
1382 // Make sure to keep this below the SRLIW cases, as we always want to
1383 // prefer the more common instruction.
1384 const unsigned Msb = llvm::bit_width(C1) + C2 - 1;
1385 const unsigned Lsb = C2;
1386 if (tryUnsignedBitfieldExtract(Node, DL, VT, X, Msb, Lsb))
1387 return;
1388
1389 // (srli (slli x, c3-c2), c3).
1390 // Skip if we could use (zext.w (sraiw X, C2)).
1391 bool Skip = Subtarget->hasStdExtZba() && Leading == 32 &&
1392 X.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1393 cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i32;
1394 // Also Skip if we can use bexti or th.tst.
1395 Skip |= HasBitTest && Leading == XLen - 1;
1396 if (OneUseOrZExtW && !Skip) {
1397 SDNode *SLLI = CurDAG->getMachineNode(
1398 RISCV::SLLI, DL, VT, X,
1399 CurDAG->getTargetConstant(Leading - C2, DL, VT));
1400 SDNode *SRLI = CurDAG->getMachineNode(
1401 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1402 CurDAG->getTargetConstant(Leading, DL, VT));
1403 ReplaceNode(Node, SRLI);
1404 return;
1405 }
1406 }
1407 }
1408
1409 // Turn (and (shl x, c2), c1) -> (srli (slli c2+c3), c3) if c1 is a mask
1410 // shifted by c2 bits with c3 leading zeros.
1411 if (LeftShift && isShiftedMask_64(C1)) {
1412 unsigned Leading = XLen - llvm::bit_width(C1);
1413
1414 if (C2 + Leading < XLen &&
1415 C1 == (maskTrailingOnes<uint64_t>(XLen - (C2 + Leading)) << C2)) {
1416 // Use slli.uw when possible.
1417 if ((XLen - (C2 + Leading)) == 32 && Subtarget->hasStdExtZba()) {
1418 SDNode *SLLI_UW =
1419 CurDAG->getMachineNode(RISCV::SLLI_UW, DL, VT, X,
1420 CurDAG->getTargetConstant(C2, DL, VT));
1421 ReplaceNode(Node, SLLI_UW);
1422 return;
1423 }
1424
1425 // Try to use an unsigned bitfield insert (e.g., nds.bfoz) if
1426 // available.
1427 // Transform (and (shl x, c2), c1)
1428 // -> (<bfinsert> x, msb, lsb)
1429 // e.g.
1430 // (and (shl x, 12), 0x00fff000)
1431 // If XLen = 32 and C2 = 12, then
1432 // Msb = 32 - 8 - 1 = 23 and Lsb = 12
1433 const unsigned Msb = XLen - Leading - 1;
1434 const unsigned Lsb = C2;
1435 if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb))
1436 return;
1437
1438 // (srli (slli c2+c3), c3)
1439 if (OneUseOrZExtW && !IsCANDI) {
1440 SDNode *SLLI = CurDAG->getMachineNode(
1441 RISCV::SLLI, DL, VT, X,
1442 CurDAG->getTargetConstant(C2 + Leading, DL, VT));
1443 SDNode *SRLI = CurDAG->getMachineNode(
1444 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1445 CurDAG->getTargetConstant(Leading, DL, VT));
1446 ReplaceNode(Node, SRLI);
1447 return;
1448 }
1449 }
1450 }
1451
1452 // Turn (and (shr x, c2), c1) -> (slli (srli x, c2+c3), c3) if c1 is a
1453 // shifted mask with c2 leading zeros and c3 trailing zeros.
1454 if (!LeftShift && isShiftedMask_64(C1)) {
1455 unsigned Leading = XLen - llvm::bit_width(C1);
1456 unsigned Trailing = llvm::countr_zero(C1);
1457 if (Leading == C2 && C2 + Trailing < XLen && OneUseOrZExtW &&
1458 !IsCANDI) {
1459 unsigned SrliOpc = RISCV::SRLI;
1460 // If the input is zexti32 we should use SRLIW.
1461 if (X.getOpcode() == ISD::AND &&
1462 isa<ConstantSDNode>(X.getOperand(1)) &&
1463 X.getConstantOperandVal(1) == UINT64_C(0xFFFFFFFF)) {
1464 SrliOpc = RISCV::SRLIW;
1465 X = X.getOperand(0);
1466 }
1467 SDNode *SRLI = CurDAG->getMachineNode(
1468 SrliOpc, DL, VT, X,
1469 CurDAG->getTargetConstant(C2 + Trailing, DL, VT));
1470 SDNode *SLLI = CurDAG->getMachineNode(
1471 RISCV::SLLI, DL, VT, SDValue(SRLI, 0),
1472 CurDAG->getTargetConstant(Trailing, DL, VT));
1473 ReplaceNode(Node, SLLI);
1474 return;
1475 }
1476 // If the leading zero count is C2+32, we can use SRLIW instead of SRLI.
1477 if (Leading > 32 && (Leading - 32) == C2 && C2 + Trailing < 32 &&
1478 OneUseOrZExtW && !IsCANDI) {
1479 SDNode *SRLIW = CurDAG->getMachineNode(
1480 RISCV::SRLIW, DL, VT, X,
1481 CurDAG->getTargetConstant(C2 + Trailing, DL, VT));
1482 SDNode *SLLI = CurDAG->getMachineNode(
1483 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1484 CurDAG->getTargetConstant(Trailing, DL, VT));
1485 ReplaceNode(Node, SLLI);
1486 return;
1487 }
1488 // If we have 32 bits in the mask, we can use SLLI_UW instead of SLLI.
1489 if (Trailing > 0 && Leading + Trailing == 32 && C2 + Trailing < XLen &&
1490 OneUseOrZExtW && Subtarget->hasStdExtZba()) {
1491 SDNode *SRLI = CurDAG->getMachineNode(
1492 RISCV::SRLI, DL, VT, X,
1493 CurDAG->getTargetConstant(C2 + Trailing, DL, VT));
1494 SDNode *SLLI_UW = CurDAG->getMachineNode(
1495 RISCV::SLLI_UW, DL, VT, SDValue(SRLI, 0),
1496 CurDAG->getTargetConstant(Trailing, DL, VT));
1497 ReplaceNode(Node, SLLI_UW);
1498 return;
1499 }
1500 }
1501
1502 // Turn (and (shl x, c2), c1) -> (slli (srli x, c3-c2), c3) if c1 is a
1503 // shifted mask with no leading zeros and c3 trailing zeros.
1504 if (LeftShift && isShiftedMask_64(C1)) {
1505 unsigned Leading = XLen - llvm::bit_width(C1);
1506 unsigned Trailing = llvm::countr_zero(C1);
1507 if (Leading == 0 && C2 < Trailing && OneUseOrZExtW && !IsCANDI) {
1508 SDNode *SRLI = CurDAG->getMachineNode(
1509 RISCV::SRLI, DL, VT, X,
1510 CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1511 SDNode *SLLI = CurDAG->getMachineNode(
1512 RISCV::SLLI, DL, VT, SDValue(SRLI, 0),
1513 CurDAG->getTargetConstant(Trailing, DL, VT));
1514 ReplaceNode(Node, SLLI);
1515 return;
1516 }
1517 // If we have (32-C2) leading zeros, we can use SRLIW instead of SRLI.
1518 if (C2 < Trailing && Leading + C2 == 32 && OneUseOrZExtW && !IsCANDI) {
1519 SDNode *SRLIW = CurDAG->getMachineNode(
1520 RISCV::SRLIW, DL, VT, X,
1521 CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1522 SDNode *SLLI = CurDAG->getMachineNode(
1523 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1524 CurDAG->getTargetConstant(Trailing, DL, VT));
1525 ReplaceNode(Node, SLLI);
1526 return;
1527 }
1528
1529 // If we have 32 bits in the mask, we can use SLLI_UW instead of SLLI.
1530 if (C2 < Trailing && Leading + Trailing == 32 && OneUseOrZExtW &&
1531 Subtarget->hasStdExtZba()) {
1532 SDNode *SRLI = CurDAG->getMachineNode(
1533 RISCV::SRLI, DL, VT, X,
1534 CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1535 SDNode *SLLI_UW = CurDAG->getMachineNode(
1536 RISCV::SLLI_UW, DL, VT, SDValue(SRLI, 0),
1537 CurDAG->getTargetConstant(Trailing, DL, VT));
1538 ReplaceNode(Node, SLLI_UW);
1539 return;
1540 }
1541 }
1542 }
1543
1544 const uint64_t C1 = N1C->getZExtValue();
1545
1546 if (N0.getOpcode() == ISD::SRA && isa<ConstantSDNode>(N0.getOperand(1)) &&
1547 N0.hasOneUse()) {
1548 unsigned C2 = N0.getConstantOperandVal(1);
1549 unsigned XLen = Subtarget->getXLen();
1550 assert((C2 > 0 && C2 < XLen) && "Unexpected shift amount!");
1551
1552 SDValue X = N0.getOperand(0);
1553
1554 // Prefer SRAIW + ANDI when possible.
1555 bool Skip = C2 > 32 && isInt<12>(N1C->getSExtValue()) &&
1556 X.getOpcode() == ISD::SHL &&
1557 isa<ConstantSDNode>(X.getOperand(1)) &&
1558 X.getConstantOperandVal(1) == 32;
1559 // Turn (and (sra x, c2), c1) -> (srli (srai x, c2-c3), c3) if c1 is a
1560 // mask with c3 leading zeros and c2 is larger than c3.
1561 if (isMask_64(C1) && !Skip) {
1562 unsigned Leading = XLen - llvm::bit_width(C1);
1563 if (C2 > Leading) {
1564 SDNode *SRAI = CurDAG->getMachineNode(
1565 RISCV::SRAI, DL, VT, X,
1566 CurDAG->getTargetConstant(C2 - Leading, DL, VT));
1567 SDNode *SRLI = CurDAG->getMachineNode(
1568 RISCV::SRLI, DL, VT, SDValue(SRAI, 0),
1569 CurDAG->getTargetConstant(Leading, DL, VT));
1570 ReplaceNode(Node, SRLI);
1571 return;
1572 }
1573 }
1574
1575 // Look for (and (sra y, c2), c1) where c1 is a shifted mask with c3
1576 // leading zeros and c4 trailing zeros. If c2 is greater than c3, we can
1577 // use (slli (srli (srai y, c2 - c3), c3 + c4), c4).
1578 if (isShiftedMask_64(C1) && !Skip) {
1579 unsigned Leading = XLen - llvm::bit_width(C1);
1580 unsigned Trailing = llvm::countr_zero(C1);
1581 if (C2 > Leading && Leading > 0 && Trailing > 0) {
1582 SDNode *SRAI = CurDAG->getMachineNode(
1583 RISCV::SRAI, DL, VT, N0.getOperand(0),
1584 CurDAG->getTargetConstant(C2 - Leading, DL, VT));
1585 SDNode *SRLI = CurDAG->getMachineNode(
1586 RISCV::SRLI, DL, VT, SDValue(SRAI, 0),
1587 CurDAG->getTargetConstant(Leading + Trailing, DL, VT));
1588 SDNode *SLLI = CurDAG->getMachineNode(
1589 RISCV::SLLI, DL, VT, SDValue(SRLI, 0),
1590 CurDAG->getTargetConstant(Trailing, DL, VT));
1591 ReplaceNode(Node, SLLI);
1592 return;
1593 }
1594 }
1595 }
1596
1597 // If C1 masks off the upper bits only (but can't be formed as an
1598 // ANDI), use an unsigned bitfield extract (e.g., th.extu), if
1599 // available.
1600 // Transform (and x, C1)
1601 // -> (<bfextract> x, msb, lsb)
1602 if (isMask_64(C1) && !isInt<12>(N1C->getSExtValue()) &&
1603 !(C1 == 0xffff && Subtarget->hasStdExtZbb()) &&
1604 !(C1 == 0xffffffff && Subtarget->hasStdExtZba())) {
1605 const unsigned Msb = llvm::bit_width(C1) - 1;
1606 if (tryUnsignedBitfieldExtract(Node, DL, VT, N0, Msb, 0))
1607 return;
1608 }
1609
1611 return;
1612
1613 break;
1614 }
1615 case ISD::MUL: {
1616 // Special case for calculating (mul (and X, C2), C1) where the full product
1617 // fits in XLen bits. We can shift X left by the number of leading zeros in
1618 // C2 and shift C1 left by XLen-lzcnt(C2). This will ensure the final
1619 // product has XLen trailing zeros, putting it in the output of MULHU. This
1620 // can avoid materializing a constant in a register for C2.
1621
1622 // RHS should be a constant.
1623 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1624 if (!N1C || !N1C->hasOneUse())
1625 break;
1626
1627 // LHS should be an AND with constant.
1628 SDValue N0 = Node->getOperand(0);
1629 if (N0.getOpcode() != ISD::AND || !isa<ConstantSDNode>(N0.getOperand(1)))
1630 break;
1631
1633
1634 // Constant should be a mask.
1635 if (!isMask_64(C2))
1636 break;
1637
1638 // If this can be an ANDI or ZEXT.H, don't do this if the ANDI/ZEXT has
1639 // multiple users or the constant is a simm12. This prevents inserting a
1640 // shift and still have uses of the AND/ZEXT. Shifting a simm12 will likely
1641 // make it more costly to materialize. Otherwise, using a SLLI might allow
1642 // it to be compressed.
1643 bool IsANDIOrZExt =
1644 isInt<12>(C2) ||
1645 (C2 == UINT64_C(0xFFFF) && Subtarget->hasStdExtZbb());
1646 // With XTHeadBb, we can use TH.EXTU.
1647 IsANDIOrZExt |= C2 == UINT64_C(0xFFFF) && Subtarget->hasVendorXTHeadBb();
1648 if (IsANDIOrZExt && (isInt<12>(N1C->getSExtValue()) || !N0.hasOneUse()))
1649 break;
1650 // If this can be a ZEXT.w, don't do this if the ZEXT has multiple users or
1651 // the constant is a simm32.
1652 bool IsZExtW = C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba();
1653 // With XTHeadBb, we can use TH.EXTU.
1654 IsZExtW |= C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasVendorXTHeadBb();
1655 if (IsZExtW && (isInt<32>(N1C->getSExtValue()) || !N0.hasOneUse()))
1656 break;
1657
1658 // We need to shift left the AND input and C1 by a total of XLen bits.
1659
1660 // How far left do we need to shift the AND input?
1661 unsigned XLen = Subtarget->getXLen();
1662 unsigned LeadingZeros = XLen - llvm::bit_width(C2);
1663
1664 // The constant gets shifted by the remaining amount unless that would
1665 // shift bits out.
1666 uint64_t C1 = N1C->getZExtValue();
1667 unsigned ConstantShift = XLen - LeadingZeros;
1668 if (ConstantShift > (XLen - llvm::bit_width(C1)))
1669 break;
1670
1671 uint64_t ShiftedC1 = C1 << ConstantShift;
1672 // If this RV32, we need to sign extend the constant.
1673 if (XLen == 32)
1674 ShiftedC1 = SignExtend64<32>(ShiftedC1);
1675
1676 // Create (mulhu (slli X, lzcnt(C2)), C1 << (XLen - lzcnt(C2))).
1677 SDNode *Imm = selectImm(CurDAG, DL, VT, ShiftedC1, *Subtarget).getNode();
1678 SDNode *SLLI =
1679 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0.getOperand(0),
1680 CurDAG->getTargetConstant(LeadingZeros, DL, VT));
1681 SDNode *MULHU = CurDAG->getMachineNode(RISCV::MULHU, DL, VT,
1682 SDValue(SLLI, 0), SDValue(Imm, 0));
1683 ReplaceNode(Node, MULHU);
1684 return;
1685 }
1686 case ISD::LOAD: {
1687 if (tryIndexedLoad(Node))
1688 return;
1689
1690 if (Subtarget->hasVendorXCVmem() && !Subtarget->is64Bit()) {
1691 // We match post-incrementing load here
1693 if (Load->getAddressingMode() != ISD::POST_INC)
1694 break;
1695
1696 SDValue Chain = Node->getOperand(0);
1697 SDValue Base = Node->getOperand(1);
1698 SDValue Offset = Node->getOperand(2);
1699
1700 bool Simm12 = false;
1701 bool SignExtend = Load->getExtensionType() == ISD::SEXTLOAD;
1702
1703 if (auto ConstantOffset = dyn_cast<ConstantSDNode>(Offset)) {
1704 int ConstantVal = ConstantOffset->getSExtValue();
1705 Simm12 = isInt<12>(ConstantVal);
1706 if (Simm12)
1707 Offset = CurDAG->getTargetConstant(ConstantVal, SDLoc(Offset),
1708 Offset.getValueType());
1709 }
1710
1711 unsigned Opcode = 0;
1712 switch (Load->getMemoryVT().getSimpleVT().SimpleTy) {
1713 case MVT::i8:
1714 if (Simm12 && SignExtend)
1715 Opcode = RISCV::CV_LB_ri_inc;
1716 else if (Simm12 && !SignExtend)
1717 Opcode = RISCV::CV_LBU_ri_inc;
1718 else if (!Simm12 && SignExtend)
1719 Opcode = RISCV::CV_LB_rr_inc;
1720 else
1721 Opcode = RISCV::CV_LBU_rr_inc;
1722 break;
1723 case MVT::i16:
1724 if (Simm12 && SignExtend)
1725 Opcode = RISCV::CV_LH_ri_inc;
1726 else if (Simm12 && !SignExtend)
1727 Opcode = RISCV::CV_LHU_ri_inc;
1728 else if (!Simm12 && SignExtend)
1729 Opcode = RISCV::CV_LH_rr_inc;
1730 else
1731 Opcode = RISCV::CV_LHU_rr_inc;
1732 break;
1733 case MVT::i32:
1734 if (Simm12)
1735 Opcode = RISCV::CV_LW_ri_inc;
1736 else
1737 Opcode = RISCV::CV_LW_rr_inc;
1738 break;
1739 default:
1740 break;
1741 }
1742 if (!Opcode)
1743 break;
1744
1745 ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, XLenVT, XLenVT,
1746 Chain.getSimpleValueType(), Base,
1747 Offset, Chain));
1748 return;
1749 }
1750 break;
1751 }
1752 case RISCVISD::LD_RV32: {
1753 assert(Subtarget->hasStdExtZilsd() && "LD_RV32 is only used with Zilsd");
1754
1756 SDValue Chain = Node->getOperand(0);
1757 SDValue Addr = Node->getOperand(1);
1759
1760 SDValue Ops[] = {Base, Offset, Chain};
1761 MachineSDNode *New = CurDAG->getMachineNode(
1762 RISCV::LD_RV32, DL, {MVT::Untyped, MVT::Other}, Ops);
1763 SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL,
1764 MVT::i32, SDValue(New, 0));
1765 SDValue Hi = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_odd, DL,
1766 MVT::i32, SDValue(New, 0));
1767 CurDAG->setNodeMemRefs(New, {cast<MemSDNode>(Node)->getMemOperand()});
1768 ReplaceUses(SDValue(Node, 0), Lo);
1769 ReplaceUses(SDValue(Node, 1), Hi);
1770 ReplaceUses(SDValue(Node, 2), SDValue(New, 1));
1771 CurDAG->RemoveDeadNode(Node);
1772 return;
1773 }
1774 case RISCVISD::SD_RV32: {
1776 SDValue Chain = Node->getOperand(0);
1777 SDValue Addr = Node->getOperand(3);
1779
1780 SDValue Lo = Node->getOperand(1);
1781 SDValue Hi = Node->getOperand(2);
1782
1783 SDValue RegPair;
1784 // Peephole to use X0_Pair for storing zero.
1786 RegPair = CurDAG->getRegister(RISCV::X0_Pair, MVT::Untyped);
1787 } else {
1788 SDValue Ops[] = {
1789 CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32), Lo,
1790 CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32), Hi,
1791 CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
1792
1793 RegPair = SDValue(CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
1794 MVT::Untyped, Ops),
1795 0);
1796 }
1797
1798 MachineSDNode *New = CurDAG->getMachineNode(RISCV::SD_RV32, DL, MVT::Other,
1799 {RegPair, Base, Offset, Chain});
1800 CurDAG->setNodeMemRefs(New, {cast<MemSDNode>(Node)->getMemOperand()});
1801 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
1802 CurDAG->RemoveDeadNode(Node);
1803 return;
1804 }
1806 unsigned IntNo = Node->getConstantOperandVal(0);
1807 switch (IntNo) {
1808 // By default we do not custom select any intrinsic.
1809 default:
1810 break;
1811 case Intrinsic::riscv_vmsgeu:
1812 case Intrinsic::riscv_vmsge: {
1813 SDValue Src1 = Node->getOperand(1);
1814 SDValue Src2 = Node->getOperand(2);
1815 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu;
1816 bool IsCmpConstant = false;
1817 bool IsCmpMinimum = false;
1818 // Only custom select scalar second operand.
1819 if (Src2.getValueType() != XLenVT)
1820 break;
1821 // Small constants are handled with patterns.
1822 int64_t CVal = 0;
1823 MVT Src1VT = Src1.getSimpleValueType();
1824 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1825 IsCmpConstant = true;
1826 CVal = C->getSExtValue();
1827 if (CVal >= -15 && CVal <= 16) {
1828 if (!IsUnsigned || CVal != 0)
1829 break;
1830 IsCmpMinimum = true;
1831 } else if (!IsUnsigned && CVal == APInt::getSignedMinValue(
1832 Src1VT.getScalarSizeInBits())
1833 .getSExtValue()) {
1834 IsCmpMinimum = true;
1835 }
1836 }
1837 unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode, VMSGTOpcode;
1838 switch (RISCVTargetLowering::getLMUL(Src1VT)) {
1839 default:
1840 llvm_unreachable("Unexpected LMUL!");
1841#define CASE_VMSLT_OPCODES(lmulenum, suffix) \
1842 case RISCVVType::lmulenum: \
1843 VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
1844 : RISCV::PseudoVMSLT_VX_##suffix; \
1845 VMSGTOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix \
1846 : RISCV::PseudoVMSGT_VX_##suffix; \
1847 break;
1848 CASE_VMSLT_OPCODES(LMUL_F8, MF8)
1849 CASE_VMSLT_OPCODES(LMUL_F4, MF4)
1850 CASE_VMSLT_OPCODES(LMUL_F2, MF2)
1851 CASE_VMSLT_OPCODES(LMUL_1, M1)
1852 CASE_VMSLT_OPCODES(LMUL_2, M2)
1853 CASE_VMSLT_OPCODES(LMUL_4, M4)
1854 CASE_VMSLT_OPCODES(LMUL_8, M8)
1855#undef CASE_VMSLT_OPCODES
1856 }
1857 // Mask operations use the LMUL from the mask type.
1858 switch (RISCVTargetLowering::getLMUL(VT)) {
1859 default:
1860 llvm_unreachable("Unexpected LMUL!");
1861#define CASE_VMNAND_VMSET_OPCODES(lmulenum, suffix) \
1862 case RISCVVType::lmulenum: \
1863 VMNANDOpcode = RISCV::PseudoVMNAND_MM_##suffix; \
1864 VMSetOpcode = RISCV::PseudoVMSET_M_##suffix; \
1865 break;
1866 CASE_VMNAND_VMSET_OPCODES(LMUL_F8, B64)
1867 CASE_VMNAND_VMSET_OPCODES(LMUL_F4, B32)
1868 CASE_VMNAND_VMSET_OPCODES(LMUL_F2, B16)
1869 CASE_VMNAND_VMSET_OPCODES(LMUL_1, B8)
1870 CASE_VMNAND_VMSET_OPCODES(LMUL_2, B4)
1871 CASE_VMNAND_VMSET_OPCODES(LMUL_4, B2)
1872 CASE_VMNAND_VMSET_OPCODES(LMUL_8, B1)
1873#undef CASE_VMNAND_VMSET_OPCODES
1874 }
1875 SDValue SEW = CurDAG->getTargetConstant(
1876 Log2_32(Src1VT.getScalarSizeInBits()), DL, XLenVT);
1877 SDValue MaskSEW = CurDAG->getTargetConstant(0, DL, XLenVT);
1878 SDValue VL;
1879 selectVLOp(Node->getOperand(3), VL);
1880
1881 // If vmsge(u) with minimum value, expand it to vmset.
1882 if (IsCmpMinimum) {
1884 CurDAG->getMachineNode(VMSetOpcode, DL, VT, VL, MaskSEW));
1885 return;
1886 }
1887
1888 if (IsCmpConstant) {
1889 SDValue Imm =
1890 selectImm(CurDAG, SDLoc(Src2), XLenVT, CVal - 1, *Subtarget);
1891
1892 ReplaceNode(Node, CurDAG->getMachineNode(VMSGTOpcode, DL, VT,
1893 {Src1, Imm, VL, SEW}));
1894 return;
1895 }
1896
1897 // Expand to
1898 // vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
1899 SDValue Cmp = SDValue(
1900 CurDAG->getMachineNode(VMSLTOpcode, DL, VT, {Src1, Src2, VL, SEW}),
1901 0);
1902 ReplaceNode(Node, CurDAG->getMachineNode(VMNANDOpcode, DL, VT,
1903 {Cmp, Cmp, VL, MaskSEW}));
1904 return;
1905 }
1906 case Intrinsic::riscv_vmsgeu_mask:
1907 case Intrinsic::riscv_vmsge_mask: {
1908 SDValue Src1 = Node->getOperand(2);
1909 SDValue Src2 = Node->getOperand(3);
1910 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu_mask;
1911 bool IsCmpConstant = false;
1912 bool IsCmpMinimum = false;
1913 // Only custom select scalar second operand.
1914 if (Src2.getValueType() != XLenVT)
1915 break;
1916 // Small constants are handled with patterns.
1917 MVT Src1VT = Src1.getSimpleValueType();
1918 int64_t CVal = 0;
1919 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1920 IsCmpConstant = true;
1921 CVal = C->getSExtValue();
1922 if (CVal >= -15 && CVal <= 16) {
1923 if (!IsUnsigned || CVal != 0)
1924 break;
1925 IsCmpMinimum = true;
1926 } else if (!IsUnsigned && CVal == APInt::getSignedMinValue(
1927 Src1VT.getScalarSizeInBits())
1928 .getSExtValue()) {
1929 IsCmpMinimum = true;
1930 }
1931 }
1932 unsigned VMSLTOpcode, VMSLTMaskOpcode, VMXOROpcode, VMANDNOpcode,
1933 VMOROpcode, VMSGTMaskOpcode;
1934 switch (RISCVTargetLowering::getLMUL(Src1VT)) {
1935 default:
1936 llvm_unreachable("Unexpected LMUL!");
1937#define CASE_VMSLT_OPCODES(lmulenum, suffix) \
1938 case RISCVVType::lmulenum: \
1939 VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
1940 : RISCV::PseudoVMSLT_VX_##suffix; \
1941 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix##_MASK \
1942 : RISCV::PseudoVMSLT_VX_##suffix##_MASK; \
1943 VMSGTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix##_MASK \
1944 : RISCV::PseudoVMSGT_VX_##suffix##_MASK; \
1945 break;
1946 CASE_VMSLT_OPCODES(LMUL_F8, MF8)
1947 CASE_VMSLT_OPCODES(LMUL_F4, MF4)
1948 CASE_VMSLT_OPCODES(LMUL_F2, MF2)
1949 CASE_VMSLT_OPCODES(LMUL_1, M1)
1950 CASE_VMSLT_OPCODES(LMUL_2, M2)
1951 CASE_VMSLT_OPCODES(LMUL_4, M4)
1952 CASE_VMSLT_OPCODES(LMUL_8, M8)
1953#undef CASE_VMSLT_OPCODES
1954 }
1955 // Mask operations use the LMUL from the mask type.
1956 switch (RISCVTargetLowering::getLMUL(VT)) {
1957 default:
1958 llvm_unreachable("Unexpected LMUL!");
1959#define CASE_VMXOR_VMANDN_VMOR_OPCODES(lmulenum, suffix) \
1960 case RISCVVType::lmulenum: \
1961 VMXOROpcode = RISCV::PseudoVMXOR_MM_##suffix; \
1962 VMANDNOpcode = RISCV::PseudoVMANDN_MM_##suffix; \
1963 VMOROpcode = RISCV::PseudoVMOR_MM_##suffix; \
1964 break;
1965 CASE_VMXOR_VMANDN_VMOR_OPCODES(LMUL_F8, B64)
1966 CASE_VMXOR_VMANDN_VMOR_OPCODES(LMUL_F4, B32)
1967 CASE_VMXOR_VMANDN_VMOR_OPCODES(LMUL_F2, B16)
1972#undef CASE_VMXOR_VMANDN_VMOR_OPCODES
1973 }
1974 SDValue SEW = CurDAG->getTargetConstant(
1975 Log2_32(Src1VT.getScalarSizeInBits()), DL, XLenVT);
1976 SDValue MaskSEW = CurDAG->getTargetConstant(0, DL, XLenVT);
1977 SDValue VL;
1978 selectVLOp(Node->getOperand(5), VL);
1979 SDValue MaskedOff = Node->getOperand(1);
1980 SDValue Mask = Node->getOperand(4);
1981
1982 // If vmsge(u) with minimum value, expand it to vmor mask, maskedoff.
1983 if (IsCmpMinimum) {
1984 // We don't need vmor if the MaskedOff and the Mask are the same
1985 // value.
1986 if (Mask == MaskedOff) {
1987 ReplaceUses(Node, Mask.getNode());
1988 return;
1989 }
1991 CurDAG->getMachineNode(VMOROpcode, DL, VT,
1992 {Mask, MaskedOff, VL, MaskSEW}));
1993 return;
1994 }
1995
1996 // If the MaskedOff value and the Mask are the same value use
1997 // vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt
1998 // This avoids needing to copy v0 to vd before starting the next sequence.
1999 if (Mask == MaskedOff) {
2000 SDValue Cmp = SDValue(
2001 CurDAG->getMachineNode(VMSLTOpcode, DL, VT, {Src1, Src2, VL, SEW}),
2002 0);
2003 ReplaceNode(Node, CurDAG->getMachineNode(VMANDNOpcode, DL, VT,
2004 {Mask, Cmp, VL, MaskSEW}));
2005 return;
2006 }
2007
2008 SDValue PolicyOp =
2009 CurDAG->getTargetConstant(RISCVVType::TAIL_AGNOSTIC, DL, XLenVT);
2010
2011 if (IsCmpConstant) {
2012 SDValue Imm =
2013 selectImm(CurDAG, SDLoc(Src2), XLenVT, CVal - 1, *Subtarget);
2014
2015 ReplaceNode(Node, CurDAG->getMachineNode(
2016 VMSGTMaskOpcode, DL, VT,
2017 {MaskedOff, Src1, Imm, Mask, VL, SEW, PolicyOp}));
2018 return;
2019 }
2020
2021 // Otherwise use
2022 // vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
2023 // The result is mask undisturbed.
2024 // We use the same instructions to emulate mask agnostic behavior, because
2025 // the agnostic result can be either undisturbed or all 1.
2026 SDValue Cmp = SDValue(CurDAG->getMachineNode(VMSLTMaskOpcode, DL, VT,
2027 {MaskedOff, Src1, Src2, Mask,
2028 VL, SEW, PolicyOp}),
2029 0);
2030 // vmxor.mm vd, vd, v0 is used to update active value.
2031 ReplaceNode(Node, CurDAG->getMachineNode(VMXOROpcode, DL, VT,
2032 {Cmp, Mask, VL, MaskSEW}));
2033 return;
2034 }
2035 case Intrinsic::riscv_vsetvli:
2036 case Intrinsic::riscv_vsetvlimax:
2037 return selectVSETVLI(Node);
2038 }
2039 break;
2040 }
2042 unsigned IntNo = Node->getConstantOperandVal(1);
2043 switch (IntNo) {
2044 // By default we do not custom select any intrinsic.
2045 default:
2046 break;
2047 case Intrinsic::riscv_vlseg2:
2048 case Intrinsic::riscv_vlseg3:
2049 case Intrinsic::riscv_vlseg4:
2050 case Intrinsic::riscv_vlseg5:
2051 case Intrinsic::riscv_vlseg6:
2052 case Intrinsic::riscv_vlseg7:
2053 case Intrinsic::riscv_vlseg8: {
2054 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2055 /*IsStrided*/ false);
2056 return;
2057 }
2058 case Intrinsic::riscv_vlseg2_mask:
2059 case Intrinsic::riscv_vlseg3_mask:
2060 case Intrinsic::riscv_vlseg4_mask:
2061 case Intrinsic::riscv_vlseg5_mask:
2062 case Intrinsic::riscv_vlseg6_mask:
2063 case Intrinsic::riscv_vlseg7_mask:
2064 case Intrinsic::riscv_vlseg8_mask: {
2065 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2066 /*IsStrided*/ false);
2067 return;
2068 }
2069 case Intrinsic::riscv_vlsseg2:
2070 case Intrinsic::riscv_vlsseg3:
2071 case Intrinsic::riscv_vlsseg4:
2072 case Intrinsic::riscv_vlsseg5:
2073 case Intrinsic::riscv_vlsseg6:
2074 case Intrinsic::riscv_vlsseg7:
2075 case Intrinsic::riscv_vlsseg8: {
2076 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2077 /*IsStrided*/ true);
2078 return;
2079 }
2080 case Intrinsic::riscv_vlsseg2_mask:
2081 case Intrinsic::riscv_vlsseg3_mask:
2082 case Intrinsic::riscv_vlsseg4_mask:
2083 case Intrinsic::riscv_vlsseg5_mask:
2084 case Intrinsic::riscv_vlsseg6_mask:
2085 case Intrinsic::riscv_vlsseg7_mask:
2086 case Intrinsic::riscv_vlsseg8_mask: {
2087 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2088 /*IsStrided*/ true);
2089 return;
2090 }
2091 case Intrinsic::riscv_vloxseg2:
2092 case Intrinsic::riscv_vloxseg3:
2093 case Intrinsic::riscv_vloxseg4:
2094 case Intrinsic::riscv_vloxseg5:
2095 case Intrinsic::riscv_vloxseg6:
2096 case Intrinsic::riscv_vloxseg7:
2097 case Intrinsic::riscv_vloxseg8:
2098 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2099 /*IsOrdered*/ true);
2100 return;
2101 case Intrinsic::riscv_vluxseg2:
2102 case Intrinsic::riscv_vluxseg3:
2103 case Intrinsic::riscv_vluxseg4:
2104 case Intrinsic::riscv_vluxseg5:
2105 case Intrinsic::riscv_vluxseg6:
2106 case Intrinsic::riscv_vluxseg7:
2107 case Intrinsic::riscv_vluxseg8:
2108 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2109 /*IsOrdered*/ false);
2110 return;
2111 case Intrinsic::riscv_vloxseg2_mask:
2112 case Intrinsic::riscv_vloxseg3_mask:
2113 case Intrinsic::riscv_vloxseg4_mask:
2114 case Intrinsic::riscv_vloxseg5_mask:
2115 case Intrinsic::riscv_vloxseg6_mask:
2116 case Intrinsic::riscv_vloxseg7_mask:
2117 case Intrinsic::riscv_vloxseg8_mask:
2118 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2119 /*IsOrdered*/ true);
2120 return;
2121 case Intrinsic::riscv_vluxseg2_mask:
2122 case Intrinsic::riscv_vluxseg3_mask:
2123 case Intrinsic::riscv_vluxseg4_mask:
2124 case Intrinsic::riscv_vluxseg5_mask:
2125 case Intrinsic::riscv_vluxseg6_mask:
2126 case Intrinsic::riscv_vluxseg7_mask:
2127 case Intrinsic::riscv_vluxseg8_mask:
2128 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2129 /*IsOrdered*/ false);
2130 return;
2131 case Intrinsic::riscv_vlseg8ff:
2132 case Intrinsic::riscv_vlseg7ff:
2133 case Intrinsic::riscv_vlseg6ff:
2134 case Intrinsic::riscv_vlseg5ff:
2135 case Intrinsic::riscv_vlseg4ff:
2136 case Intrinsic::riscv_vlseg3ff:
2137 case Intrinsic::riscv_vlseg2ff: {
2138 selectVLSEGFF(Node, getSegInstNF(IntNo), /*IsMasked*/ false);
2139 return;
2140 }
2141 case Intrinsic::riscv_vlseg8ff_mask:
2142 case Intrinsic::riscv_vlseg7ff_mask:
2143 case Intrinsic::riscv_vlseg6ff_mask:
2144 case Intrinsic::riscv_vlseg5ff_mask:
2145 case Intrinsic::riscv_vlseg4ff_mask:
2146 case Intrinsic::riscv_vlseg3ff_mask:
2147 case Intrinsic::riscv_vlseg2ff_mask: {
2148 selectVLSEGFF(Node, getSegInstNF(IntNo), /*IsMasked*/ true);
2149 return;
2150 }
2151 case Intrinsic::riscv_vloxei:
2152 case Intrinsic::riscv_vloxei_mask:
2153 case Intrinsic::riscv_vluxei:
2154 case Intrinsic::riscv_vluxei_mask: {
2155 bool IsMasked = IntNo == Intrinsic::riscv_vloxei_mask ||
2156 IntNo == Intrinsic::riscv_vluxei_mask;
2157 bool IsOrdered = IntNo == Intrinsic::riscv_vloxei ||
2158 IntNo == Intrinsic::riscv_vloxei_mask;
2159
2160 MVT VT = Node->getSimpleValueType(0);
2161 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2162
2163 unsigned CurOp = 2;
2165 Operands.push_back(Node->getOperand(CurOp++));
2166
2167 MVT IndexVT;
2168 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2169 /*IsStridedOrIndexed*/ true, Operands,
2170 /*IsLoad=*/true, &IndexVT);
2171
2173 "Element count mismatch");
2174
2177 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
2178 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
2179 report_fatal_error("The V extension does not support EEW=64 for index "
2180 "values when XLEN=32");
2181 }
2182 const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo(
2183 IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
2184 static_cast<unsigned>(IndexLMUL));
2185 MachineSDNode *Load =
2186 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2187
2188 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
2189
2190 ReplaceNode(Node, Load);
2191 return;
2192 }
2193 case Intrinsic::riscv_vlm:
2194 case Intrinsic::riscv_vle:
2195 case Intrinsic::riscv_vle_mask:
2196 case Intrinsic::riscv_vlse:
2197 case Intrinsic::riscv_vlse_mask: {
2198 bool IsMasked = IntNo == Intrinsic::riscv_vle_mask ||
2199 IntNo == Intrinsic::riscv_vlse_mask;
2200 bool IsStrided =
2201 IntNo == Intrinsic::riscv_vlse || IntNo == Intrinsic::riscv_vlse_mask;
2202
2203 MVT VT = Node->getSimpleValueType(0);
2204 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2205
2206 // The riscv_vlm intrinsic are always tail agnostic and no passthru
2207 // operand at the IR level. In pseudos, they have both policy and
2208 // passthru operand. The passthru operand is needed to track the
2209 // "tail undefined" state, and the policy is there just for
2210 // for consistency - it will always be "don't care" for the
2211 // unmasked form.
2212 bool HasPassthruOperand = IntNo != Intrinsic::riscv_vlm;
2213 unsigned CurOp = 2;
2215 if (HasPassthruOperand)
2216 Operands.push_back(Node->getOperand(CurOp++));
2217 else {
2218 // We eagerly lower to implicit_def (instead of undef), as we
2219 // otherwise fail to select nodes such as: nxv1i1 = undef
2220 SDNode *Passthru =
2221 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
2222 Operands.push_back(SDValue(Passthru, 0));
2223 }
2224 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
2225 Operands, /*IsLoad=*/true);
2226
2228 const RISCV::VLEPseudo *P =
2229 RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW,
2230 static_cast<unsigned>(LMUL));
2231 MachineSDNode *Load =
2232 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2233
2234 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
2235
2236 ReplaceNode(Node, Load);
2237 return;
2238 }
2239 case Intrinsic::riscv_vleff:
2240 case Intrinsic::riscv_vleff_mask: {
2241 bool IsMasked = IntNo == Intrinsic::riscv_vleff_mask;
2242
2243 MVT VT = Node->getSimpleValueType(0);
2244 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2245
2246 unsigned CurOp = 2;
2248 Operands.push_back(Node->getOperand(CurOp++));
2249 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2250 /*IsStridedOrIndexed*/ false, Operands,
2251 /*IsLoad=*/true);
2252
2254 const RISCV::VLEPseudo *P =
2255 RISCV::getVLEPseudo(IsMasked, /*Strided*/ false, /*FF*/ true,
2256 Log2SEW, static_cast<unsigned>(LMUL));
2257 MachineSDNode *Load = CurDAG->getMachineNode(
2258 P->Pseudo, DL, Node->getVTList(), Operands);
2259 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
2260
2261 ReplaceNode(Node, Load);
2262 return;
2263 }
2264 case Intrinsic::riscv_nds_vln:
2265 case Intrinsic::riscv_nds_vln_mask:
2266 case Intrinsic::riscv_nds_vlnu:
2267 case Intrinsic::riscv_nds_vlnu_mask: {
2268 bool IsMasked = IntNo == Intrinsic::riscv_nds_vln_mask ||
2269 IntNo == Intrinsic::riscv_nds_vlnu_mask;
2270 bool IsUnsigned = IntNo == Intrinsic::riscv_nds_vlnu ||
2271 IntNo == Intrinsic::riscv_nds_vlnu_mask;
2272
2273 MVT VT = Node->getSimpleValueType(0);
2274 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2275 unsigned CurOp = 2;
2277
2278 Operands.push_back(Node->getOperand(CurOp++));
2279 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2280 /*IsStridedOrIndexed=*/false, Operands,
2281 /*IsLoad=*/true);
2282
2284 const RISCV::NDSVLNPseudo *P = RISCV::getNDSVLNPseudo(
2285 IsMasked, IsUnsigned, Log2SEW, static_cast<unsigned>(LMUL));
2286 MachineSDNode *Load =
2287 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2288
2289 if (auto *MemOp = dyn_cast<MemSDNode>(Node))
2290 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
2291
2292 ReplaceNode(Node, Load);
2293 return;
2294 }
2295 }
2296 break;
2297 }
2298 case ISD::INTRINSIC_VOID: {
2299 unsigned IntNo = Node->getConstantOperandVal(1);
2300 switch (IntNo) {
2301 case Intrinsic::riscv_vsseg2:
2302 case Intrinsic::riscv_vsseg3:
2303 case Intrinsic::riscv_vsseg4:
2304 case Intrinsic::riscv_vsseg5:
2305 case Intrinsic::riscv_vsseg6:
2306 case Intrinsic::riscv_vsseg7:
2307 case Intrinsic::riscv_vsseg8: {
2308 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2309 /*IsStrided*/ false);
2310 return;
2311 }
2312 case Intrinsic::riscv_vsseg2_mask:
2313 case Intrinsic::riscv_vsseg3_mask:
2314 case Intrinsic::riscv_vsseg4_mask:
2315 case Intrinsic::riscv_vsseg5_mask:
2316 case Intrinsic::riscv_vsseg6_mask:
2317 case Intrinsic::riscv_vsseg7_mask:
2318 case Intrinsic::riscv_vsseg8_mask: {
2319 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2320 /*IsStrided*/ false);
2321 return;
2322 }
2323 case Intrinsic::riscv_vssseg2:
2324 case Intrinsic::riscv_vssseg3:
2325 case Intrinsic::riscv_vssseg4:
2326 case Intrinsic::riscv_vssseg5:
2327 case Intrinsic::riscv_vssseg6:
2328 case Intrinsic::riscv_vssseg7:
2329 case Intrinsic::riscv_vssseg8: {
2330 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2331 /*IsStrided*/ true);
2332 return;
2333 }
2334 case Intrinsic::riscv_vssseg2_mask:
2335 case Intrinsic::riscv_vssseg3_mask:
2336 case Intrinsic::riscv_vssseg4_mask:
2337 case Intrinsic::riscv_vssseg5_mask:
2338 case Intrinsic::riscv_vssseg6_mask:
2339 case Intrinsic::riscv_vssseg7_mask:
2340 case Intrinsic::riscv_vssseg8_mask: {
2341 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2342 /*IsStrided*/ true);
2343 return;
2344 }
2345 case Intrinsic::riscv_vsoxseg2:
2346 case Intrinsic::riscv_vsoxseg3:
2347 case Intrinsic::riscv_vsoxseg4:
2348 case Intrinsic::riscv_vsoxseg5:
2349 case Intrinsic::riscv_vsoxseg6:
2350 case Intrinsic::riscv_vsoxseg7:
2351 case Intrinsic::riscv_vsoxseg8:
2352 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2353 /*IsOrdered*/ true);
2354 return;
2355 case Intrinsic::riscv_vsuxseg2:
2356 case Intrinsic::riscv_vsuxseg3:
2357 case Intrinsic::riscv_vsuxseg4:
2358 case Intrinsic::riscv_vsuxseg5:
2359 case Intrinsic::riscv_vsuxseg6:
2360 case Intrinsic::riscv_vsuxseg7:
2361 case Intrinsic::riscv_vsuxseg8:
2362 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2363 /*IsOrdered*/ false);
2364 return;
2365 case Intrinsic::riscv_vsoxseg2_mask:
2366 case Intrinsic::riscv_vsoxseg3_mask:
2367 case Intrinsic::riscv_vsoxseg4_mask:
2368 case Intrinsic::riscv_vsoxseg5_mask:
2369 case Intrinsic::riscv_vsoxseg6_mask:
2370 case Intrinsic::riscv_vsoxseg7_mask:
2371 case Intrinsic::riscv_vsoxseg8_mask:
2372 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2373 /*IsOrdered*/ true);
2374 return;
2375 case Intrinsic::riscv_vsuxseg2_mask:
2376 case Intrinsic::riscv_vsuxseg3_mask:
2377 case Intrinsic::riscv_vsuxseg4_mask:
2378 case Intrinsic::riscv_vsuxseg5_mask:
2379 case Intrinsic::riscv_vsuxseg6_mask:
2380 case Intrinsic::riscv_vsuxseg7_mask:
2381 case Intrinsic::riscv_vsuxseg8_mask:
2382 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2383 /*IsOrdered*/ false);
2384 return;
2385 case Intrinsic::riscv_vsoxei:
2386 case Intrinsic::riscv_vsoxei_mask:
2387 case Intrinsic::riscv_vsuxei:
2388 case Intrinsic::riscv_vsuxei_mask: {
2389 bool IsMasked = IntNo == Intrinsic::riscv_vsoxei_mask ||
2390 IntNo == Intrinsic::riscv_vsuxei_mask;
2391 bool IsOrdered = IntNo == Intrinsic::riscv_vsoxei ||
2392 IntNo == Intrinsic::riscv_vsoxei_mask;
2393
2394 MVT VT = Node->getOperand(2)->getSimpleValueType(0);
2395 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2396
2397 unsigned CurOp = 2;
2399 Operands.push_back(Node->getOperand(CurOp++)); // Store value.
2400
2401 MVT IndexVT;
2402 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2403 /*IsStridedOrIndexed*/ true, Operands,
2404 /*IsLoad=*/false, &IndexVT);
2405
2407 "Element count mismatch");
2408
2411 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
2412 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
2413 report_fatal_error("The V extension does not support EEW=64 for index "
2414 "values when XLEN=32");
2415 }
2416 const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo(
2417 IsMasked, IsOrdered, IndexLog2EEW,
2418 static_cast<unsigned>(LMUL), static_cast<unsigned>(IndexLMUL));
2419 MachineSDNode *Store =
2420 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2421
2422 CurDAG->setNodeMemRefs(Store, {cast<MemSDNode>(Node)->getMemOperand()});
2423
2424 ReplaceNode(Node, Store);
2425 return;
2426 }
2427 case Intrinsic::riscv_vsm:
2428 case Intrinsic::riscv_vse:
2429 case Intrinsic::riscv_vse_mask:
2430 case Intrinsic::riscv_vsse:
2431 case Intrinsic::riscv_vsse_mask: {
2432 bool IsMasked = IntNo == Intrinsic::riscv_vse_mask ||
2433 IntNo == Intrinsic::riscv_vsse_mask;
2434 bool IsStrided =
2435 IntNo == Intrinsic::riscv_vsse || IntNo == Intrinsic::riscv_vsse_mask;
2436
2437 MVT VT = Node->getOperand(2)->getSimpleValueType(0);
2438 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2439
2440 unsigned CurOp = 2;
2442 Operands.push_back(Node->getOperand(CurOp++)); // Store value.
2443
2444 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
2445 Operands);
2446
2448 const RISCV::VSEPseudo *P = RISCV::getVSEPseudo(
2449 IsMasked, IsStrided, Log2SEW, static_cast<unsigned>(LMUL));
2450 MachineSDNode *Store =
2451 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2452 CurDAG->setNodeMemRefs(Store, {cast<MemSDNode>(Node)->getMemOperand()});
2453
2454 ReplaceNode(Node, Store);
2455 return;
2456 }
2457 case Intrinsic::riscv_sf_vc_x_se:
2458 case Intrinsic::riscv_sf_vc_i_se:
2460 return;
2461 }
2462 break;
2463 }
2464 case ISD::BITCAST: {
2465 MVT SrcVT = Node->getOperand(0).getSimpleValueType();
2466 // Just drop bitcasts between vectors if both are fixed or both are
2467 // scalable.
2468 if ((VT.isScalableVector() && SrcVT.isScalableVector()) ||
2469 (VT.isFixedLengthVector() && SrcVT.isFixedLengthVector())) {
2470 ReplaceUses(SDValue(Node, 0), Node->getOperand(0));
2471 CurDAG->RemoveDeadNode(Node);
2472 return;
2473 }
2474 break;
2475 }
2477 case RISCVISD::TUPLE_INSERT: {
2478 SDValue V = Node->getOperand(0);
2479 SDValue SubV = Node->getOperand(1);
2480 SDLoc DL(SubV);
2481 auto Idx = Node->getConstantOperandVal(2);
2482 MVT SubVecVT = SubV.getSimpleValueType();
2483
2484 const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering();
2485 MVT SubVecContainerVT = SubVecVT;
2486 // Establish the correct scalable-vector types for any fixed-length type.
2487 if (SubVecVT.isFixedLengthVector()) {
2488 SubVecContainerVT = TLI.getContainerForFixedLengthVector(SubVecVT);
2490 [[maybe_unused]] bool ExactlyVecRegSized =
2491 Subtarget->expandVScale(SubVecVT.getSizeInBits())
2492 .isKnownMultipleOf(Subtarget->expandVScale(VecRegSize));
2493 assert(isPowerOf2_64(Subtarget->expandVScale(SubVecVT.getSizeInBits())
2494 .getKnownMinValue()));
2495 assert(Idx == 0 && (ExactlyVecRegSized || V.isUndef()));
2496 }
2497 MVT ContainerVT = VT;
2498 if (VT.isFixedLengthVector())
2499 ContainerVT = TLI.getContainerForFixedLengthVector(VT);
2500
2501 const auto *TRI = Subtarget->getRegisterInfo();
2502 unsigned SubRegIdx;
2503 std::tie(SubRegIdx, Idx) =
2505 ContainerVT, SubVecContainerVT, Idx, TRI);
2506
2507 // If the Idx hasn't been completely eliminated then this is a subvector
2508 // insert which doesn't naturally align to a vector register. These must
2509 // be handled using instructions to manipulate the vector registers.
2510 if (Idx != 0)
2511 break;
2512
2513 RISCVVType::VLMUL SubVecLMUL =
2514 RISCVTargetLowering::getLMUL(SubVecContainerVT);
2515 [[maybe_unused]] bool IsSubVecPartReg =
2516 SubVecLMUL == RISCVVType::VLMUL::LMUL_F2 ||
2517 SubVecLMUL == RISCVVType::VLMUL::LMUL_F4 ||
2518 SubVecLMUL == RISCVVType::VLMUL::LMUL_F8;
2519 assert((V.getValueType().isRISCVVectorTuple() || !IsSubVecPartReg ||
2520 V.isUndef()) &&
2521 "Expecting lowering to have created legal INSERT_SUBVECTORs when "
2522 "the subvector is smaller than a full-sized register");
2523
2524 // If we haven't set a SubRegIdx, then we must be going between
2525 // equally-sized LMUL groups (e.g. VR -> VR). This can be done as a copy.
2526 if (SubRegIdx == RISCV::NoSubRegister) {
2527 unsigned InRegClassID =
2530 InRegClassID &&
2531 "Unexpected subvector extraction");
2532 SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT);
2533 SDNode *NewNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
2534 DL, VT, SubV, RC);
2535 ReplaceNode(Node, NewNode);
2536 return;
2537 }
2538
2539 SDValue Insert = CurDAG->getTargetInsertSubreg(SubRegIdx, DL, VT, V, SubV);
2540 ReplaceNode(Node, Insert.getNode());
2541 return;
2542 }
2544 case RISCVISD::TUPLE_EXTRACT: {
2545 SDValue V = Node->getOperand(0);
2546 auto Idx = Node->getConstantOperandVal(1);
2547 MVT InVT = V.getSimpleValueType();
2548 SDLoc DL(V);
2549
2550 const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering();
2551 MVT SubVecContainerVT = VT;
2552 // Establish the correct scalable-vector types for any fixed-length type.
2553 if (VT.isFixedLengthVector()) {
2554 assert(Idx == 0);
2555 SubVecContainerVT = TLI.getContainerForFixedLengthVector(VT);
2556 }
2557 if (InVT.isFixedLengthVector())
2558 InVT = TLI.getContainerForFixedLengthVector(InVT);
2559
2560 const auto *TRI = Subtarget->getRegisterInfo();
2561 unsigned SubRegIdx;
2562 std::tie(SubRegIdx, Idx) =
2564 InVT, SubVecContainerVT, Idx, TRI);
2565
2566 // If the Idx hasn't been completely eliminated then this is a subvector
2567 // extract which doesn't naturally align to a vector register. These must
2568 // be handled using instructions to manipulate the vector registers.
2569 if (Idx != 0)
2570 break;
2571
2572 // If we haven't set a SubRegIdx, then we must be going between
2573 // equally-sized LMUL types (e.g. VR -> VR). This can be done as a copy.
2574 if (SubRegIdx == RISCV::NoSubRegister) {
2575 unsigned InRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(InVT);
2577 InRegClassID &&
2578 "Unexpected subvector extraction");
2579 SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT);
2580 SDNode *NewNode =
2581 CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
2582 ReplaceNode(Node, NewNode);
2583 return;
2584 }
2585
2586 SDValue Extract = CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, V);
2587 ReplaceNode(Node, Extract.getNode());
2588 return;
2589 }
2590 case RISCVISD::VMV_S_X_VL:
2591 case RISCVISD::VFMV_S_F_VL:
2592 case RISCVISD::VMV_V_X_VL:
2593 case RISCVISD::VFMV_V_F_VL: {
2594 // Try to match splat of a scalar load to a strided load with stride of x0.
2595 bool IsScalarMove = Node->getOpcode() == RISCVISD::VMV_S_X_VL ||
2596 Node->getOpcode() == RISCVISD::VFMV_S_F_VL;
2597 if (!Node->getOperand(0).isUndef())
2598 break;
2599 SDValue Src = Node->getOperand(1);
2600 auto *Ld = dyn_cast<LoadSDNode>(Src);
2601 // Can't fold load update node because the second
2602 // output is used so that load update node can't be removed.
2603 if (!Ld || Ld->isIndexed())
2604 break;
2605 EVT MemVT = Ld->getMemoryVT();
2606 // The memory VT should be the same size as the element type.
2607 if (MemVT.getStoreSize() != VT.getVectorElementType().getStoreSize())
2608 break;
2609 if (!IsProfitableToFold(Src, Node, Node) ||
2610 !IsLegalToFold(Src, Node, Node, TM.getOptLevel()))
2611 break;
2612
2613 SDValue VL;
2614 if (IsScalarMove) {
2615 // We could deal with more VL if we update the VSETVLI insert pass to
2616 // avoid introducing more VSETVLI.
2617 if (!isOneConstant(Node->getOperand(2)))
2618 break;
2619 selectVLOp(Node->getOperand(2), VL);
2620 } else
2621 selectVLOp(Node->getOperand(2), VL);
2622
2623 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2624 SDValue SEW = CurDAG->getTargetConstant(Log2SEW, DL, XLenVT);
2625
2626 // If VL=1, then we don't need to do a strided load and can just do a
2627 // regular load.
2628 bool IsStrided = !isOneConstant(VL);
2629
2630 // Only do a strided load if we have optimized zero-stride vector load.
2631 if (IsStrided && !Subtarget->hasOptimizedZeroStrideLoad())
2632 break;
2633
2635 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT), 0),
2636 Ld->getBasePtr()};
2637 if (IsStrided)
2638 Operands.push_back(CurDAG->getRegister(RISCV::X0, XLenVT));
2640 SDValue PolicyOp = CurDAG->getTargetConstant(Policy, DL, XLenVT);
2641 Operands.append({VL, SEW, PolicyOp, Ld->getChain()});
2642
2644 const RISCV::VLEPseudo *P = RISCV::getVLEPseudo(
2645 /*IsMasked*/ false, IsStrided, /*FF*/ false,
2646 Log2SEW, static_cast<unsigned>(LMUL));
2647 MachineSDNode *Load =
2648 CurDAG->getMachineNode(P->Pseudo, DL, {VT, MVT::Other}, Operands);
2649 // Update the chain.
2650 ReplaceUses(Src.getValue(1), SDValue(Load, 1));
2651 // Record the mem-refs
2652 CurDAG->setNodeMemRefs(Load, {Ld->getMemOperand()});
2653 // Replace the splat with the vlse.
2654 ReplaceNode(Node, Load);
2655 return;
2656 }
2657 case ISD::PREFETCH:
2658 unsigned Locality = Node->getConstantOperandVal(3);
2659 if (Locality > 2)
2660 break;
2661
2662 auto *LoadStoreMem = cast<MemSDNode>(Node);
2663 MachineMemOperand *MMO = LoadStoreMem->getMemOperand();
2665
2666 int NontemporalLevel = 0;
2667 switch (Locality) {
2668 case 0:
2669 NontemporalLevel = 3; // NTL.ALL
2670 break;
2671 case 1:
2672 NontemporalLevel = 1; // NTL.PALL
2673 break;
2674 case 2:
2675 NontemporalLevel = 0; // NTL.P1
2676 break;
2677 default:
2678 llvm_unreachable("unexpected locality value.");
2679 }
2680
2681 if (NontemporalLevel & 0b1)
2683 if (NontemporalLevel & 0b10)
2685 break;
2686 }
2687
2688 // Select the default instruction.
2689 SelectCode(Node);
2690}
2691
2693 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
2694 std::vector<SDValue> &OutOps) {
2695 // Always produce a register and immediate operand, as expected by
2696 // RISCVAsmPrinter::PrintAsmMemoryOperand.
2697 switch (ConstraintID) {
2700 SDValue Op0, Op1;
2701 [[maybe_unused]] bool Found = SelectAddrRegImm(Op, Op0, Op1);
2702 assert(Found && "SelectAddrRegImm should always succeed");
2703 OutOps.push_back(Op0);
2704 OutOps.push_back(Op1);
2705 return false;
2706 }
2708 OutOps.push_back(Op);
2709 OutOps.push_back(
2710 CurDAG->getTargetConstant(0, SDLoc(Op), Subtarget->getXLenVT()));
2711 return false;
2712 default:
2713 report_fatal_error("Unexpected asm memory constraint " +
2714 InlineAsm::getMemConstraintName(ConstraintID));
2715 }
2716
2717 return true;
2718}
2719
2721 SDValue &Offset) {
2722 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2723 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
2724 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT());
2725 return true;
2726 }
2727
2728 return false;
2729}
2730
2731// Fold constant addresses.
2732static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
2733 const MVT VT, const RISCVSubtarget *Subtarget,
2735 bool IsPrefetch = false) {
2736 if (!isa<ConstantSDNode>(Addr))
2737 return false;
2738
2739 int64_t CVal = cast<ConstantSDNode>(Addr)->getSExtValue();
2740
2741 // If the constant is a simm12, we can fold the whole constant and use X0 as
2742 // the base. If the constant can be materialized with LUI+simm12, use LUI as
2743 // the base. We can't use generateInstSeq because it favors LUI+ADDIW.
2744 int64_t Lo12 = SignExtend64<12>(CVal);
2745 int64_t Hi = (uint64_t)CVal - (uint64_t)Lo12;
2746 if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
2747 if (IsPrefetch && (Lo12 & 0b11111) != 0)
2748 return false;
2749 if (Hi) {
2750 int64_t Hi20 = (Hi >> 12) & 0xfffff;
2751 Base = SDValue(
2752 CurDAG->getMachineNode(RISCV::LUI, DL, VT,
2753 CurDAG->getTargetConstant(Hi20, DL, VT)),
2754 0);
2755 } else {
2756 Base = CurDAG->getRegister(RISCV::X0, VT);
2757 }
2758 Offset = CurDAG->getSignedTargetConstant(Lo12, DL, VT);
2759 return true;
2760 }
2761
2762 // Ask how constant materialization would handle this constant.
2763 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(CVal, *Subtarget);
2764
2765 // If the last instruction would be an ADDI, we can fold its immediate and
2766 // emit the rest of the sequence as the base.
2767 if (Seq.back().getOpcode() != RISCV::ADDI)
2768 return false;
2769 Lo12 = Seq.back().getImm();
2770 if (IsPrefetch && (Lo12 & 0b11111) != 0)
2771 return false;
2772
2773 // Drop the last instruction.
2774 Seq.pop_back();
2775 assert(!Seq.empty() && "Expected more instructions in sequence");
2776
2777 Base = selectImmSeq(CurDAG, DL, VT, Seq);
2778 Offset = CurDAG->getSignedTargetConstant(Lo12, DL, VT);
2779 return true;
2780}
2781
2782// Is this ADD instruction only used as the base pointer of scalar loads and
2783// stores?
2785 for (auto *User : Add->users()) {
2786 if (User->getOpcode() != ISD::LOAD && User->getOpcode() != ISD::STORE &&
2787 User->getOpcode() != RISCVISD::LD_RV32 &&
2788 User->getOpcode() != RISCVISD::SD_RV32 &&
2789 User->getOpcode() != ISD::ATOMIC_LOAD &&
2790 User->getOpcode() != ISD::ATOMIC_STORE)
2791 return false;
2792 EVT VT = cast<MemSDNode>(User)->getMemoryVT();
2793 if (!VT.isScalarInteger() && VT != MVT::f16 && VT != MVT::f32 &&
2794 VT != MVT::f64)
2795 return false;
2796 // Don't allow stores of the value. It must be used as the address.
2797 if (User->getOpcode() == ISD::STORE &&
2798 cast<StoreSDNode>(User)->getValue() == Add)
2799 return false;
2800 if (User->getOpcode() == ISD::ATOMIC_STORE &&
2801 cast<AtomicSDNode>(User)->getVal() == Add)
2802 return false;
2803 if (User->getOpcode() == RISCVISD::SD_RV32 &&
2804 (User->getOperand(0) == Add || User->getOperand(1) == Add))
2805 return false;
2806 if (isStrongerThanMonotonic(cast<MemSDNode>(User)->getSuccessOrdering()))
2807 return false;
2808 }
2809
2810 return true;
2811}
2812
2814 switch (User->getOpcode()) {
2815 default:
2816 return false;
2817 case ISD::LOAD:
2818 case RISCVISD::LD_RV32:
2819 case ISD::ATOMIC_LOAD:
2820 break;
2821 case ISD::STORE:
2822 // Don't allow stores of Add. It must only be used as the address.
2823 if (cast<StoreSDNode>(User)->getValue() == Add)
2824 return false;
2825 break;
2826 case RISCVISD::SD_RV32:
2827 // Don't allow stores of Add. It must only be used as the address.
2828 if (User->getOperand(0) == Add || User->getOperand(1) == Add)
2829 return false;
2830 break;
2831 case ISD::ATOMIC_STORE:
2832 // Don't allow stores of Add. It must only be used as the address.
2833 if (cast<AtomicSDNode>(User)->getVal() == Add)
2834 return false;
2835 break;
2836 }
2837
2838 return true;
2839}
2840
2841// To prevent SelectAddrRegImm from folding offsets that conflict with the
2842// fusion of PseudoMovAddr, check if the offset of every use of a given address
2843// is within the alignment.
2845 Align Alignment) {
2846 assert(Addr->getOpcode() == RISCVISD::ADD_LO);
2847 for (auto *User : Addr->users()) {
2848 // If the user is a load or store, then the offset is 0 which is always
2849 // within alignment.
2850 if (isRegImmLoadOrStore(User, Addr))
2851 continue;
2852
2853 if (CurDAG->isBaseWithConstantOffset(SDValue(User, 0))) {
2854 int64_t CVal = cast<ConstantSDNode>(User->getOperand(1))->getSExtValue();
2855 if (!isInt<12>(CVal) || Alignment <= CVal)
2856 return false;
2857
2858 // Make sure all uses are foldable load/stores.
2859 for (auto *AddUser : User->users())
2860 if (!isRegImmLoadOrStore(AddUser, SDValue(User, 0)))
2861 return false;
2862
2863 continue;
2864 }
2865
2866 return false;
2867 }
2868
2869 return true;
2870}
2871
2873 SDValue &Offset) {
2874 if (SelectAddrFrameIndex(Addr, Base, Offset))
2875 return true;
2876
2877 SDLoc DL(Addr);
2878 MVT VT = Addr.getSimpleValueType();
2879
2880 if (Addr.getOpcode() == RISCVISD::ADD_LO) {
2881 bool CanFold = true;
2882 // Unconditionally fold if operand 1 is not a global address (e.g.
2883 // externsymbol)
2884 if (auto *GA = dyn_cast<GlobalAddressSDNode>(Addr.getOperand(1))) {
2885 const DataLayout &DL = CurDAG->getDataLayout();
2886 Align Alignment = commonAlignment(
2887 GA->getGlobal()->getPointerAlignment(DL), GA->getOffset());
2888 if (!areOffsetsWithinAlignment(Addr, Alignment))
2889 CanFold = false;
2890 }
2891 if (CanFold) {
2892 Base = Addr.getOperand(0);
2893 Offset = Addr.getOperand(1);
2894 return true;
2895 }
2896 }
2897
2898 if (CurDAG->isBaseWithConstantOffset(Addr)) {
2899 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2900 if (isInt<12>(CVal)) {
2901 Base = Addr.getOperand(0);
2902 if (Base.getOpcode() == RISCVISD::ADD_LO) {
2903 SDValue LoOperand = Base.getOperand(1);
2904 if (auto *GA = dyn_cast<GlobalAddressSDNode>(LoOperand)) {
2905 // If the Lo in (ADD_LO hi, lo) is a global variable's address
2906 // (its low part, really), then we can rely on the alignment of that
2907 // variable to provide a margin of safety before low part can overflow
2908 // the 12 bits of the load/store offset. Check if CVal falls within
2909 // that margin; if so (low part + CVal) can't overflow.
2910 const DataLayout &DL = CurDAG->getDataLayout();
2911 Align Alignment = commonAlignment(
2912 GA->getGlobal()->getPointerAlignment(DL), GA->getOffset());
2913 if ((CVal == 0 || Alignment > CVal) &&
2914 areOffsetsWithinAlignment(Base, Alignment)) {
2915 int64_t CombinedOffset = CVal + GA->getOffset();
2916 Base = Base.getOperand(0);
2917 Offset = CurDAG->getTargetGlobalAddress(
2918 GA->getGlobal(), SDLoc(LoOperand), LoOperand.getValueType(),
2919 CombinedOffset, GA->getTargetFlags());
2920 return true;
2921 }
2922 }
2923 }
2924
2925 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
2926 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
2927 Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
2928 return true;
2929 }
2930 }
2931
2932 // Handle ADD with large immediates.
2933 if (Addr.getOpcode() == ISD::ADD && isa<ConstantSDNode>(Addr.getOperand(1))) {
2934 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2935 assert(!isInt<12>(CVal) && "simm12 not already handled?");
2936
2937 // Handle immediates in the range [-4096,-2049] or [2048, 4094]. We can use
2938 // an ADDI for part of the offset and fold the rest into the load/store.
2939 // This mirrors the AddiPair PatFrag in RISCVInstrInfo.td.
2940 if (CVal >= -4096 && CVal <= 4094) {
2941 int64_t Adj = CVal < 0 ? -2048 : 2047;
2942 Base = SDValue(
2943 CurDAG->getMachineNode(RISCV::ADDI, DL, VT, Addr.getOperand(0),
2944 CurDAG->getSignedTargetConstant(Adj, DL, VT)),
2945 0);
2946 Offset = CurDAG->getSignedTargetConstant(CVal - Adj, DL, VT);
2947 return true;
2948 }
2949
2950 // For larger immediates, we might be able to save one instruction from
2951 // constant materialization by folding the Lo12 bits of the immediate into
2952 // the address. We should only do this if the ADD is only used by loads and
2953 // stores that can fold the lo12 bits. Otherwise, the ADD will get iseled
2954 // separately with the full materialized immediate creating extra
2955 // instructions.
2956 if (isWorthFoldingAdd(Addr) &&
2957 selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
2958 Offset, /*IsPrefetch=*/false)) {
2959 // Insert an ADD instruction with the materialized Hi52 bits.
2960 Base = SDValue(
2961 CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
2962 0);
2963 return true;
2964 }
2965 }
2966
2967 if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
2968 /*IsPrefetch=*/false))
2969 return true;
2970
2971 Base = Addr;
2972 Offset = CurDAG->getTargetConstant(0, DL, VT);
2973 return true;
2974}
2975
2976/// Similar to SelectAddrRegImm, except that the offset is restricted to uimm9.
2978 SDValue &Offset) {
2979 if (SelectAddrFrameIndex(Addr, Base, Offset))
2980 return true;
2981
2982 SDLoc DL(Addr);
2983 MVT VT = Addr.getSimpleValueType();
2984
2985 if (CurDAG->isBaseWithConstantOffset(Addr)) {
2986 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2987 if (isUInt<9>(CVal)) {
2988 Base = Addr.getOperand(0);
2989
2990 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
2991 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
2992 Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
2993 return true;
2994 }
2995 }
2996
2997 Base = Addr;
2998 Offset = CurDAG->getTargetConstant(0, DL, VT);
2999 return true;
3000}
3001
3002/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
3003/// Offset should be all zeros.
3005 SDValue &Offset) {
3006 if (SelectAddrFrameIndex(Addr, Base, Offset))
3007 return true;
3008
3009 SDLoc DL(Addr);
3010 MVT VT = Addr.getSimpleValueType();
3011
3012 if (CurDAG->isBaseWithConstantOffset(Addr)) {
3013 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
3014 if (isInt<12>(CVal)) {
3015 Base = Addr.getOperand(0);
3016
3017 // Early-out if not a valid offset.
3018 if ((CVal & 0b11111) != 0) {
3019 Base = Addr;
3020 Offset = CurDAG->getTargetConstant(0, DL, VT);
3021 return true;
3022 }
3023
3024 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
3025 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
3026 Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
3027 return true;
3028 }
3029 }
3030
3031 // Handle ADD with large immediates.
3032 if (Addr.getOpcode() == ISD::ADD && isa<ConstantSDNode>(Addr.getOperand(1))) {
3033 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
3034 assert(!isInt<12>(CVal) && "simm12 not already handled?");
3035
3036 // Handle immediates in the range [-4096,-2049] or [2017, 4065]. We can save
3037 // one instruction by folding adjustment (-2048 or 2016) into the address.
3038 if ((-2049 >= CVal && CVal >= -4096) || (4065 >= CVal && CVal >= 2017)) {
3039 int64_t Adj = CVal < 0 ? -2048 : 2016;
3040 int64_t AdjustedOffset = CVal - Adj;
3041 Base =
3042 SDValue(CurDAG->getMachineNode(
3043 RISCV::ADDI, DL, VT, Addr.getOperand(0),
3044 CurDAG->getSignedTargetConstant(AdjustedOffset, DL, VT)),
3045 0);
3046 Offset = CurDAG->getSignedTargetConstant(Adj, DL, VT);
3047 return true;
3048 }
3049
3050 if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
3051 Offset, /*IsPrefetch=*/true)) {
3052 // Insert an ADD instruction with the materialized Hi52 bits.
3053 Base = SDValue(
3054 CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
3055 0);
3056 return true;
3057 }
3058 }
3059
3060 if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
3061 /*IsPrefetch=*/true))
3062 return true;
3063
3064 Base = Addr;
3065 Offset = CurDAG->getTargetConstant(0, DL, VT);
3066 return true;
3067}
3068
3069/// Return true if this a load/store that we have a RegRegScale instruction for.
3071 const RISCVSubtarget &Subtarget) {
3072 if (User->getOpcode() != ISD::LOAD && User->getOpcode() != ISD::STORE)
3073 return false;
3074 EVT VT = cast<MemSDNode>(User)->getMemoryVT();
3075 if (!(VT.isScalarInteger() &&
3076 (Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls())) &&
3077 !((VT == MVT::f32 || VT == MVT::f64) &&
3078 Subtarget.hasVendorXTHeadFMemIdx()))
3079 return false;
3080 // Don't allow stores of the value. It must be used as the address.
3081 if (User->getOpcode() == ISD::STORE &&
3082 cast<StoreSDNode>(User)->getValue() == Add)
3083 return false;
3084
3085 return true;
3086}
3087
3088/// Is it profitable to fold this Add into RegRegScale load/store. If \p
3089/// Shift is non-null, then we have matched a shl+add. We allow reassociating
3090/// (add (add (shl A C2) B) C1) -> (add (add B C1) (shl A C2)) if there is a
3091/// single addi and we don't have a SHXADD instruction we could use.
3092/// FIXME: May still need to check how many and what kind of users the SHL has.
3094 SDValue Add,
3095 SDValue Shift = SDValue()) {
3096 bool FoundADDI = false;
3097 for (auto *User : Add->users()) {
3098 if (isRegRegScaleLoadOrStore(User, Add, Subtarget))
3099 continue;
3100
3101 // Allow a single ADDI that is used by loads/stores if we matched a shift.
3102 if (!Shift || FoundADDI || User->getOpcode() != ISD::ADD ||
3104 !isInt<12>(cast<ConstantSDNode>(User->getOperand(1))->getSExtValue()))
3105 return false;
3106
3107 FoundADDI = true;
3108
3109 // If we have a SHXADD instruction, prefer that over reassociating an ADDI.
3110 assert(Shift.getOpcode() == ISD::SHL);
3111 unsigned ShiftAmt = Shift.getConstantOperandVal(1);
3112 if (Subtarget.hasShlAdd(ShiftAmt))
3113 return false;
3114
3115 // All users of the ADDI should be load/store.
3116 for (auto *ADDIUser : User->users())
3117 if (!isRegRegScaleLoadOrStore(ADDIUser, SDValue(User, 0), Subtarget))
3118 return false;
3119 }
3120
3121 return true;
3122}
3123
3125 unsigned MaxShiftAmount,
3126 SDValue &Base, SDValue &Index,
3127 SDValue &Scale) {
3128 if (Addr.getOpcode() != ISD::ADD)
3129 return false;
3130 SDValue LHS = Addr.getOperand(0);
3131 SDValue RHS = Addr.getOperand(1);
3132
3133 EVT VT = Addr.getSimpleValueType();
3134 auto SelectShl = [this, VT, MaxShiftAmount](SDValue N, SDValue &Index,
3135 SDValue &Shift) {
3136 if (N.getOpcode() != ISD::SHL || !isa<ConstantSDNode>(N.getOperand(1)))
3137 return false;
3138
3139 // Only match shifts by a value in range [0, MaxShiftAmount].
3140 unsigned ShiftAmt = N.getConstantOperandVal(1);
3141 if (ShiftAmt > MaxShiftAmount)
3142 return false;
3143
3144 Index = N.getOperand(0);
3145 Shift = CurDAG->getTargetConstant(ShiftAmt, SDLoc(N), VT);
3146 return true;
3147 };
3148
3149 if (auto *C1 = dyn_cast<ConstantSDNode>(RHS)) {
3150 // (add (add (shl A C2) B) C1) -> (add (add B C1) (shl A C2))
3151 if (LHS.getOpcode() == ISD::ADD &&
3152 !isa<ConstantSDNode>(LHS.getOperand(1)) &&
3153 isInt<12>(C1->getSExtValue())) {
3154 if (SelectShl(LHS.getOperand(1), Index, Scale) &&
3155 isWorthFoldingIntoRegRegScale(*Subtarget, LHS, LHS.getOperand(1))) {
3156 SDValue C1Val = CurDAG->getTargetConstant(*C1->getConstantIntValue(),
3157 SDLoc(Addr), VT);
3158 Base = SDValue(CurDAG->getMachineNode(RISCV::ADDI, SDLoc(Addr), VT,
3159 LHS.getOperand(0), C1Val),
3160 0);
3161 return true;
3162 }
3163
3164 // Add is commutative so we need to check both operands.
3165 if (SelectShl(LHS.getOperand(0), Index, Scale) &&
3166 isWorthFoldingIntoRegRegScale(*Subtarget, LHS, LHS.getOperand(0))) {
3167 SDValue C1Val = CurDAG->getTargetConstant(*C1->getConstantIntValue(),
3168 SDLoc(Addr), VT);
3169 Base = SDValue(CurDAG->getMachineNode(RISCV::ADDI, SDLoc(Addr), VT,
3170 LHS.getOperand(1), C1Val),
3171 0);
3172 return true;
3173 }
3174 }
3175
3176 // Don't match add with constants.
3177 // FIXME: Is this profitable for large constants that have 0s in the lower
3178 // 12 bits that we can materialize with LUI?
3179 return false;
3180 }
3181
3182 // Try to match a shift on the RHS.
3183 if (SelectShl(RHS, Index, Scale)) {
3184 if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr, RHS))
3185 return false;
3186 Base = LHS;
3187 return true;
3188 }
3189
3190 // Try to match a shift on the LHS.
3191 if (SelectShl(LHS, Index, Scale)) {
3192 if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr, LHS))
3193 return false;
3194 Base = RHS;
3195 return true;
3196 }
3197
3198 if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr))
3199 return false;
3200
3201 Base = LHS;
3202 Index = RHS;
3203 Scale = CurDAG->getTargetConstant(0, SDLoc(Addr), VT);
3204 return true;
3205}
3206
3208 unsigned MaxShiftAmount,
3209 unsigned Bits, SDValue &Base,
3210 SDValue &Index,
3211 SDValue &Scale) {
3212 if (!SelectAddrRegRegScale(Addr, MaxShiftAmount, Base, Index, Scale))
3213 return false;
3214
3215 if (Index.getOpcode() == ISD::AND) {
3216 auto *C = dyn_cast<ConstantSDNode>(Index.getOperand(1));
3217 if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) {
3218 Index = Index.getOperand(0);
3219 return true;
3220 }
3221 }
3222
3223 return false;
3224}
3225
3227 SDValue &Offset) {
3228 if (Addr.getOpcode() != ISD::ADD)
3229 return false;
3230
3231 if (isa<ConstantSDNode>(Addr.getOperand(1)))
3232 return false;
3233
3234 Base = Addr.getOperand(0);
3235 Offset = Addr.getOperand(1);
3236 return true;
3237}
3238
3240 SDValue &ShAmt) {
3241 ShAmt = N;
3242
3243 // Peek through zext.
3244 if (ShAmt->getOpcode() == ISD::ZERO_EXTEND)
3245 ShAmt = ShAmt.getOperand(0);
3246
3247 // Shift instructions on RISC-V only read the lower 5 or 6 bits of the shift
3248 // amount. If there is an AND on the shift amount, we can bypass it if it
3249 // doesn't affect any of those bits.
3250 if (ShAmt.getOpcode() == ISD::AND &&
3251 isa<ConstantSDNode>(ShAmt.getOperand(1))) {
3252 const APInt &AndMask = ShAmt.getConstantOperandAPInt(1);
3253
3254 // Since the max shift amount is a power of 2 we can subtract 1 to make a
3255 // mask that covers the bits needed to represent all shift amounts.
3256 assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
3257 APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
3258
3259 if (ShMask.isSubsetOf(AndMask)) {
3260 ShAmt = ShAmt.getOperand(0);
3261 } else {
3262 // SimplifyDemandedBits may have optimized the mask so try restoring any
3263 // bits that are known zero.
3264 KnownBits Known = CurDAG->computeKnownBits(ShAmt.getOperand(0));
3265 if (!ShMask.isSubsetOf(AndMask | Known.Zero))
3266 return true;
3267 ShAmt = ShAmt.getOperand(0);
3268 }
3269 }
3270
3271 if (ShAmt.getOpcode() == ISD::ADD &&
3272 isa<ConstantSDNode>(ShAmt.getOperand(1))) {
3273 uint64_t Imm = ShAmt.getConstantOperandVal(1);
3274 // If we are shifting by X+N where N == 0 mod Size, then just shift by X
3275 // to avoid the ADD.
3276 if (Imm != 0 && Imm % ShiftWidth == 0) {
3277 ShAmt = ShAmt.getOperand(0);
3278 return true;
3279 }
3280 } else if (ShAmt.getOpcode() == ISD::SUB &&
3281 isa<ConstantSDNode>(ShAmt.getOperand(0))) {
3282 uint64_t Imm = ShAmt.getConstantOperandVal(0);
3283 // If we are shifting by N-X where N == 0 mod Size, then just shift by -X to
3284 // generate a NEG instead of a SUB of a constant.
3285 if (Imm != 0 && Imm % ShiftWidth == 0) {
3286 SDLoc DL(ShAmt);
3287 EVT VT = ShAmt.getValueType();
3288 SDValue Zero = CurDAG->getRegister(RISCV::X0, VT);
3289 unsigned NegOpc = VT == MVT::i64 ? RISCV::SUBW : RISCV::SUB;
3290 MachineSDNode *Neg = CurDAG->getMachineNode(NegOpc, DL, VT, Zero,
3291 ShAmt.getOperand(1));
3292 ShAmt = SDValue(Neg, 0);
3293 return true;
3294 }
3295 // If we are shifting by N-X where N == -1 mod Size, then just shift by ~X
3296 // to generate a NOT instead of a SUB of a constant.
3297 if (Imm % ShiftWidth == ShiftWidth - 1) {
3298 SDLoc DL(ShAmt);
3299 EVT VT = ShAmt.getValueType();
3300 MachineSDNode *Not = CurDAG->getMachineNode(
3301 RISCV::XORI, DL, VT, ShAmt.getOperand(1),
3302 CurDAG->getAllOnesConstant(DL, VT, /*isTarget=*/true));
3303 ShAmt = SDValue(Not, 0);
3304 return true;
3305 }
3306 }
3307
3308 return true;
3309}
3310
3311/// RISC-V doesn't have general instructions for integer setne/seteq, but we can
3312/// check for equality with 0. This function emits instructions that convert the
3313/// seteq/setne into something that can be compared with 0.
3314/// \p ExpectedCCVal indicates the condition code to attempt to match (e.g.
3315/// ISD::SETNE).
3317 SDValue &Val) {
3318 assert(ISD::isIntEqualitySetCC(ExpectedCCVal) &&
3319 "Unexpected condition code!");
3320
3321 // We're looking for a setcc.
3322 if (N->getOpcode() != ISD::SETCC)
3323 return false;
3324
3325 // Must be an equality comparison.
3326 ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
3327 if (CCVal != ExpectedCCVal)
3328 return false;
3329
3330 SDValue LHS = N->getOperand(0);
3331 SDValue RHS = N->getOperand(1);
3332
3333 if (!LHS.getValueType().isScalarInteger())
3334 return false;
3335
3336 // If the RHS side is 0, we don't need any extra instructions, return the LHS.
3337 if (isNullConstant(RHS)) {
3338 Val = LHS;
3339 return true;
3340 }
3341
3342 SDLoc DL(N);
3343
3344 if (auto *C = dyn_cast<ConstantSDNode>(RHS)) {
3345 int64_t CVal = C->getSExtValue();
3346 // If the RHS is -2048, we can use xori to produce 0 if the LHS is -2048 and
3347 // non-zero otherwise.
3348 if (CVal == -2048) {
3349 Val = SDValue(
3350 CurDAG->getMachineNode(
3351 RISCV::XORI, DL, N->getValueType(0), LHS,
3352 CurDAG->getSignedTargetConstant(CVal, DL, N->getValueType(0))),
3353 0);
3354 return true;
3355 }
3356 // If the RHS is [-2047,2048], we can use addi with -RHS to produce 0 if the
3357 // LHS is equal to the RHS and non-zero otherwise.
3358 if (isInt<12>(CVal) || CVal == 2048) {
3359 Val = SDValue(
3360 CurDAG->getMachineNode(
3361 RISCV::ADDI, DL, N->getValueType(0), LHS,
3362 CurDAG->getSignedTargetConstant(-CVal, DL, N->getValueType(0))),
3363 0);
3364 return true;
3365 }
3366 if (isPowerOf2_64(CVal) && Subtarget->hasStdExtZbs()) {
3367 Val = SDValue(
3368 CurDAG->getMachineNode(
3369 RISCV::BINVI, DL, N->getValueType(0), LHS,
3370 CurDAG->getTargetConstant(Log2_64(CVal), DL, N->getValueType(0))),
3371 0);
3372 return true;
3373 }
3374 // Same as the addi case above but for larger immediates (signed 26-bit) use
3375 // the QC_E_ADDI instruction from the Xqcilia extension, if available. Avoid
3376 // anything which can be done with a single lui as it might be compressible.
3377 if (Subtarget->hasVendorXqcilia() && isInt<26>(CVal) &&
3378 (CVal & 0xFFF) != 0) {
3379 Val = SDValue(
3380 CurDAG->getMachineNode(
3381 RISCV::QC_E_ADDI, DL, N->getValueType(0), LHS,
3382 CurDAG->getSignedTargetConstant(-CVal, DL, N->getValueType(0))),
3383 0);
3384 return true;
3385 }
3386 }
3387
3388 // If nothing else we can XOR the LHS and RHS to produce zero if they are
3389 // equal and a non-zero value if they aren't.
3390 Val = SDValue(
3391 CurDAG->getMachineNode(RISCV::XOR, DL, N->getValueType(0), LHS, RHS), 0);
3392 return true;
3393}
3394
3396 if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
3397 cast<VTSDNode>(N.getOperand(1))->getVT().getSizeInBits() == Bits) {
3398 Val = N.getOperand(0);
3399 return true;
3400 }
3401
3402 auto UnwrapShlSra = [](SDValue N, unsigned ShiftAmt) {
3403 if (N.getOpcode() != ISD::SRA || !isa<ConstantSDNode>(N.getOperand(1)))
3404 return N;
3405
3406 SDValue N0 = N.getOperand(0);
3407 if (N0.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N0.getOperand(1)) &&
3408 N.getConstantOperandVal(1) == ShiftAmt &&
3409 N0.getConstantOperandVal(1) == ShiftAmt)
3410 return N0.getOperand(0);
3411
3412 return N;
3413 };
3414
3415 MVT VT = N.getSimpleValueType();
3416 if (CurDAG->ComputeNumSignBits(N) > (VT.getSizeInBits() - Bits)) {
3417 Val = UnwrapShlSra(N, VT.getSizeInBits() - Bits);
3418 return true;
3419 }
3420
3421 return false;
3422}
3423
3425 if (N.getOpcode() == ISD::AND) {
3426 auto *C = dyn_cast<ConstantSDNode>(N.getOperand(1));
3427 if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) {
3428 Val = N.getOperand(0);
3429 return true;
3430 }
3431 }
3432 MVT VT = N.getSimpleValueType();
3433 APInt Mask = APInt::getBitsSetFrom(VT.getSizeInBits(), Bits);
3434 if (CurDAG->MaskedValueIsZero(N, Mask)) {
3435 Val = N;
3436 return true;
3437 }
3438
3439 return false;
3440}
3441
3442/// Look for various patterns that can be done with a SHL that can be folded
3443/// into a SHXADD. \p ShAmt contains 1, 2, or 3 and is set based on which
3444/// SHXADD we are trying to match.
3446 SDValue &Val) {
3447 if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) {
3448 SDValue N0 = N.getOperand(0);
3449
3450 if (bool LeftShift = N0.getOpcode() == ISD::SHL;
3451 (LeftShift || N0.getOpcode() == ISD::SRL) &&
3453 uint64_t Mask = N.getConstantOperandVal(1);
3454 unsigned C2 = N0.getConstantOperandVal(1);
3455
3456 unsigned XLen = Subtarget->getXLen();
3457 if (LeftShift)
3458 Mask &= maskTrailingZeros<uint64_t>(C2);
3459 else
3460 Mask &= maskTrailingOnes<uint64_t>(XLen - C2);
3461
3462 if (isShiftedMask_64(Mask)) {
3463 unsigned Leading = XLen - llvm::bit_width(Mask);
3464 unsigned Trailing = llvm::countr_zero(Mask);
3465 if (Trailing != ShAmt)
3466 return false;
3467
3468 unsigned Opcode;
3469 // Look for (and (shl y, c2), c1) where c1 is a shifted mask with no
3470 // leading zeros and c3 trailing zeros. We can use an SRLI by c3-c2
3471 // followed by a SHXADD with c3 for the X amount.
3472 if (LeftShift && Leading == 0 && C2 < Trailing)
3473 Opcode = RISCV::SRLI;
3474 // Look for (and (shl y, c2), c1) where c1 is a shifted mask with 32-c2
3475 // leading zeros and c3 trailing zeros. We can use an SRLIW by c3-c2
3476 // followed by a SHXADD with c3 for the X amount.
3477 else if (LeftShift && Leading == 32 - C2 && C2 < Trailing)
3478 Opcode = RISCV::SRLIW;
3479 // Look for (and (shr y, c2), c1) where c1 is a shifted mask with c2
3480 // leading zeros and c3 trailing zeros. We can use an SRLI by c2+c3
3481 // followed by a SHXADD using c3 for the X amount.
3482 else if (!LeftShift && Leading == C2)
3483 Opcode = RISCV::SRLI;
3484 // Look for (and (shr y, c2), c1) where c1 is a shifted mask with 32+c2
3485 // leading zeros and c3 trailing zeros. We can use an SRLIW by c2+c3
3486 // followed by a SHXADD using c3 for the X amount.
3487 else if (!LeftShift && Leading == 32 + C2)
3488 Opcode = RISCV::SRLIW;
3489 else
3490 return false;
3491
3492 SDLoc DL(N);
3493 EVT VT = N.getValueType();
3494 ShAmt = LeftShift ? Trailing - C2 : Trailing + C2;
3495 Val = SDValue(
3496 CurDAG->getMachineNode(Opcode, DL, VT, N0.getOperand(0),
3497 CurDAG->getTargetConstant(ShAmt, DL, VT)),
3498 0);
3499 return true;
3500 }
3501 } else if (N0.getOpcode() == ISD::SRA && N0.hasOneUse() &&
3503 uint64_t Mask = N.getConstantOperandVal(1);
3504 unsigned C2 = N0.getConstantOperandVal(1);
3505
3506 // Look for (and (sra y, c2), c1) where c1 is a shifted mask with c3
3507 // leading zeros and c4 trailing zeros. If c2 is greater than c3, we can
3508 // use (srli (srai y, c2 - c3), c3 + c4) followed by a SHXADD with c4 as
3509 // the X amount.
3510 if (isShiftedMask_64(Mask)) {
3511 unsigned XLen = Subtarget->getXLen();
3512 unsigned Leading = XLen - llvm::bit_width(Mask);
3513 unsigned Trailing = llvm::countr_zero(Mask);
3514 if (C2 > Leading && Leading > 0 && Trailing == ShAmt) {
3515 SDLoc DL(N);
3516 EVT VT = N.getValueType();
3517 Val = SDValue(CurDAG->getMachineNode(
3518 RISCV::SRAI, DL, VT, N0.getOperand(0),
3519 CurDAG->getTargetConstant(C2 - Leading, DL, VT)),
3520 0);
3521 Val = SDValue(CurDAG->getMachineNode(
3522 RISCV::SRLI, DL, VT, Val,
3523 CurDAG->getTargetConstant(Leading + ShAmt, DL, VT)),
3524 0);
3525 return true;
3526 }
3527 }
3528 }
3529 } else if (bool LeftShift = N.getOpcode() == ISD::SHL;
3530 (LeftShift || N.getOpcode() == ISD::SRL) &&
3531 isa<ConstantSDNode>(N.getOperand(1))) {
3532 SDValue N0 = N.getOperand(0);
3533 if (N0.getOpcode() == ISD::AND && N0.hasOneUse() &&
3535 uint64_t Mask = N0.getConstantOperandVal(1);
3536 if (isShiftedMask_64(Mask)) {
3537 unsigned C1 = N.getConstantOperandVal(1);
3538 unsigned XLen = Subtarget->getXLen();
3539 unsigned Leading = XLen - llvm::bit_width(Mask);
3540 unsigned Trailing = llvm::countr_zero(Mask);
3541 // Look for (shl (and X, Mask), C1) where Mask has 32 leading zeros and
3542 // C3 trailing zeros. If C1+C3==ShAmt we can use SRLIW+SHXADD.
3543 if (LeftShift && Leading == 32 && Trailing > 0 &&
3544 (Trailing + C1) == ShAmt) {
3545 SDLoc DL(N);
3546 EVT VT = N.getValueType();
3547 Val = SDValue(CurDAG->getMachineNode(
3548 RISCV::SRLIW, DL, VT, N0.getOperand(0),
3549 CurDAG->getTargetConstant(Trailing, DL, VT)),
3550 0);
3551 return true;
3552 }
3553 // Look for (srl (and X, Mask), C1) where Mask has 32 leading zeros and
3554 // C3 trailing zeros. If C3-C1==ShAmt we can use SRLIW+SHXADD.
3555 if (!LeftShift && Leading == 32 && Trailing > C1 &&
3556 (Trailing - C1) == ShAmt) {
3557 SDLoc DL(N);
3558 EVT VT = N.getValueType();
3559 Val = SDValue(CurDAG->getMachineNode(
3560 RISCV::SRLIW, DL, VT, N0.getOperand(0),
3561 CurDAG->getTargetConstant(Trailing, DL, VT)),
3562 0);
3563 return true;
3564 }
3565 }
3566 }
3567 }
3568
3569 return false;
3570}
3571
3572/// Look for various patterns that can be done with a SHL that can be folded
3573/// into a SHXADD_UW. \p ShAmt contains 1, 2, or 3 and is set based on which
3574/// SHXADD_UW we are trying to match.
3576 SDValue &Val) {
3577 if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1)) &&
3578 N.hasOneUse()) {
3579 SDValue N0 = N.getOperand(0);
3580 if (N0.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N0.getOperand(1)) &&
3581 N0.hasOneUse()) {
3582 uint64_t Mask = N.getConstantOperandVal(1);
3583 unsigned C2 = N0.getConstantOperandVal(1);
3584
3585 Mask &= maskTrailingZeros<uint64_t>(C2);
3586
3587 // Look for (and (shl y, c2), c1) where c1 is a shifted mask with
3588 // 32-ShAmt leading zeros and c2 trailing zeros. We can use SLLI by
3589 // c2-ShAmt followed by SHXADD_UW with ShAmt for the X amount.
3590 if (isShiftedMask_64(Mask)) {
3591 unsigned Leading = llvm::countl_zero(Mask);
3592 unsigned Trailing = llvm::countr_zero(Mask);
3593 if (Leading == 32 - ShAmt && Trailing == C2 && Trailing > ShAmt) {
3594 SDLoc DL(N);
3595 EVT VT = N.getValueType();
3596 Val = SDValue(CurDAG->getMachineNode(
3597 RISCV::SLLI, DL, VT, N0.getOperand(0),
3598 CurDAG->getTargetConstant(C2 - ShAmt, DL, VT)),
3599 0);
3600 return true;
3601 }
3602 }
3603 }
3604 }
3605
3606 return false;
3607}
3608
3610 assert(N->getOpcode() == ISD::OR || N->getOpcode() == RISCVISD::OR_VL);
3611 if (N->getFlags().hasDisjoint())
3612 return true;
3613 return CurDAG->haveNoCommonBitsSet(N->getOperand(0), N->getOperand(1));
3614}
3615
3616bool RISCVDAGToDAGISel::selectImm64IfCheaper(int64_t Imm, int64_t OrigImm,
3617 SDValue N, SDValue &Val) {
3618 int OrigCost = RISCVMatInt::getIntMatCost(APInt(64, OrigImm), 64, *Subtarget,
3619 /*CompressionCost=*/true);
3620 int Cost = RISCVMatInt::getIntMatCost(APInt(64, Imm), 64, *Subtarget,
3621 /*CompressionCost=*/true);
3622 if (OrigCost <= Cost)
3623 return false;
3624
3625 Val = selectImm(CurDAG, SDLoc(N), N->getSimpleValueType(0), Imm, *Subtarget);
3626 return true;
3627}
3628
3630 if (!isa<ConstantSDNode>(N))
3631 return false;
3632 int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
3633 if ((Imm >> 31) != 1)
3634 return false;
3635
3636 for (const SDNode *U : N->users()) {
3637 switch (U->getOpcode()) {
3638 case ISD::ADD:
3639 break;
3640 case ISD::OR:
3641 if (orDisjoint(U))
3642 break;
3643 return false;
3644 default:
3645 return false;
3646 }
3647 }
3648
3649 return selectImm64IfCheaper(0xffffffff00000000 | Imm, Imm, N, Val);
3650}
3651
3653 if (!isa<ConstantSDNode>(N))
3654 return false;
3655 int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
3656 if (isInt<32>(Imm))
3657 return false;
3658
3659 for (const SDNode *U : N->users()) {
3660 switch (U->getOpcode()) {
3661 case ISD::ADD:
3662 break;
3663 case RISCVISD::VMV_V_X_VL:
3664 if (!all_of(U->users(), [](const SDNode *V) {
3665 return V->getOpcode() == ISD::ADD ||
3666 V->getOpcode() == RISCVISD::ADD_VL;
3667 }))
3668 return false;
3669 break;
3670 default:
3671 return false;
3672 }
3673 }
3674
3675 return selectImm64IfCheaper(-Imm, Imm, N, Val);
3676}
3677
3679 if (!isa<ConstantSDNode>(N))
3680 return false;
3681 int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
3682
3683 // For 32-bit signed constants, we can only substitute LUI+ADDI with LUI.
3684 if (isInt<32>(Imm) && ((Imm & 0xfff) != 0xfff || Imm == -1))
3685 return false;
3686
3687 // Abandon this transform if the constant is needed elsewhere.
3688 for (const SDNode *U : N->users()) {
3689 switch (U->getOpcode()) {
3690 case ISD::AND:
3691 case ISD::OR:
3692 case ISD::XOR:
3693 if (!(Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbkb()))
3694 return false;
3695 break;
3696 case RISCVISD::VMV_V_X_VL:
3697 if (!Subtarget->hasStdExtZvkb())
3698 return false;
3699 if (!all_of(U->users(), [](const SDNode *V) {
3700 return V->getOpcode() == ISD::AND ||
3701 V->getOpcode() == RISCVISD::AND_VL;
3702 }))
3703 return false;
3704 break;
3705 default:
3706 return false;
3707 }
3708 }
3709
3710 if (isInt<32>(Imm)) {
3711 Val =
3712 selectImm(CurDAG, SDLoc(N), N->getSimpleValueType(0), ~Imm, *Subtarget);
3713 return true;
3714 }
3715
3716 // For 64-bit constants, the instruction sequences get complex,
3717 // so we select inverted only if it's cheaper.
3718 return selectImm64IfCheaper(~Imm, Imm, N, Val);
3719}
3720
3721static bool vectorPseudoHasAllNBitUsers(SDNode *User, unsigned UserOpNo,
3722 unsigned Bits,
3723 const TargetInstrInfo *TII) {
3724 unsigned MCOpcode = RISCV::getRVVMCOpcode(User->getMachineOpcode());
3725
3726 if (!MCOpcode)
3727 return false;
3728
3729 const MCInstrDesc &MCID = TII->get(User->getMachineOpcode());
3730 const uint64_t TSFlags = MCID.TSFlags;
3731 if (!RISCVII::hasSEWOp(TSFlags))
3732 return false;
3733 assert(RISCVII::hasVLOp(TSFlags));
3734
3735 unsigned ChainOpIdx = User->getNumOperands() - 1;
3736 bool HasChainOp = User->getOperand(ChainOpIdx).getValueType() == MVT::Other;
3737 bool HasVecPolicyOp = RISCVII::hasVecPolicyOp(TSFlags);
3738 unsigned VLIdx = User->getNumOperands() - HasVecPolicyOp - HasChainOp - 2;
3739 const unsigned Log2SEW = User->getConstantOperandVal(VLIdx + 1);
3740
3741 if (UserOpNo == VLIdx)
3742 return false;
3743
3744 auto NumDemandedBits =
3745 RISCV::getVectorLowDemandedScalarBits(MCOpcode, Log2SEW);
3746 return NumDemandedBits && Bits >= *NumDemandedBits;
3747}
3748
3749// Return true if all users of this SDNode* only consume the lower \p Bits.
3750// This can be used to form W instructions for add/sub/mul/shl even when the
3751// root isn't a sext_inreg. This can allow the ADDW/SUBW/MULW/SLLIW to CSE if
3752// SimplifyDemandedBits has made it so some users see a sext_inreg and some
3753// don't. The sext_inreg+add/sub/mul/shl will get selected, but still leave
3754// the add/sub/mul/shl to become non-W instructions. By checking the users we
3755// may be able to use a W instruction and CSE with the other instruction if
3756// this has happened. We could try to detect that the CSE opportunity exists
3757// before doing this, but that would be more complicated.
3759 const unsigned Depth) const {
3760 assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB ||
3761 Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL ||
3762 Node->getOpcode() == ISD::SRL || Node->getOpcode() == ISD::AND ||
3763 Node->getOpcode() == ISD::OR || Node->getOpcode() == ISD::XOR ||
3764 Node->getOpcode() == ISD::SIGN_EXTEND_INREG ||
3765 isa<ConstantSDNode>(Node) || Depth != 0) &&
3766 "Unexpected opcode");
3767
3769 return false;
3770
3771 // The PatFrags that call this may run before RISCVGenDAGISel.inc has checked
3772 // the VT. Ensure the type is scalar to avoid wasting time on vectors.
3773 if (Depth == 0 && !Node->getValueType(0).isScalarInteger())
3774 return false;
3775
3776 for (SDUse &Use : Node->uses()) {
3777 SDNode *User = Use.getUser();
3778 // Users of this node should have already been instruction selected
3779 if (!User->isMachineOpcode())
3780 return false;
3781
3782 // TODO: Add more opcodes?
3783 switch (User->getMachineOpcode()) {
3784 default:
3786 break;
3787 return false;
3788 case RISCV::ADDW:
3789 case RISCV::ADDIW:
3790 case RISCV::SUBW:
3791 case RISCV::MULW:
3792 case RISCV::SLLW:
3793 case RISCV::SLLIW:
3794 case RISCV::SRAW:
3795 case RISCV::SRAIW:
3796 case RISCV::SRLW:
3797 case RISCV::SRLIW:
3798 case RISCV::DIVW:
3799 case RISCV::DIVUW:
3800 case RISCV::REMW:
3801 case RISCV::REMUW:
3802 case RISCV::ROLW:
3803 case RISCV::RORW:
3804 case RISCV::RORIW:
3805 case RISCV::CLZW:
3806 case RISCV::CTZW:
3807 case RISCV::CPOPW:
3808 case RISCV::SLLI_UW:
3809 case RISCV::FMV_W_X:
3810 case RISCV::FCVT_H_W:
3811 case RISCV::FCVT_H_W_INX:
3812 case RISCV::FCVT_H_WU:
3813 case RISCV::FCVT_H_WU_INX:
3814 case RISCV::FCVT_S_W:
3815 case RISCV::FCVT_S_W_INX:
3816 case RISCV::FCVT_S_WU:
3817 case RISCV::FCVT_S_WU_INX:
3818 case RISCV::FCVT_D_W:
3819 case RISCV::FCVT_D_W_INX:
3820 case RISCV::FCVT_D_WU:
3821 case RISCV::FCVT_D_WU_INX:
3822 case RISCV::TH_REVW:
3823 case RISCV::TH_SRRIW:
3824 if (Bits >= 32)
3825 break;
3826 return false;
3827 case RISCV::SLL:
3828 case RISCV::SRA:
3829 case RISCV::SRL:
3830 case RISCV::ROL:
3831 case RISCV::ROR:
3832 case RISCV::BSET:
3833 case RISCV::BCLR:
3834 case RISCV::BINV:
3835 // Shift amount operands only use log2(Xlen) bits.
3836 if (Use.getOperandNo() == 1 && Bits >= Log2_32(Subtarget->getXLen()))
3837 break;
3838 return false;
3839 case RISCV::SLLI:
3840 // SLLI only uses the lower (XLen - ShAmt) bits.
3841 if (Bits >= Subtarget->getXLen() - User->getConstantOperandVal(1))
3842 break;
3843 return false;
3844 case RISCV::ANDI:
3845 if (Bits >= (unsigned)llvm::bit_width(User->getConstantOperandVal(1)))
3846 break;
3847 goto RecCheck;
3848 case RISCV::ORI: {
3849 uint64_t Imm = cast<ConstantSDNode>(User->getOperand(1))->getSExtValue();
3850 if (Bits >= (unsigned)llvm::bit_width<uint64_t>(~Imm))
3851 break;
3852 [[fallthrough]];
3853 }
3854 case RISCV::AND:
3855 case RISCV::OR:
3856 case RISCV::XOR:
3857 case RISCV::XORI:
3858 case RISCV::ANDN:
3859 case RISCV::ORN:
3860 case RISCV::XNOR:
3861 case RISCV::SH1ADD:
3862 case RISCV::SH2ADD:
3863 case RISCV::SH3ADD:
3864 RecCheck:
3865 if (hasAllNBitUsers(User, Bits, Depth + 1))
3866 break;
3867 return false;
3868 case RISCV::SRLI: {
3869 unsigned ShAmt = User->getConstantOperandVal(1);
3870 // If we are shifting right by less than Bits, and users don't demand any
3871 // bits that were shifted into [Bits-1:0], then we can consider this as an
3872 // N-Bit user.
3873 if (Bits > ShAmt && hasAllNBitUsers(User, Bits - ShAmt, Depth + 1))
3874 break;
3875 return false;
3876 }
3877 case RISCV::SEXT_B:
3878 case RISCV::PACKH:
3879 if (Bits >= 8)
3880 break;
3881 return false;
3882 case RISCV::SEXT_H:
3883 case RISCV::FMV_H_X:
3884 case RISCV::ZEXT_H_RV32:
3885 case RISCV::ZEXT_H_RV64:
3886 case RISCV::PACKW:
3887 if (Bits >= 16)
3888 break;
3889 return false;
3890 case RISCV::PACK:
3891 if (Bits >= (Subtarget->getXLen() / 2))
3892 break;
3893 return false;
3894 case RISCV::ADD_UW:
3895 case RISCV::SH1ADD_UW:
3896 case RISCV::SH2ADD_UW:
3897 case RISCV::SH3ADD_UW:
3898 // The first operand to add.uw/shXadd.uw is implicitly zero extended from
3899 // 32 bits.
3900 if (Use.getOperandNo() == 0 && Bits >= 32)
3901 break;
3902 return false;
3903 case RISCV::SB:
3904 if (Use.getOperandNo() == 0 && Bits >= 8)
3905 break;
3906 return false;
3907 case RISCV::SH:
3908 if (Use.getOperandNo() == 0 && Bits >= 16)
3909 break;
3910 return false;
3911 case RISCV::SW:
3912 if (Use.getOperandNo() == 0 && Bits >= 32)
3913 break;
3914 return false;
3915 case RISCV::TH_EXT:
3916 case RISCV::TH_EXTU: {
3917 unsigned Msb = User->getConstantOperandVal(1);
3918 unsigned Lsb = User->getConstantOperandVal(2);
3919 // Behavior of Msb < Lsb is not well documented.
3920 if (Msb >= Lsb && Bits > Msb)
3921 break;
3922 return false;
3923 }
3924 }
3925 }
3926
3927 return true;
3928}
3929
3930// Select a constant that can be represented as (sign_extend(imm5) << imm2).
3932 SDValue &Shl2) {
3933 auto *C = dyn_cast<ConstantSDNode>(N);
3934 if (!C)
3935 return false;
3936
3937 int64_t Offset = C->getSExtValue();
3938 for (unsigned Shift = 0; Shift < 4; Shift++) {
3939 if (isInt<5>(Offset >> Shift) && ((Offset % (1LL << Shift)) == 0)) {
3940 EVT VT = N->getValueType(0);
3941 Simm5 = CurDAG->getSignedTargetConstant(Offset >> Shift, SDLoc(N), VT);
3942 Shl2 = CurDAG->getTargetConstant(Shift, SDLoc(N), VT);
3943 return true;
3944 }
3945 }
3946
3947 return false;
3948}
3949
3950// Select VL as a 5 bit immediate or a value that will become a register. This
3951// allows us to choose between VSETIVLI or VSETVLI later.
3953 auto *C = dyn_cast<ConstantSDNode>(N);
3954 if (C && isUInt<5>(C->getZExtValue())) {
3955 VL = CurDAG->getTargetConstant(C->getZExtValue(), SDLoc(N),
3956 N->getValueType(0));
3957 } else if (C && C->isAllOnes()) {
3958 // Treat all ones as VLMax.
3959 VL = CurDAG->getSignedTargetConstant(RISCV::VLMaxSentinel, SDLoc(N),
3960 N->getValueType(0));
3961 } else if (isa<RegisterSDNode>(N) &&
3962 cast<RegisterSDNode>(N)->getReg() == RISCV::X0) {
3963 // All our VL operands use an operand that allows GPRNoX0 or an immediate
3964 // as the register class. Convert X0 to a special immediate to pass the
3965 // MachineVerifier. This is recognized specially by the vsetvli insertion
3966 // pass.
3967 VL = CurDAG->getSignedTargetConstant(RISCV::VLMaxSentinel, SDLoc(N),
3968 N->getValueType(0));
3969 } else {
3970 VL = N;
3971 }
3972
3973 return true;
3974}
3975
3977 if (N.getOpcode() == ISD::INSERT_SUBVECTOR) {
3978 if (!N.getOperand(0).isUndef())
3979 return SDValue();
3980 N = N.getOperand(1);
3981 }
3982 SDValue Splat = N;
3983 if ((Splat.getOpcode() != RISCVISD::VMV_V_X_VL &&
3984 Splat.getOpcode() != RISCVISD::VMV_S_X_VL) ||
3985 !Splat.getOperand(0).isUndef())
3986 return SDValue();
3987 assert(Splat.getNumOperands() == 3 && "Unexpected number of operands");
3988 return Splat;
3989}
3990
3993 if (!Splat)
3994 return false;
3995
3996 SplatVal = Splat.getOperand(1);
3997 return true;
3998}
3999
4001 SelectionDAG &DAG,
4002 const RISCVSubtarget &Subtarget,
4003 std::function<bool(int64_t)> ValidateImm,
4004 bool Decrement = false) {
4006 if (!Splat || !isa<ConstantSDNode>(Splat.getOperand(1)))
4007 return false;
4008
4009 const unsigned SplatEltSize = Splat.getScalarValueSizeInBits();
4010 assert(Subtarget.getXLenVT() == Splat.getOperand(1).getSimpleValueType() &&
4011 "Unexpected splat operand type");
4012
4013 // The semantics of RISCVISD::VMV_V_X_VL is that when the operand
4014 // type is wider than the resulting vector element type: an implicit
4015 // truncation first takes place. Therefore, perform a manual
4016 // truncation/sign-extension in order to ignore any truncated bits and catch
4017 // any zero-extended immediate.
4018 // For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first
4019 // sign-extending to (XLenVT -1).
4020 APInt SplatConst = Splat.getConstantOperandAPInt(1).sextOrTrunc(SplatEltSize);
4021
4022 int64_t SplatImm = SplatConst.getSExtValue();
4023
4024 if (!ValidateImm(SplatImm))
4025 return false;
4026
4027 if (Decrement)
4028 SplatImm -= 1;
4029
4030 SplatVal =
4031 DAG.getSignedTargetConstant(SplatImm, SDLoc(N), Subtarget.getXLenVT());
4032 return true;
4033}
4034
4036 return selectVSplatImmHelper(N, SplatVal, *CurDAG, *Subtarget,
4037 [](int64_t Imm) { return isInt<5>(Imm); });
4038}
4039
4041 return selectVSplatImmHelper(
4042 N, SplatVal, *CurDAG, *Subtarget,
4043 [](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; },
4044 /*Decrement=*/true);
4045}
4046
4048 return selectVSplatImmHelper(
4049 N, SplatVal, *CurDAG, *Subtarget,
4050 [](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; },
4051 /*Decrement=*/false);
4052}
4053
4055 SDValue &SplatVal) {
4056 return selectVSplatImmHelper(
4057 N, SplatVal, *CurDAG, *Subtarget,
4058 [](int64_t Imm) {
4059 return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16);
4060 },
4061 /*Decrement=*/true);
4062}
4063
4065 SDValue &SplatVal) {
4066 return selectVSplatImmHelper(
4067 N, SplatVal, *CurDAG, *Subtarget,
4068 [Bits](int64_t Imm) { return isUIntN(Bits, Imm); });
4069}
4070
4073 return Splat && selectNegImm(Splat.getOperand(1), SplatVal);
4074}
4075
4077 auto IsExtOrTrunc = [](SDValue N) {
4078 switch (N->getOpcode()) {
4079 case ISD::SIGN_EXTEND:
4080 case ISD::ZERO_EXTEND:
4081 // There's no passthru on these _VL nodes so any VL/mask is ok, since any
4082 // inactive elements will be undef.
4083 case RISCVISD::TRUNCATE_VECTOR_VL:
4084 case RISCVISD::VSEXT_VL:
4085 case RISCVISD::VZEXT_VL:
4086 return true;
4087 default:
4088 return false;
4089 }
4090 };
4091
4092 // We can have multiple nested nodes, so unravel them all if needed.
4093 while (IsExtOrTrunc(N)) {
4094 if (!N.hasOneUse() || N.getScalarValueSizeInBits() < 8)
4095 return false;
4096 N = N->getOperand(0);
4097 }
4098
4099 return selectVSplat(N, SplatVal);
4100}
4101
4103 // Allow bitcasts from XLenVT -> FP.
4104 if (N.getOpcode() == ISD::BITCAST &&
4105 N.getOperand(0).getValueType() == Subtarget->getXLenVT()) {
4106 Imm = N.getOperand(0);
4107 return true;
4108 }
4109 // Allow moves from XLenVT to FP.
4110 if (N.getOpcode() == RISCVISD::FMV_H_X ||
4111 N.getOpcode() == RISCVISD::FMV_W_X_RV64) {
4112 Imm = N.getOperand(0);
4113 return true;
4114 }
4115
4116 // Otherwise, look for FP constants that can materialized with scalar int.
4118 if (!CFP)
4119 return false;
4120 const APFloat &APF = CFP->getValueAPF();
4121 // td can handle +0.0 already.
4122 if (APF.isPosZero())
4123 return false;
4124
4125 MVT VT = CFP->getSimpleValueType(0);
4126
4127 MVT XLenVT = Subtarget->getXLenVT();
4128 if (VT == MVT::f64 && !Subtarget->is64Bit()) {
4129 assert(APF.isNegZero() && "Unexpected constant.");
4130 return false;
4131 }
4132 SDLoc DL(N);
4133 Imm = selectImm(CurDAG, DL, XLenVT, APF.bitcastToAPInt().getSExtValue(),
4134 *Subtarget);
4135 return true;
4136}
4137
4139 SDValue &Imm) {
4140 if (auto *C = dyn_cast<ConstantSDNode>(N)) {
4141 int64_t ImmVal = SignExtend64(C->getSExtValue(), Width);
4142
4143 if (!isInt<5>(ImmVal))
4144 return false;
4145
4146 Imm = CurDAG->getSignedTargetConstant(ImmVal, SDLoc(N),
4147 Subtarget->getXLenVT());
4148 return true;
4149 }
4150
4151 return false;
4152}
4153
4154// Try to remove sext.w if the input is a W instruction or can be made into
4155// a W instruction cheaply.
4156bool RISCVDAGToDAGISel::doPeepholeSExtW(SDNode *N) {
4157 // Look for the sext.w pattern, addiw rd, rs1, 0.
4158 if (N->getMachineOpcode() != RISCV::ADDIW ||
4159 !isNullConstant(N->getOperand(1)))
4160 return false;
4161
4162 SDValue N0 = N->getOperand(0);
4163 if (!N0.isMachineOpcode())
4164 return false;
4165
4166 switch (N0.getMachineOpcode()) {
4167 default:
4168 break;
4169 case RISCV::ADD:
4170 case RISCV::ADDI:
4171 case RISCV::SUB:
4172 case RISCV::MUL:
4173 case RISCV::SLLI: {
4174 // Convert sext.w+add/sub/mul to their W instructions. This will create
4175 // a new independent instruction. This improves latency.
4176 unsigned Opc;
4177 switch (N0.getMachineOpcode()) {
4178 default:
4179 llvm_unreachable("Unexpected opcode!");
4180 case RISCV::ADD: Opc = RISCV::ADDW; break;
4181 case RISCV::ADDI: Opc = RISCV::ADDIW; break;
4182 case RISCV::SUB: Opc = RISCV::SUBW; break;
4183 case RISCV::MUL: Opc = RISCV::MULW; break;
4184 case RISCV::SLLI: Opc = RISCV::SLLIW; break;
4185 }
4186
4187 SDValue N00 = N0.getOperand(0);
4188 SDValue N01 = N0.getOperand(1);
4189
4190 // Shift amount needs to be uimm5.
4191 if (N0.getMachineOpcode() == RISCV::SLLI &&
4192 !isUInt<5>(cast<ConstantSDNode>(N01)->getSExtValue()))
4193 break;
4194
4195 SDNode *Result =
4196 CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0),
4197 N00, N01);
4198 ReplaceUses(N, Result);
4199 return true;
4200 }
4201 case RISCV::ADDW:
4202 case RISCV::ADDIW:
4203 case RISCV::SUBW:
4204 case RISCV::MULW:
4205 case RISCV::SLLIW:
4206 case RISCV::PACKW:
4207 case RISCV::TH_MULAW:
4208 case RISCV::TH_MULAH:
4209 case RISCV::TH_MULSW:
4210 case RISCV::TH_MULSH:
4211 if (N0.getValueType() == MVT::i32)
4212 break;
4213
4214 // Result is already sign extended just remove the sext.w.
4215 // NOTE: We only handle the nodes that are selected with hasAllWUsers.
4216 ReplaceUses(N, N0.getNode());
4217 return true;
4218 }
4219
4220 return false;
4221}
4222
4223static bool usesAllOnesMask(SDValue MaskOp) {
4224 const auto IsVMSet = [](unsigned Opc) {
4225 return Opc == RISCV::PseudoVMSET_M_B1 || Opc == RISCV::PseudoVMSET_M_B16 ||
4226 Opc == RISCV::PseudoVMSET_M_B2 || Opc == RISCV::PseudoVMSET_M_B32 ||
4227 Opc == RISCV::PseudoVMSET_M_B4 || Opc == RISCV::PseudoVMSET_M_B64 ||
4228 Opc == RISCV::PseudoVMSET_M_B8;
4229 };
4230
4231 // TODO: Check that the VMSET is the expected bitwidth? The pseudo has
4232 // undefined behaviour if it's the wrong bitwidth, so we could choose to
4233 // assume that it's all-ones? Same applies to its VL.
4234 return MaskOp->isMachineOpcode() && IsVMSet(MaskOp.getMachineOpcode());
4235}
4236
4237static bool isImplicitDef(SDValue V) {
4238 if (!V.isMachineOpcode())
4239 return false;
4240 if (V.getMachineOpcode() == TargetOpcode::REG_SEQUENCE) {
4241 for (unsigned I = 1; I < V.getNumOperands(); I += 2)
4242 if (!isImplicitDef(V.getOperand(I)))
4243 return false;
4244 return true;
4245 }
4246 return V.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;
4247}
4248
4249// Optimize masked RVV pseudo instructions with a known all-ones mask to their
4250// corresponding "unmasked" pseudo versions.
4251bool RISCVDAGToDAGISel::doPeepholeMaskedRVV(MachineSDNode *N) {
4252 const RISCV::RISCVMaskedPseudoInfo *I =
4253 RISCV::getMaskedPseudoInfo(N->getMachineOpcode());
4254 if (!I)
4255 return false;
4256
4257 unsigned MaskOpIdx = I->MaskOpIdx;
4258 if (!usesAllOnesMask(N->getOperand(MaskOpIdx)))
4259 return false;
4260
4261 // There are two classes of pseudos in the table - compares and
4262 // everything else. See the comment on RISCVMaskedPseudo for details.
4263 const unsigned Opc = I->UnmaskedPseudo;
4264 const MCInstrDesc &MCID = TII->get(Opc);
4265 const bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(MCID);
4266
4267 const MCInstrDesc &MaskedMCID = TII->get(N->getMachineOpcode());
4268 const bool MaskedHasPassthru = RISCVII::isFirstDefTiedToFirstUse(MaskedMCID);
4269
4270 assert((RISCVII::hasVecPolicyOp(MaskedMCID.TSFlags) ||
4272 "Unmasked pseudo has policy but masked pseudo doesn't?");
4273 assert(RISCVII::hasVecPolicyOp(MCID.TSFlags) == HasPassthru &&
4274 "Unexpected pseudo structure");
4275 assert(!(HasPassthru && !MaskedHasPassthru) &&
4276 "Unmasked pseudo has passthru but masked pseudo doesn't?");
4277
4279 // Skip the passthru operand at index 0 if the unmasked don't have one.
4280 bool ShouldSkip = !HasPassthru && MaskedHasPassthru;
4281 bool DropPolicy = !RISCVII::hasVecPolicyOp(MCID.TSFlags) &&
4282 RISCVII::hasVecPolicyOp(MaskedMCID.TSFlags);
4283 bool HasChainOp =
4284 N->getOperand(N->getNumOperands() - 1).getValueType() == MVT::Other;
4285 unsigned LastOpNum = N->getNumOperands() - 1 - HasChainOp;
4286 for (unsigned I = ShouldSkip, E = N->getNumOperands(); I != E; I++) {
4287 // Skip the mask
4288 SDValue Op = N->getOperand(I);
4289 if (I == MaskOpIdx)
4290 continue;
4291 if (DropPolicy && I == LastOpNum)
4292 continue;
4293 Ops.push_back(Op);
4294 }
4295
4296 MachineSDNode *Result =
4297 CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
4298
4299 if (!N->memoperands_empty())
4300 CurDAG->setNodeMemRefs(Result, N->memoperands());
4301
4302 Result->setFlags(N->getFlags());
4303 ReplaceUses(N, Result);
4304
4305 return true;
4306}
4307
4308/// If our passthru is an implicit_def, use noreg instead. This side
4309/// steps issues with MachineCSE not being able to CSE expressions with
4310/// IMPLICIT_DEF operands while preserving the semantic intent. See
4311/// pr64282 for context. Note that this transform is the last one
4312/// performed at ISEL DAG to DAG.
4313bool RISCVDAGToDAGISel::doPeepholeNoRegPassThru() {
4314 bool MadeChange = false;
4315 SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end();
4316
4317 while (Position != CurDAG->allnodes_begin()) {
4318 SDNode *N = &*--Position;
4319 if (N->use_empty() || !N->isMachineOpcode())
4320 continue;
4321
4322 const unsigned Opc = N->getMachineOpcode();
4323 if (!RISCVVPseudosTable::getPseudoInfo(Opc) ||
4325 !isImplicitDef(N->getOperand(0)))
4326 continue;
4327
4329 Ops.push_back(CurDAG->getRegister(RISCV::NoRegister, N->getValueType(0)));
4330 for (unsigned I = 1, E = N->getNumOperands(); I != E; I++) {
4331 SDValue Op = N->getOperand(I);
4332 Ops.push_back(Op);
4333 }
4334
4335 MachineSDNode *Result =
4336 CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
4337 Result->setFlags(N->getFlags());
4338 CurDAG->setNodeMemRefs(Result, cast<MachineSDNode>(N)->memoperands());
4339 ReplaceUses(N, Result);
4340 MadeChange = true;
4341 }
4342 return MadeChange;
4343}
4344
4345
4346// This pass converts a legalized DAG into a RISCV-specific DAG, ready
4347// for instruction scheduling.
4349 CodeGenOptLevel OptLevel) {
4350 return new RISCVDAGToDAGISelLegacy(TM, OptLevel);
4351}
4352
4354
4359
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define I(x, y, z)
Definition MD5.cpp:58
mir Rename Register Operands
Register const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val)
static bool usesAllOnesMask(SDValue MaskOp)
static SDValue selectImm(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT, int64_t Imm, const RISCVSubtarget &Subtarget)
static bool isRegRegScaleLoadOrStore(SDNode *User, SDValue Add, const RISCVSubtarget &Subtarget)
Return true if this a load/store that we have a RegRegScale instruction for.
#define CASE_VMNAND_VMSET_OPCODES(lmulenum, suffix)
static bool isWorthFoldingAdd(SDValue Add)
static SDValue selectImmSeq(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT, RISCVMatInt::InstSeq &Seq)
static bool isImplicitDef(SDValue V)
#define CASE_VMXOR_VMANDN_VMOR_OPCODES(lmulenum, suffix)
static bool selectVSplatImmHelper(SDValue N, SDValue &SplatVal, SelectionDAG &DAG, const RISCVSubtarget &Subtarget, std::function< bool(int64_t)> ValidateImm, bool Decrement=false)
static unsigned getSegInstNF(unsigned Intrinsic)
static bool isWorthFoldingIntoRegRegScale(const RISCVSubtarget &Subtarget, SDValue Add, SDValue Shift=SDValue())
Is it profitable to fold this Add into RegRegScale load/store.
static bool vectorPseudoHasAllNBitUsers(SDNode *User, unsigned UserOpNo, unsigned Bits, const TargetInstrInfo *TII)
static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT, const RISCVSubtarget *Subtarget, SDValue Addr, SDValue &Base, SDValue &Offset, bool IsPrefetch=false)
#define INST_ALL_NF_CASE_WITH_FF(NAME)
#define CASE_VMSLT_OPCODES(lmulenum, suffix)
bool isRegImmLoadOrStore(SDNode *User, SDValue Add)
static cl::opt< bool > UsePseudoMovImm("riscv-use-rematerializable-movimm", cl::Hidden, cl::desc("Use a rematerializable pseudoinstruction for 2 instruction " "constant materialization"), cl::init(false))
static SDValue findVSplat(SDValue N)
#define INST_ALL_NF_CASE(NAME)
Contains matchers for matching SelectionDAG nodes and values.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
#define PASS_NAME
DEMANGLE_DUMP_METHOD void dump() const
bool isZero() const
Definition APFloat.h:1445
APInt bitcastToAPInt() const
Definition APFloat.h:1353
bool isPosZero() const
Definition APFloat.h:1460
bool isNegZero() const
Definition APFloat.h:1461
Class for arbitrary precision integers.
Definition APInt.h:78
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1488
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:219
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition APInt.h:1257
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
Definition APInt.h:286
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1562
const APFloat & getValueAPF() const
uint64_t getZExtValue() const
int64_t getSExtValue() const
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
This class is used to form a handle around another node that is persistent and is updated across invo...
const SDValue & getValue() const
static StringRef getMemConstraintName(ConstraintCode C)
Definition InlineAsm.h:470
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Describe properties that are true of each instruction in the target description file.
Machine Value Type.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
SimpleValueType SimpleTy
uint64_t getScalarSizeInBits() const
MVT changeVectorElementType(MVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool isScalableVector() const
Return true if this is a vector value type where the runtime length is machine dependent.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool isFixedLengthVector() const
ElementCount getVectorElementCount() const
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MVT getVectorElementType() const
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MONonTemporal
The memory access is non-temporal.
void setFlags(Flags f)
Bitwise OR the current flags with the given flags.
An SDNode that represents everything that will be needed to construct a MachineInstr.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine, CodeGenOptLevel OptLevel)
bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val)
RISC-V doesn't have general instructions for integer setne/seteq, but we can check for equality with ...
bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val)
bool selectNegImm(SDValue N, SDValue &Val)
bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val)
bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val)
Look for various patterns that can be done with a SHL that can be folded into a SHXADD_UW.
bool areOffsetsWithinAlignment(SDValue Addr, Align Alignment)
bool hasAllNBitUsers(SDNode *Node, unsigned Bits, const unsigned Depth=0) const
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset)
Similar to SelectAddrRegImm, except that the least significant 5 bits of Offset should be all zeros.
bool selectZExtImm32(SDValue N, SDValue &Val)
bool SelectAddrRegZextRegScale(SDValue Addr, unsigned MaxShiftAmount, unsigned Bits, SDValue &Base, SDValue &Index, SDValue &Scale)
bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset)
void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered)
void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked)
bool selectVSplatSimm5Plus1NoDec(SDValue N, SDValue &SplatVal)
bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2)
void selectSF_VC_X_SE(SDNode *Node)
bool orDisjoint(const SDNode *Node) const
bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal)
bool hasAllHUsers(SDNode *Node) const
bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
bool selectVSplatSimm5(SDValue N, SDValue &SplatVal)
bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm)
bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset)
bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT, SDValue X, unsigned Msb, unsigned Lsb)
bool hasAllWUsers(SDNode *Node) const
void PreprocessISelDAG() override
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
bool selectInvLogicImm(SDValue N, SDValue &Val)
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset)
void Select(SDNode *Node) override
Main hook for targets to transform nodes into machine nodes.
bool trySignedBitfieldInsertInSign(SDNode *Node)
bool selectVSplat(SDValue N, SDValue &SplatVal)
void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, const SDLoc &DL, unsigned CurOp, bool IsMasked, bool IsStridedOrIndexed, SmallVectorImpl< SDValue > &Operands, bool IsLoad=false, MVT *IndexVT=nullptr)
void PostprocessISelDAG() override
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection.
bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset)
Similar to SelectAddrRegImm, except that the offset is restricted to uimm9.
bool selectScalarFPAsInt(SDValue N, SDValue &Imm)
bool hasAllBUsers(SDNode *Node) const
void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided)
bool tryShrinkShlLogicImm(SDNode *Node)
void selectVSETVLI(SDNode *Node)
bool selectVLOp(SDValue N, SDValue &VL)
bool trySignedBitfieldExtract(SDNode *Node)
bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal)
void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided)
bool selectVSplatImm64Neg(SDValue N, SDValue &SplatVal)
bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal)
bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT, SDValue X, unsigned Msb, unsigned Lsb)
void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered)
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt)
bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val)
Look for various patterns that can be done with a SHL that can be folded into a SHXADD.
bool tryIndexedLoad(SDNode *Node)
bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount, SDValue &Base, SDValue &Index, SDValue &Scale)
bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal)
bool hasShlAdd(int64_t ShAmt) const
static std::pair< unsigned, unsigned > decomposeSubvectorInsertExtractToSubRegs(MVT VecVT, MVT SubVecVT, unsigned InsertExtractIdx, const RISCVRegisterInfo *TRI)
static unsigned getRegClassIDForVecVT(MVT VT)
static RISCVVType::VLMUL getLMUL(MVT VT)
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
SelectionDAGISelLegacy(char &ID, std::unique_ptr< SelectionDAGISel > S)
const TargetLowering * TLI
const TargetInstrInfo * TII
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const
IsProfitableToFold - Returns true if it's profitable to fold the specific operand node N of U during ...
static bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root, CodeGenOptLevel OptLevel, bool IgnoreChains=false)
IsLegalToFold - Returns true if the specific operand node N of U can be folded during instruction sel...
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
ilist< SDNode >::iterator allnodes_iterator
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition Use.cpp:35
Value * getOperand(unsigned i) const
Definition User.h:232
unsigned getNumOperands() const
Definition User.h:254
iterator_range< user_iterator > users()
Definition Value.h:426
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:801
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition ISDOpcodes.h:587
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:259
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:835
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition ISDOpcodes.h:215
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:826
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:663
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:756
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:601
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:832
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:870
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:730
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:200
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:208
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isIntEqualitySetCC(CondCode Code)
Return true if this is a setcc instruction that performs an equality comparison when used with intege...
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
static bool hasVLOp(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
int getIntMatCost(const APInt &Val, unsigned Size, const MCSubtargetInfo &STI, bool CompressionCost, bool FreeZeroes)
InstSeq generateTwoRegInstSeq(int64_t Val, const MCSubtargetInfo &STI, unsigned &ShiftAmt, unsigned &AddOpc)
SmallVector< Inst, 8 > InstSeq
Definition RISCVMatInt.h:43
static unsigned decodeVSEW(unsigned VSEW)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
std::optional< unsigned > getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW)
static constexpr unsigned RVVBitsPerBlock
static constexpr int64_t VLMaxSentinel
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1705
static const MachineMemOperand::Flags MONontemporalBit1
InstructionCost Cost
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
Definition bit.h:279
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:289
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:252
static const MachineMemOperand::Flags MONontemporalBit0
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:293
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:348
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:186
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
Definition MathExtras.h:282
unsigned M1(unsigned Val)
Definition VE.h:377
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:342
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:222
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:288
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Definition MathExtras.h:270
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:198
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
constexpr T maskTrailingZeros(unsigned N)
Create a bitmask with the N right-most bits set to 0, and all other bits set to 1.
Definition MathExtras.h:103
@ Add
Sum of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
FunctionPass * createRISCVISelDag(RISCVTargetMachine &TM, CodeGenOptLevel OptLevel)
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:583
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:86
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:395
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition ValueTypes.h:157
This class contains a discriminated union of information about pointers in memory operands,...
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.