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 // Supported only in Xqcibm for now.
682 if (!Subtarget->hasVendorXqcibm())
683 return false;
684
685 using namespace SDPatternMatch;
686
687 SDValue X;
688 APInt MaskImm;
689 if (!sd_match(Node, m_Or(m_OneUse(m_Value(X)), m_ConstInt(MaskImm))))
690 return false;
691
692 unsigned ShAmt, Width;
693 if (!MaskImm.isShiftedMask(ShAmt, Width) || MaskImm.isSignedIntN(12))
694 return false;
695
696 // If Zbs is enabled and it is a single bit set we can use BSETI which
697 // can be compressed to C_BSETI when Xqcibm in enabled.
698 if (Width == 1 && Subtarget->hasStdExtZbs())
699 return false;
700
701 // If C1 is a shifted mask (but can't be formed as an ORI),
702 // use a bitfield insert of -1.
703 // Transform (or x, C1)
704 // -> (qc.insbi x, -1, width, shift)
705 SDLoc DL(Node);
706 MVT VT = Node->getSimpleValueType(0);
707
708 SDValue Ops[] = {X, CurDAG->getSignedTargetConstant(-1, DL, VT),
709 CurDAG->getTargetConstant(Width, DL, VT),
710 CurDAG->getTargetConstant(ShAmt, DL, VT)};
711 SDNode *BitIns = CurDAG->getMachineNode(RISCV::QC_INSBI, DL, VT, Ops);
712 ReplaceNode(Node, BitIns);
713 return true;
714}
715
716// Generate a QC_INSB/QC_INSBI from 'or (and X, MaskImm), OrImm' iff the value
717// being inserted only sets known zero bits.
719 // Supported only in Xqcibm for now.
720 if (!Subtarget->hasVendorXqcibm())
721 return false;
722
723 using namespace SDPatternMatch;
724
725 SDValue And;
726 APInt MaskImm, OrImm;
727 if (!sd_match(Node, m_Or(m_OneUse(m_And(m_Value(And), m_ConstInt(MaskImm))),
728 m_ConstInt(OrImm))))
729 return false;
730
731 // Compute the Known Zero for the AND as this allows us to catch more general
732 // cases than just looking for AND with imm.
733 KnownBits Known = CurDAG->computeKnownBits(Node->getOperand(0));
734
735 // The bits being inserted must only set those bits that are known to be zero.
736 if (!OrImm.isSubsetOf(Known.Zero)) {
737 // FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't
738 // currently handle this case.
739 return false;
740 }
741
742 unsigned ShAmt, Width;
743 // The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
744 if (!Known.Zero.isShiftedMask(ShAmt, Width))
745 return false;
746
747 // QC_INSB(I) dst, src, #width, #shamt.
748 SDLoc DL(Node);
749 MVT VT = Node->getSimpleValueType(0);
750 SDValue ImmNode;
751 auto Opc = RISCV::QC_INSB;
752
753 int32_t LIImm = OrImm.getSExtValue() >> ShAmt;
754
755 if (isInt<5>(LIImm)) {
756 Opc = RISCV::QC_INSBI;
757 ImmNode = CurDAG->getSignedTargetConstant(LIImm, DL, MVT::i32);
758 } else {
759 ImmNode = selectImm(CurDAG, DL, MVT::i32, LIImm, *Subtarget);
760 }
761
762 SDValue Ops[] = {And, ImmNode, CurDAG->getTargetConstant(Width, DL, VT),
763 CurDAG->getTargetConstant(ShAmt, DL, VT)};
764 SDNode *BitIns = CurDAG->getMachineNode(Opc, DL, VT, Ops);
765 ReplaceNode(Node, BitIns);
766 return true;
767}
768
770 // Only supported with XAndesPerf at the moment.
771 if (!Subtarget->hasVendorXAndesPerf())
772 return false;
773
774 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
775 if (!N1C)
776 return false;
777
778 SDValue N0 = Node->getOperand(0);
779 if (!N0.hasOneUse())
780 return false;
781
782 auto BitfieldInsert = [&](SDValue N0, unsigned Msb, unsigned Lsb,
783 const SDLoc &DL, MVT VT) {
784 unsigned Opc = RISCV::NDS_BFOS;
785 // If the Lsb is equal to the Msb, then the Lsb should be 0.
786 if (Lsb == Msb)
787 Lsb = 0;
788 return CurDAG->getMachineNode(Opc, DL, VT, N0.getOperand(0),
789 CurDAG->getTargetConstant(Lsb, DL, VT),
790 CurDAG->getTargetConstant(Msb, DL, VT));
791 };
792
793 SDLoc DL(Node);
794 MVT VT = Node->getSimpleValueType(0);
795 const unsigned RightShAmt = N1C->getZExtValue();
796
797 // Transform (sra (shl X, C1) C2) with C1 > C2
798 // -> (NDS.BFOS X, lsb, msb)
799 if (N0.getOpcode() == ISD::SHL) {
800 auto *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
801 if (!N01C)
802 return false;
803
804 const unsigned LeftShAmt = N01C->getZExtValue();
805 // Make sure that this is a bitfield insertion (i.e., the shift-right
806 // amount should be less than the left-shift).
807 if (LeftShAmt <= RightShAmt)
808 return false;
809
810 const unsigned MsbPlusOne = VT.getSizeInBits() - RightShAmt;
811 const unsigned Msb = MsbPlusOne - 1;
812 const unsigned Lsb = LeftShAmt - RightShAmt;
813
814 SDNode *Sbi = BitfieldInsert(N0, Msb, Lsb, DL, VT);
815 ReplaceNode(Node, Sbi);
816 return true;
817 }
818
819 return false;
820}
821
823 const SDLoc &DL, MVT VT,
824 SDValue X, unsigned Msb,
825 unsigned Lsb) {
826 unsigned Opc;
827
828 if (Subtarget->hasVendorXTHeadBb()) {
829 Opc = RISCV::TH_EXTU;
830 } else if (Subtarget->hasVendorXAndesPerf()) {
831 Opc = RISCV::NDS_BFOZ;
832 } else if (Subtarget->hasVendorXqcibm()) {
833 Opc = RISCV::QC_EXTU;
834 // QC.EXTU X, width, shamt
835 // shamt is the same as Lsb
836 // width is the number of bits to extract from the Lsb
837 Msb = Msb - Lsb + 1;
838 } else {
839 // Only supported with XTHeadBb/XAndesPerf/Xqcibm at the moment.
840 return false;
841 }
842
843 SDNode *Ube = CurDAG->getMachineNode(Opc, DL, VT, X,
844 CurDAG->getTargetConstant(Msb, DL, VT),
845 CurDAG->getTargetConstant(Lsb, DL, VT));
846 ReplaceNode(Node, Ube);
847 return true;
848}
849
851 const SDLoc &DL, MVT VT,
852 SDValue X, unsigned Msb,
853 unsigned Lsb) {
854 // Only supported with XAndesPerf at the moment.
855 if (!Subtarget->hasVendorXAndesPerf())
856 return false;
857
858 unsigned Opc = RISCV::NDS_BFOZ;
859
860 // If the Lsb is equal to the Msb, then the Lsb should be 0.
861 if (Lsb == Msb)
862 Lsb = 0;
863 SDNode *Ubi = CurDAG->getMachineNode(Opc, DL, VT, X,
864 CurDAG->getTargetConstant(Lsb, DL, VT),
865 CurDAG->getTargetConstant(Msb, DL, VT));
866 ReplaceNode(Node, Ubi);
867 return true;
868}
869
871 // Target does not support indexed loads.
872 if (!Subtarget->hasVendorXTHeadMemIdx())
873 return false;
874
877 if (AM == ISD::UNINDEXED)
878 return false;
879
881 if (!C)
882 return false;
883
884 EVT LoadVT = Ld->getMemoryVT();
885 assert((AM == ISD::PRE_INC || AM == ISD::POST_INC) &&
886 "Unexpected addressing mode");
887 bool IsPre = AM == ISD::PRE_INC;
888 bool IsPost = AM == ISD::POST_INC;
889 int64_t Offset = C->getSExtValue();
890
891 // The constants that can be encoded in the THeadMemIdx instructions
892 // are of the form (sign_extend(imm5) << imm2).
893 unsigned Shift;
894 for (Shift = 0; Shift < 4; Shift++)
895 if (isInt<5>(Offset >> Shift) && ((Offset % (1LL << Shift)) == 0))
896 break;
897
898 // Constant cannot be encoded.
899 if (Shift == 4)
900 return false;
901
902 bool IsZExt = (Ld->getExtensionType() == ISD::ZEXTLOAD);
903 unsigned Opcode;
904 if (LoadVT == MVT::i8 && IsPre)
905 Opcode = IsZExt ? RISCV::TH_LBUIB : RISCV::TH_LBIB;
906 else if (LoadVT == MVT::i8 && IsPost)
907 Opcode = IsZExt ? RISCV::TH_LBUIA : RISCV::TH_LBIA;
908 else if (LoadVT == MVT::i16 && IsPre)
909 Opcode = IsZExt ? RISCV::TH_LHUIB : RISCV::TH_LHIB;
910 else if (LoadVT == MVT::i16 && IsPost)
911 Opcode = IsZExt ? RISCV::TH_LHUIA : RISCV::TH_LHIA;
912 else if (LoadVT == MVT::i32 && IsPre)
913 Opcode = IsZExt ? RISCV::TH_LWUIB : RISCV::TH_LWIB;
914 else if (LoadVT == MVT::i32 && IsPost)
915 Opcode = IsZExt ? RISCV::TH_LWUIA : RISCV::TH_LWIA;
916 else if (LoadVT == MVT::i64 && IsPre)
917 Opcode = RISCV::TH_LDIB;
918 else if (LoadVT == MVT::i64 && IsPost)
919 Opcode = RISCV::TH_LDIA;
920 else
921 return false;
922
923 EVT Ty = Ld->getOffset().getValueType();
924 SDValue Ops[] = {
925 Ld->getBasePtr(),
926 CurDAG->getSignedTargetConstant(Offset >> Shift, SDLoc(Node), Ty),
927 CurDAG->getTargetConstant(Shift, SDLoc(Node), Ty), Ld->getChain()};
928 SDNode *New = CurDAG->getMachineNode(Opcode, SDLoc(Node), Ld->getValueType(0),
929 Ld->getValueType(1), MVT::Other, Ops);
930
931 MachineMemOperand *MemOp = cast<MemSDNode>(Node)->getMemOperand();
932 CurDAG->setNodeMemRefs(cast<MachineSDNode>(New), {MemOp});
933
934 ReplaceNode(Node, New);
935
936 return true;
937}
938
940 if (!Subtarget->hasVInstructions())
941 return;
942
943 assert(Node->getOpcode() == ISD::INTRINSIC_VOID && "Unexpected opcode");
944
945 SDLoc DL(Node);
946 unsigned IntNo = Node->getConstantOperandVal(1);
947
948 assert((IntNo == Intrinsic::riscv_sf_vc_x_se ||
949 IntNo == Intrinsic::riscv_sf_vc_i_se) &&
950 "Unexpected vsetvli intrinsic");
951
952 // imm, imm, imm, simm5/scalar, sew, log2lmul, vl
953 unsigned Log2SEW = Log2_32(Node->getConstantOperandVal(6));
954 SDValue SEWOp =
955 CurDAG->getTargetConstant(Log2SEW, DL, Subtarget->getXLenVT());
956 SmallVector<SDValue, 8> Operands = {Node->getOperand(2), Node->getOperand(3),
957 Node->getOperand(4), Node->getOperand(5),
958 Node->getOperand(8), SEWOp,
959 Node->getOperand(0)};
960
961 unsigned Opcode;
962 auto *LMulSDNode = cast<ConstantSDNode>(Node->getOperand(7));
963 switch (LMulSDNode->getSExtValue()) {
964 case 5:
965 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_MF8
966 : RISCV::PseudoSF_VC_I_SE_MF8;
967 break;
968 case 6:
969 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_MF4
970 : RISCV::PseudoSF_VC_I_SE_MF4;
971 break;
972 case 7:
973 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_MF2
974 : RISCV::PseudoSF_VC_I_SE_MF2;
975 break;
976 case 0:
977 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M1
978 : RISCV::PseudoSF_VC_I_SE_M1;
979 break;
980 case 1:
981 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M2
982 : RISCV::PseudoSF_VC_I_SE_M2;
983 break;
984 case 2:
985 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M4
986 : RISCV::PseudoSF_VC_I_SE_M4;
987 break;
988 case 3:
989 Opcode = IntNo == Intrinsic::riscv_sf_vc_x_se ? RISCV::PseudoSF_VC_X_SE_M8
990 : RISCV::PseudoSF_VC_I_SE_M8;
991 break;
992 }
993
994 ReplaceNode(Node, CurDAG->getMachineNode(
995 Opcode, DL, Node->getSimpleValueType(0), Operands));
996}
997
998static unsigned getSegInstNF(unsigned Intrinsic) {
999#define INST_NF_CASE(NAME, NF) \
1000 case Intrinsic::riscv_##NAME##NF: \
1001 return NF;
1002#define INST_NF_CASE_MASK(NAME, NF) \
1003 case Intrinsic::riscv_##NAME##NF##_mask: \
1004 return NF;
1005#define INST_NF_CASE_FF(NAME, NF) \
1006 case Intrinsic::riscv_##NAME##NF##ff: \
1007 return NF;
1008#define INST_NF_CASE_FF_MASK(NAME, NF) \
1009 case Intrinsic::riscv_##NAME##NF##ff_mask: \
1010 return NF;
1011#define INST_ALL_NF_CASE_BASE(MACRO_NAME, NAME) \
1012 MACRO_NAME(NAME, 2) \
1013 MACRO_NAME(NAME, 3) \
1014 MACRO_NAME(NAME, 4) \
1015 MACRO_NAME(NAME, 5) \
1016 MACRO_NAME(NAME, 6) \
1017 MACRO_NAME(NAME, 7) \
1018 MACRO_NAME(NAME, 8)
1019#define INST_ALL_NF_CASE(NAME) \
1020 INST_ALL_NF_CASE_BASE(INST_NF_CASE, NAME) \
1021 INST_ALL_NF_CASE_BASE(INST_NF_CASE_MASK, NAME)
1022#define INST_ALL_NF_CASE_WITH_FF(NAME) \
1023 INST_ALL_NF_CASE(NAME) \
1024 INST_ALL_NF_CASE_BASE(INST_NF_CASE_FF, NAME) \
1025 INST_ALL_NF_CASE_BASE(INST_NF_CASE_FF_MASK, NAME)
1026 switch (Intrinsic) {
1027 default:
1028 llvm_unreachable("Unexpected segment load/store intrinsic");
1030 INST_ALL_NF_CASE(vlsseg)
1031 INST_ALL_NF_CASE(vloxseg)
1032 INST_ALL_NF_CASE(vluxseg)
1033 INST_ALL_NF_CASE(vsseg)
1034 INST_ALL_NF_CASE(vssseg)
1035 INST_ALL_NF_CASE(vsoxseg)
1036 INST_ALL_NF_CASE(vsuxseg)
1037 }
1038}
1039
1041 // If we have a custom node, we have already selected.
1042 if (Node->isMachineOpcode()) {
1043 LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
1044 Node->setNodeId(-1);
1045 return;
1046 }
1047
1048 // Instruction Selection not handled by the auto-generated tablegen selection
1049 // should be handled here.
1050 unsigned Opcode = Node->getOpcode();
1051 MVT XLenVT = Subtarget->getXLenVT();
1052 SDLoc DL(Node);
1053 MVT VT = Node->getSimpleValueType(0);
1054
1055 bool HasBitTest = Subtarget->hasBEXTILike();
1056
1057 switch (Opcode) {
1058 case ISD::Constant: {
1059 assert((VT == Subtarget->getXLenVT() || VT == MVT::i32) && "Unexpected VT");
1060 auto *ConstNode = cast<ConstantSDNode>(Node);
1061 if (ConstNode->isZero()) {
1062 SDValue New =
1063 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, RISCV::X0, VT);
1064 ReplaceNode(Node, New.getNode());
1065 return;
1066 }
1067 int64_t Imm = ConstNode->getSExtValue();
1068 // If only the lower 8 bits are used, try to convert this to a simm6 by
1069 // sign-extending bit 7. This is neutral without the C extension, and
1070 // allows C.LI to be used if C is present.
1071 if (isUInt<8>(Imm) && isInt<6>(SignExtend64<8>(Imm)) && hasAllBUsers(Node))
1072 Imm = SignExtend64<8>(Imm);
1073 // If the upper XLen-16 bits are not used, try to convert this to a simm12
1074 // by sign extending bit 15.
1075 if (isUInt<16>(Imm) && isInt<12>(SignExtend64<16>(Imm)) &&
1077 Imm = SignExtend64<16>(Imm);
1078 // If the upper 32-bits are not used try to convert this into a simm32 by
1079 // sign extending bit 32.
1080 if (!isInt<32>(Imm) && isUInt<32>(Imm) && hasAllWUsers(Node))
1081 Imm = SignExtend64<32>(Imm);
1082
1083 ReplaceNode(Node, selectImm(CurDAG, DL, VT, Imm, *Subtarget).getNode());
1084 return;
1085 }
1086 case ISD::ConstantFP: {
1087 const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
1088
1089 bool Is64Bit = Subtarget->is64Bit();
1090 bool HasZdinx = Subtarget->hasStdExtZdinx();
1091
1092 bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
1093 SDValue Imm;
1094 // For +0.0 or f64 -0.0 we need to start from X0. For all others, we will
1095 // create an integer immediate.
1096 if (APF.isPosZero() || NegZeroF64) {
1097 if (VT == MVT::f64 && HasZdinx && !Is64Bit)
1098 Imm = CurDAG->getRegister(RISCV::X0_Pair, MVT::f64);
1099 else
1100 Imm = CurDAG->getRegister(RISCV::X0, XLenVT);
1101 } else {
1102 Imm = selectImm(CurDAG, DL, XLenVT, APF.bitcastToAPInt().getSExtValue(),
1103 *Subtarget);
1104 }
1105
1106 unsigned Opc;
1107 switch (VT.SimpleTy) {
1108 default:
1109 llvm_unreachable("Unexpected size");
1110 case MVT::bf16:
1111 assert(Subtarget->hasStdExtZfbfmin());
1112 Opc = RISCV::FMV_H_X;
1113 break;
1114 case MVT::f16:
1115 Opc = Subtarget->hasStdExtZhinxmin() ? RISCV::COPY : RISCV::FMV_H_X;
1116 break;
1117 case MVT::f32:
1118 Opc = Subtarget->hasStdExtZfinx() ? RISCV::COPY : RISCV::FMV_W_X;
1119 break;
1120 case MVT::f64:
1121 // For RV32, we can't move from a GPR, we need to convert instead. This
1122 // should only happen for +0.0 and -0.0.
1123 assert((Subtarget->is64Bit() || APF.isZero()) && "Unexpected constant");
1124 if (HasZdinx)
1125 Opc = RISCV::COPY;
1126 else
1127 Opc = Is64Bit ? RISCV::FMV_D_X : RISCV::FCVT_D_W;
1128 break;
1129 }
1130
1131 SDNode *Res;
1132 if (VT.SimpleTy == MVT::f16 && Opc == RISCV::COPY) {
1133 Res =
1134 CurDAG->getTargetExtractSubreg(RISCV::sub_16, DL, VT, Imm).getNode();
1135 } else if (VT.SimpleTy == MVT::f32 && Opc == RISCV::COPY) {
1136 Res =
1137 CurDAG->getTargetExtractSubreg(RISCV::sub_32, DL, VT, Imm).getNode();
1138 } else if (Opc == RISCV::FCVT_D_W_IN32X || Opc == RISCV::FCVT_D_W)
1139 Res = CurDAG->getMachineNode(
1140 Opc, DL, VT, Imm,
1141 CurDAG->getTargetConstant(RISCVFPRndMode::RNE, DL, XLenVT));
1142 else
1143 Res = CurDAG->getMachineNode(Opc, DL, VT, Imm);
1144
1145 // For f64 -0.0, we need to insert a fneg.d idiom.
1146 if (NegZeroF64) {
1147 Opc = RISCV::FSGNJN_D;
1148 if (HasZdinx)
1149 Opc = Is64Bit ? RISCV::FSGNJN_D_INX : RISCV::FSGNJN_D_IN32X;
1150 Res =
1151 CurDAG->getMachineNode(Opc, DL, VT, SDValue(Res, 0), SDValue(Res, 0));
1152 }
1153
1154 ReplaceNode(Node, Res);
1155 return;
1156 }
1157 case RISCVISD::BuildGPRPair:
1158 case RISCVISD::BuildPairF64: {
1159 if (Opcode == RISCVISD::BuildPairF64 && !Subtarget->hasStdExtZdinx())
1160 break;
1161
1162 assert((!Subtarget->is64Bit() || Opcode == RISCVISD::BuildGPRPair) &&
1163 "BuildPairF64 only handled here on rv32i_zdinx");
1164
1165 SDValue Ops[] = {
1166 CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32),
1167 Node->getOperand(0),
1168 CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32),
1169 Node->getOperand(1),
1170 CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
1171
1172 SDNode *N = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, VT, Ops);
1173 ReplaceNode(Node, N);
1174 return;
1175 }
1176 case RISCVISD::SplitGPRPair:
1177 case RISCVISD::SplitF64: {
1178 if (Subtarget->hasStdExtZdinx() || Opcode != RISCVISD::SplitF64) {
1179 assert((!Subtarget->is64Bit() || Opcode == RISCVISD::SplitGPRPair) &&
1180 "SplitF64 only handled here on rv32i_zdinx");
1181
1182 if (!SDValue(Node, 0).use_empty()) {
1183 SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL,
1184 Node->getValueType(0),
1185 Node->getOperand(0));
1186 ReplaceUses(SDValue(Node, 0), Lo);
1187 }
1188
1189 if (!SDValue(Node, 1).use_empty()) {
1190 SDValue Hi = CurDAG->getTargetExtractSubreg(
1191 RISCV::sub_gpr_odd, DL, Node->getValueType(1), Node->getOperand(0));
1192 ReplaceUses(SDValue(Node, 1), Hi);
1193 }
1194
1195 CurDAG->RemoveDeadNode(Node);
1196 return;
1197 }
1198
1199 assert(Opcode != RISCVISD::SplitGPRPair &&
1200 "SplitGPRPair should already be handled");
1201
1202 if (!Subtarget->hasStdExtZfa())
1203 break;
1204 assert(Subtarget->hasStdExtD() && !Subtarget->is64Bit() &&
1205 "Unexpected subtarget");
1206
1207 // With Zfa, lower to fmv.x.w and fmvh.x.d.
1208 if (!SDValue(Node, 0).use_empty()) {
1209 SDNode *Lo = CurDAG->getMachineNode(RISCV::FMV_X_W_FPR64, DL, VT,
1210 Node->getOperand(0));
1211 ReplaceUses(SDValue(Node, 0), SDValue(Lo, 0));
1212 }
1213 if (!SDValue(Node, 1).use_empty()) {
1214 SDNode *Hi = CurDAG->getMachineNode(RISCV::FMVH_X_D, DL, VT,
1215 Node->getOperand(0));
1216 ReplaceUses(SDValue(Node, 1), SDValue(Hi, 0));
1217 }
1218
1219 CurDAG->RemoveDeadNode(Node);
1220 return;
1221 }
1222 case ISD::SHL: {
1223 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1224 if (!N1C)
1225 break;
1226 SDValue N0 = Node->getOperand(0);
1227 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse() ||
1229 break;
1230 unsigned ShAmt = N1C->getZExtValue();
1231 uint64_t Mask = N0.getConstantOperandVal(1);
1232
1233 if (isShiftedMask_64(Mask)) {
1234 unsigned XLen = Subtarget->getXLen();
1235 unsigned LeadingZeros = XLen - llvm::bit_width(Mask);
1236 unsigned TrailingZeros = llvm::countr_zero(Mask);
1237 if (ShAmt <= 32 && TrailingZeros > 0 && LeadingZeros == 32) {
1238 // Optimize (shl (and X, C2), C) -> (slli (srliw X, C3), C3+C)
1239 // where C2 has 32 leading zeros and C3 trailing zeros.
1240 SDNode *SRLIW = CurDAG->getMachineNode(
1241 RISCV::SRLIW, DL, VT, N0.getOperand(0),
1242 CurDAG->getTargetConstant(TrailingZeros, DL, VT));
1243 SDNode *SLLI = CurDAG->getMachineNode(
1244 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1245 CurDAG->getTargetConstant(TrailingZeros + ShAmt, DL, VT));
1246 ReplaceNode(Node, SLLI);
1247 return;
1248 }
1249 if (TrailingZeros == 0 && LeadingZeros > ShAmt &&
1250 XLen - LeadingZeros > 11 && LeadingZeros != 32) {
1251 // Optimize (shl (and X, C2), C) -> (srli (slli X, C4), C4-C)
1252 // where C2 has C4 leading zeros and no trailing zeros.
1253 // This is profitable if the "and" was to be lowered to
1254 // (srli (slli X, C4), C4) and not (andi X, C2).
1255 // For "LeadingZeros == 32":
1256 // - with Zba it's just (slli.uw X, C)
1257 // - without Zba a tablegen pattern applies the very same
1258 // transform as we would have done here
1259 SDNode *SLLI = CurDAG->getMachineNode(
1260 RISCV::SLLI, DL, VT, N0.getOperand(0),
1261 CurDAG->getTargetConstant(LeadingZeros, DL, VT));
1262 SDNode *SRLI = CurDAG->getMachineNode(
1263 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1264 CurDAG->getTargetConstant(LeadingZeros - ShAmt, DL, VT));
1265 ReplaceNode(Node, SRLI);
1266 return;
1267 }
1268 }
1269 break;
1270 }
1271 case ISD::SRL: {
1272 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1273 if (!N1C)
1274 break;
1275 SDValue N0 = Node->getOperand(0);
1276 if (N0.getOpcode() != ISD::AND || !isa<ConstantSDNode>(N0.getOperand(1)))
1277 break;
1278 unsigned ShAmt = N1C->getZExtValue();
1279 uint64_t Mask = N0.getConstantOperandVal(1);
1280
1281 // Optimize (srl (and X, C2), C) -> (slli (srliw X, C3), C3-C) where C2 has
1282 // 32 leading zeros and C3 trailing zeros.
1283 if (isShiftedMask_64(Mask) && N0.hasOneUse()) {
1284 unsigned XLen = Subtarget->getXLen();
1285 unsigned LeadingZeros = XLen - llvm::bit_width(Mask);
1286 unsigned TrailingZeros = llvm::countr_zero(Mask);
1287 if (LeadingZeros == 32 && TrailingZeros > ShAmt) {
1288 SDNode *SRLIW = CurDAG->getMachineNode(
1289 RISCV::SRLIW, DL, VT, N0.getOperand(0),
1290 CurDAG->getTargetConstant(TrailingZeros, DL, VT));
1291 SDNode *SLLI = CurDAG->getMachineNode(
1292 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1293 CurDAG->getTargetConstant(TrailingZeros - ShAmt, DL, VT));
1294 ReplaceNode(Node, SLLI);
1295 return;
1296 }
1297 }
1298
1299 // Optimize (srl (and X, C2), C) ->
1300 // (srli (slli X, (XLen-C3), (XLen-C3) + C)
1301 // Where C2 is a mask with C3 trailing ones.
1302 // Taking into account that the C2 may have had lower bits unset by
1303 // SimplifyDemandedBits. This avoids materializing the C2 immediate.
1304 // This pattern occurs when type legalizing right shifts for types with
1305 // less than XLen bits.
1306 Mask |= maskTrailingOnes<uint64_t>(ShAmt);
1307 if (!isMask_64(Mask))
1308 break;
1309 unsigned TrailingOnes = llvm::countr_one(Mask);
1310 if (ShAmt >= TrailingOnes)
1311 break;
1312 // If the mask has 32 trailing ones, use SRLI on RV32 or SRLIW on RV64.
1313 if (TrailingOnes == 32) {
1314 SDNode *SRLI = CurDAG->getMachineNode(
1315 Subtarget->is64Bit() ? RISCV::SRLIW : RISCV::SRLI, DL, VT,
1316 N0.getOperand(0), CurDAG->getTargetConstant(ShAmt, DL, VT));
1317 ReplaceNode(Node, SRLI);
1318 return;
1319 }
1320
1321 // Only do the remaining transforms if the AND has one use.
1322 if (!N0.hasOneUse())
1323 break;
1324
1325 // If C2 is (1 << ShAmt) use bexti or th.tst if possible.
1326 if (HasBitTest && ShAmt + 1 == TrailingOnes) {
1327 SDNode *BEXTI = CurDAG->getMachineNode(
1328 Subtarget->hasStdExtZbs() ? RISCV::BEXTI : RISCV::TH_TST, DL, VT,
1329 N0.getOperand(0), CurDAG->getTargetConstant(ShAmt, DL, VT));
1330 ReplaceNode(Node, BEXTI);
1331 return;
1332 }
1333
1334 const unsigned Msb = TrailingOnes - 1;
1335 const unsigned Lsb = ShAmt;
1336 if (tryUnsignedBitfieldExtract(Node, DL, VT, N0.getOperand(0), Msb, Lsb))
1337 return;
1338
1339 unsigned LShAmt = Subtarget->getXLen() - TrailingOnes;
1340 SDNode *SLLI =
1341 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0.getOperand(0),
1342 CurDAG->getTargetConstant(LShAmt, DL, VT));
1343 SDNode *SRLI = CurDAG->getMachineNode(
1344 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1345 CurDAG->getTargetConstant(LShAmt + ShAmt, DL, VT));
1346 ReplaceNode(Node, SRLI);
1347 return;
1348 }
1349 case ISD::SRA: {
1351 return;
1352
1354 return;
1355
1356 // Optimize (sra (sext_inreg X, i16), C) ->
1357 // (srai (slli X, (XLen-16), (XLen-16) + C)
1358 // And (sra (sext_inreg X, i8), C) ->
1359 // (srai (slli X, (XLen-8), (XLen-8) + C)
1360 // This can occur when Zbb is enabled, which makes sext_inreg i16/i8 legal.
1361 // This transform matches the code we get without Zbb. The shifts are more
1362 // compressible, and this can help expose CSE opportunities in the sdiv by
1363 // constant optimization.
1364 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1365 if (!N1C)
1366 break;
1367 SDValue N0 = Node->getOperand(0);
1368 if (N0.getOpcode() != ISD::SIGN_EXTEND_INREG || !N0.hasOneUse())
1369 break;
1370 unsigned ShAmt = N1C->getZExtValue();
1371 unsigned ExtSize =
1372 cast<VTSDNode>(N0.getOperand(1))->getVT().getSizeInBits();
1373 // ExtSize of 32 should use sraiw via tablegen pattern.
1374 if (ExtSize >= 32 || ShAmt >= ExtSize)
1375 break;
1376 unsigned LShAmt = Subtarget->getXLen() - ExtSize;
1377 SDNode *SLLI =
1378 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0.getOperand(0),
1379 CurDAG->getTargetConstant(LShAmt, DL, VT));
1380 SDNode *SRAI = CurDAG->getMachineNode(
1381 RISCV::SRAI, DL, VT, SDValue(SLLI, 0),
1382 CurDAG->getTargetConstant(LShAmt + ShAmt, DL, VT));
1383 ReplaceNode(Node, SRAI);
1384 return;
1385 }
1386 case ISD::OR: {
1388 return;
1389
1391 return;
1392
1394 return;
1395
1396 break;
1397 }
1398 case ISD::XOR:
1400 return;
1401
1402 break;
1403 case ISD::AND: {
1404 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1405 if (!N1C)
1406 break;
1407
1408 SDValue N0 = Node->getOperand(0);
1409
1410 bool LeftShift = N0.getOpcode() == ISD::SHL;
1411 if (LeftShift || N0.getOpcode() == ISD::SRL) {
1412 auto *C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
1413 if (!C)
1414 break;
1415 unsigned C2 = C->getZExtValue();
1416 unsigned XLen = Subtarget->getXLen();
1417 assert((C2 > 0 && C2 < XLen) && "Unexpected shift amount!");
1418
1419 // Keep track of whether this is a c.andi. If we can't use c.andi, the
1420 // shift pair might offer more compression opportunities.
1421 // TODO: We could check for C extension here, but we don't have many lit
1422 // tests with the C extension enabled so not checking gets better
1423 // coverage.
1424 // TODO: What if ANDI faster than shift?
1425 bool IsCANDI = isInt<6>(N1C->getSExtValue());
1426
1427 uint64_t C1 = N1C->getZExtValue();
1428
1429 // Clear irrelevant bits in the mask.
1430 if (LeftShift)
1432 else
1433 C1 &= maskTrailingOnes<uint64_t>(XLen - C2);
1434
1435 // Some transforms should only be done if the shift has a single use or
1436 // the AND would become (srli (slli X, 32), 32)
1437 bool OneUseOrZExtW = N0.hasOneUse() || C1 == UINT64_C(0xFFFFFFFF);
1438
1439 SDValue X = N0.getOperand(0);
1440
1441 // Turn (and (srl x, c2) c1) -> (srli (slli x, c3-c2), c3) if c1 is a mask
1442 // with c3 leading zeros.
1443 if (!LeftShift && isMask_64(C1)) {
1444 unsigned Leading = XLen - llvm::bit_width(C1);
1445 if (C2 < Leading) {
1446 // If the number of leading zeros is C2+32 this can be SRLIW.
1447 if (C2 + 32 == Leading) {
1448 SDNode *SRLIW = CurDAG->getMachineNode(
1449 RISCV::SRLIW, DL, VT, X, CurDAG->getTargetConstant(C2, DL, VT));
1450 ReplaceNode(Node, SRLIW);
1451 return;
1452 }
1453
1454 // (and (srl (sexti32 Y), c2), c1) -> (srliw (sraiw Y, 31), c3 - 32)
1455 // if c1 is a mask with c3 leading zeros and c2 >= 32 and c3-c2==1.
1456 //
1457 // This pattern occurs when (i32 (srl (sra 31), c3 - 32)) is type
1458 // legalized and goes through DAG combine.
1459 if (C2 >= 32 && (Leading - C2) == 1 && N0.hasOneUse() &&
1460 X.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1461 cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i32) {
1462 SDNode *SRAIW =
1463 CurDAG->getMachineNode(RISCV::SRAIW, DL, VT, X.getOperand(0),
1464 CurDAG->getTargetConstant(31, DL, VT));
1465 SDNode *SRLIW = CurDAG->getMachineNode(
1466 RISCV::SRLIW, DL, VT, SDValue(SRAIW, 0),
1467 CurDAG->getTargetConstant(Leading - 32, DL, VT));
1468 ReplaceNode(Node, SRLIW);
1469 return;
1470 }
1471
1472 // Try to use an unsigned bitfield extract (e.g., th.extu) if
1473 // available.
1474 // Transform (and (srl x, C2), C1)
1475 // -> (<bfextract> x, msb, lsb)
1476 //
1477 // Make sure to keep this below the SRLIW cases, as we always want to
1478 // prefer the more common instruction.
1479 const unsigned Msb = llvm::bit_width(C1) + C2 - 1;
1480 const unsigned Lsb = C2;
1481 if (tryUnsignedBitfieldExtract(Node, DL, VT, X, Msb, Lsb))
1482 return;
1483
1484 // (srli (slli x, c3-c2), c3).
1485 // Skip if we could use (zext.w (sraiw X, C2)).
1486 bool Skip = Subtarget->hasStdExtZba() && Leading == 32 &&
1487 X.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1488 cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i32;
1489 // Also Skip if we can use bexti or th.tst.
1490 Skip |= HasBitTest && Leading == XLen - 1;
1491 if (OneUseOrZExtW && !Skip) {
1492 SDNode *SLLI = CurDAG->getMachineNode(
1493 RISCV::SLLI, DL, VT, X,
1494 CurDAG->getTargetConstant(Leading - C2, DL, VT));
1495 SDNode *SRLI = CurDAG->getMachineNode(
1496 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1497 CurDAG->getTargetConstant(Leading, DL, VT));
1498 ReplaceNode(Node, SRLI);
1499 return;
1500 }
1501 }
1502 }
1503
1504 // Turn (and (shl x, c2), c1) -> (srli (slli c2+c3), c3) if c1 is a mask
1505 // shifted by c2 bits with c3 leading zeros.
1506 if (LeftShift && isShiftedMask_64(C1)) {
1507 unsigned Leading = XLen - llvm::bit_width(C1);
1508
1509 if (C2 + Leading < XLen &&
1510 C1 == (maskTrailingOnes<uint64_t>(XLen - (C2 + Leading)) << C2)) {
1511 // Use slli.uw when possible.
1512 if ((XLen - (C2 + Leading)) == 32 && Subtarget->hasStdExtZba()) {
1513 SDNode *SLLI_UW =
1514 CurDAG->getMachineNode(RISCV::SLLI_UW, DL, VT, X,
1515 CurDAG->getTargetConstant(C2, DL, VT));
1516 ReplaceNode(Node, SLLI_UW);
1517 return;
1518 }
1519
1520 // Try to use an unsigned bitfield insert (e.g., nds.bfoz) if
1521 // available.
1522 // Transform (and (shl x, c2), c1)
1523 // -> (<bfinsert> x, msb, lsb)
1524 // e.g.
1525 // (and (shl x, 12), 0x00fff000)
1526 // If XLen = 32 and C2 = 12, then
1527 // Msb = 32 - 8 - 1 = 23 and Lsb = 12
1528 const unsigned Msb = XLen - Leading - 1;
1529 const unsigned Lsb = C2;
1530 if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb))
1531 return;
1532
1533 // (srli (slli c2+c3), c3)
1534 if (OneUseOrZExtW && !IsCANDI) {
1535 SDNode *SLLI = CurDAG->getMachineNode(
1536 RISCV::SLLI, DL, VT, X,
1537 CurDAG->getTargetConstant(C2 + Leading, DL, VT));
1538 SDNode *SRLI = CurDAG->getMachineNode(
1539 RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
1540 CurDAG->getTargetConstant(Leading, DL, VT));
1541 ReplaceNode(Node, SRLI);
1542 return;
1543 }
1544 }
1545 }
1546
1547 // Turn (and (shr x, c2), c1) -> (slli (srli x, c2+c3), c3) if c1 is a
1548 // shifted mask with c2 leading zeros and c3 trailing zeros.
1549 if (!LeftShift && isShiftedMask_64(C1)) {
1550 unsigned Leading = XLen - llvm::bit_width(C1);
1551 unsigned Trailing = llvm::countr_zero(C1);
1552 if (Leading == C2 && C2 + Trailing < XLen && OneUseOrZExtW &&
1553 !IsCANDI) {
1554 unsigned SrliOpc = RISCV::SRLI;
1555 // If the input is zexti32 we should use SRLIW.
1556 if (X.getOpcode() == ISD::AND &&
1557 isa<ConstantSDNode>(X.getOperand(1)) &&
1558 X.getConstantOperandVal(1) == UINT64_C(0xFFFFFFFF)) {
1559 SrliOpc = RISCV::SRLIW;
1560 X = X.getOperand(0);
1561 }
1562 SDNode *SRLI = CurDAG->getMachineNode(
1563 SrliOpc, DL, VT, X,
1564 CurDAG->getTargetConstant(C2 + Trailing, DL, VT));
1565 SDNode *SLLI = CurDAG->getMachineNode(
1566 RISCV::SLLI, DL, VT, SDValue(SRLI, 0),
1567 CurDAG->getTargetConstant(Trailing, DL, VT));
1568 ReplaceNode(Node, SLLI);
1569 return;
1570 }
1571 // If the leading zero count is C2+32, we can use SRLIW instead of SRLI.
1572 if (Leading > 32 && (Leading - 32) == C2 && C2 + Trailing < 32 &&
1573 OneUseOrZExtW && !IsCANDI) {
1574 SDNode *SRLIW = CurDAG->getMachineNode(
1575 RISCV::SRLIW, DL, VT, X,
1576 CurDAG->getTargetConstant(C2 + Trailing, DL, VT));
1577 SDNode *SLLI = CurDAG->getMachineNode(
1578 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1579 CurDAG->getTargetConstant(Trailing, DL, VT));
1580 ReplaceNode(Node, SLLI);
1581 return;
1582 }
1583 // If we have 32 bits in the mask, we can use SLLI_UW instead of SLLI.
1584 if (Trailing > 0 && Leading + Trailing == 32 && C2 + Trailing < XLen &&
1585 OneUseOrZExtW && Subtarget->hasStdExtZba()) {
1586 SDNode *SRLI = CurDAG->getMachineNode(
1587 RISCV::SRLI, DL, VT, X,
1588 CurDAG->getTargetConstant(C2 + Trailing, DL, VT));
1589 SDNode *SLLI_UW = CurDAG->getMachineNode(
1590 RISCV::SLLI_UW, DL, VT, SDValue(SRLI, 0),
1591 CurDAG->getTargetConstant(Trailing, DL, VT));
1592 ReplaceNode(Node, SLLI_UW);
1593 return;
1594 }
1595 }
1596
1597 // Turn (and (shl x, c2), c1) -> (slli (srli x, c3-c2), c3) if c1 is a
1598 // shifted mask with no leading zeros and c3 trailing zeros.
1599 if (LeftShift && isShiftedMask_64(C1)) {
1600 unsigned Leading = XLen - llvm::bit_width(C1);
1601 unsigned Trailing = llvm::countr_zero(C1);
1602 if (Leading == 0 && C2 < Trailing && OneUseOrZExtW && !IsCANDI) {
1603 SDNode *SRLI = CurDAG->getMachineNode(
1604 RISCV::SRLI, DL, VT, X,
1605 CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1606 SDNode *SLLI = CurDAG->getMachineNode(
1607 RISCV::SLLI, DL, VT, SDValue(SRLI, 0),
1608 CurDAG->getTargetConstant(Trailing, DL, VT));
1609 ReplaceNode(Node, SLLI);
1610 return;
1611 }
1612 // If we have (32-C2) leading zeros, we can use SRLIW instead of SRLI.
1613 if (C2 < Trailing && Leading + C2 == 32 && OneUseOrZExtW && !IsCANDI) {
1614 SDNode *SRLIW = CurDAG->getMachineNode(
1615 RISCV::SRLIW, DL, VT, X,
1616 CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1617 SDNode *SLLI = CurDAG->getMachineNode(
1618 RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
1619 CurDAG->getTargetConstant(Trailing, DL, VT));
1620 ReplaceNode(Node, SLLI);
1621 return;
1622 }
1623
1624 // If we have 32 bits in the mask, we can use SLLI_UW instead of SLLI.
1625 if (C2 < Trailing && Leading + Trailing == 32 && OneUseOrZExtW &&
1626 Subtarget->hasStdExtZba()) {
1627 SDNode *SRLI = CurDAG->getMachineNode(
1628 RISCV::SRLI, DL, VT, X,
1629 CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1630 SDNode *SLLI_UW = CurDAG->getMachineNode(
1631 RISCV::SLLI_UW, DL, VT, SDValue(SRLI, 0),
1632 CurDAG->getTargetConstant(Trailing, DL, VT));
1633 ReplaceNode(Node, SLLI_UW);
1634 return;
1635 }
1636 }
1637 }
1638
1639 const uint64_t C1 = N1C->getZExtValue();
1640
1641 if (N0.getOpcode() == ISD::SRA && isa<ConstantSDNode>(N0.getOperand(1)) &&
1642 N0.hasOneUse()) {
1643 unsigned C2 = N0.getConstantOperandVal(1);
1644 unsigned XLen = Subtarget->getXLen();
1645 assert((C2 > 0 && C2 < XLen) && "Unexpected shift amount!");
1646
1647 SDValue X = N0.getOperand(0);
1648
1649 // Prefer SRAIW + ANDI when possible.
1650 bool Skip = C2 > 32 && isInt<12>(N1C->getSExtValue()) &&
1651 X.getOpcode() == ISD::SHL &&
1652 isa<ConstantSDNode>(X.getOperand(1)) &&
1653 X.getConstantOperandVal(1) == 32;
1654 // Turn (and (sra x, c2), c1) -> (srli (srai x, c2-c3), c3) if c1 is a
1655 // mask with c3 leading zeros and c2 is larger than c3.
1656 if (isMask_64(C1) && !Skip) {
1657 unsigned Leading = XLen - llvm::bit_width(C1);
1658 if (C2 > Leading) {
1659 SDNode *SRAI = CurDAG->getMachineNode(
1660 RISCV::SRAI, DL, VT, X,
1661 CurDAG->getTargetConstant(C2 - Leading, DL, VT));
1662 SDNode *SRLI = CurDAG->getMachineNode(
1663 RISCV::SRLI, DL, VT, SDValue(SRAI, 0),
1664 CurDAG->getTargetConstant(Leading, DL, VT));
1665 ReplaceNode(Node, SRLI);
1666 return;
1667 }
1668 }
1669
1670 // Look for (and (sra y, c2), c1) where c1 is a shifted mask with c3
1671 // leading zeros and c4 trailing zeros. If c2 is greater than c3, we can
1672 // use (slli (srli (srai y, c2 - c3), c3 + c4), c4).
1673 if (isShiftedMask_64(C1) && !Skip) {
1674 unsigned Leading = XLen - llvm::bit_width(C1);
1675 unsigned Trailing = llvm::countr_zero(C1);
1676 if (C2 > Leading && Leading > 0 && Trailing > 0) {
1677 SDNode *SRAI = CurDAG->getMachineNode(
1678 RISCV::SRAI, DL, VT, N0.getOperand(0),
1679 CurDAG->getTargetConstant(C2 - Leading, DL, VT));
1680 SDNode *SRLI = CurDAG->getMachineNode(
1681 RISCV::SRLI, DL, VT, SDValue(SRAI, 0),
1682 CurDAG->getTargetConstant(Leading + Trailing, DL, VT));
1683 SDNode *SLLI = CurDAG->getMachineNode(
1684 RISCV::SLLI, DL, VT, SDValue(SRLI, 0),
1685 CurDAG->getTargetConstant(Trailing, DL, VT));
1686 ReplaceNode(Node, SLLI);
1687 return;
1688 }
1689 }
1690 }
1691
1692 // If C1 masks off the upper bits only (but can't be formed as an
1693 // ANDI), use an unsigned bitfield extract (e.g., th.extu), if
1694 // available.
1695 // Transform (and x, C1)
1696 // -> (<bfextract> x, msb, lsb)
1697 if (isMask_64(C1) && !isInt<12>(N1C->getSExtValue()) &&
1698 !(C1 == 0xffff && Subtarget->hasStdExtZbb()) &&
1699 !(C1 == 0xffffffff && Subtarget->hasStdExtZba())) {
1700 const unsigned Msb = llvm::bit_width(C1) - 1;
1701 if (tryUnsignedBitfieldExtract(Node, DL, VT, N0, Msb, 0))
1702 return;
1703 }
1704
1706 return;
1707
1708 break;
1709 }
1710 case ISD::MUL: {
1711 // Special case for calculating (mul (and X, C2), C1) where the full product
1712 // fits in XLen bits. We can shift X left by the number of leading zeros in
1713 // C2 and shift C1 left by XLen-lzcnt(C2). This will ensure the final
1714 // product has XLen trailing zeros, putting it in the output of MULHU. This
1715 // can avoid materializing a constant in a register for C2.
1716
1717 // RHS should be a constant.
1718 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
1719 if (!N1C || !N1C->hasOneUse())
1720 break;
1721
1722 // LHS should be an AND with constant.
1723 SDValue N0 = Node->getOperand(0);
1724 if (N0.getOpcode() != ISD::AND || !isa<ConstantSDNode>(N0.getOperand(1)))
1725 break;
1726
1728
1729 // Constant should be a mask.
1730 if (!isMask_64(C2))
1731 break;
1732
1733 // If this can be an ANDI or ZEXT.H, don't do this if the ANDI/ZEXT has
1734 // multiple users or the constant is a simm12. This prevents inserting a
1735 // shift and still have uses of the AND/ZEXT. Shifting a simm12 will likely
1736 // make it more costly to materialize. Otherwise, using a SLLI might allow
1737 // it to be compressed.
1738 bool IsANDIOrZExt =
1739 isInt<12>(C2) ||
1740 (C2 == UINT64_C(0xFFFF) && Subtarget->hasStdExtZbb());
1741 // With XTHeadBb, we can use TH.EXTU.
1742 IsANDIOrZExt |= C2 == UINT64_C(0xFFFF) && Subtarget->hasVendorXTHeadBb();
1743 if (IsANDIOrZExt && (isInt<12>(N1C->getSExtValue()) || !N0.hasOneUse()))
1744 break;
1745 // If this can be a ZEXT.w, don't do this if the ZEXT has multiple users or
1746 // the constant is a simm32.
1747 bool IsZExtW = C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba();
1748 // With XTHeadBb, we can use TH.EXTU.
1749 IsZExtW |= C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasVendorXTHeadBb();
1750 if (IsZExtW && (isInt<32>(N1C->getSExtValue()) || !N0.hasOneUse()))
1751 break;
1752
1753 // We need to shift left the AND input and C1 by a total of XLen bits.
1754
1755 // How far left do we need to shift the AND input?
1756 unsigned XLen = Subtarget->getXLen();
1757 unsigned LeadingZeros = XLen - llvm::bit_width(C2);
1758
1759 // The constant gets shifted by the remaining amount unless that would
1760 // shift bits out.
1761 uint64_t C1 = N1C->getZExtValue();
1762 unsigned ConstantShift = XLen - LeadingZeros;
1763 if (ConstantShift > (XLen - llvm::bit_width(C1)))
1764 break;
1765
1766 uint64_t ShiftedC1 = C1 << ConstantShift;
1767 // If this RV32, we need to sign extend the constant.
1768 if (XLen == 32)
1769 ShiftedC1 = SignExtend64<32>(ShiftedC1);
1770
1771 // Create (mulhu (slli X, lzcnt(C2)), C1 << (XLen - lzcnt(C2))).
1772 SDNode *Imm = selectImm(CurDAG, DL, VT, ShiftedC1, *Subtarget).getNode();
1773 SDNode *SLLI =
1774 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0.getOperand(0),
1775 CurDAG->getTargetConstant(LeadingZeros, DL, VT));
1776 SDNode *MULHU = CurDAG->getMachineNode(RISCV::MULHU, DL, VT,
1777 SDValue(SLLI, 0), SDValue(Imm, 0));
1778 ReplaceNode(Node, MULHU);
1779 return;
1780 }
1781 case ISD::LOAD: {
1782 if (tryIndexedLoad(Node))
1783 return;
1784
1785 if (Subtarget->hasVendorXCVmem() && !Subtarget->is64Bit()) {
1786 // We match post-incrementing load here
1788 if (Load->getAddressingMode() != ISD::POST_INC)
1789 break;
1790
1791 SDValue Chain = Node->getOperand(0);
1792 SDValue Base = Node->getOperand(1);
1793 SDValue Offset = Node->getOperand(2);
1794
1795 bool Simm12 = false;
1796 bool SignExtend = Load->getExtensionType() == ISD::SEXTLOAD;
1797
1798 if (auto ConstantOffset = dyn_cast<ConstantSDNode>(Offset)) {
1799 int ConstantVal = ConstantOffset->getSExtValue();
1800 Simm12 = isInt<12>(ConstantVal);
1801 if (Simm12)
1802 Offset = CurDAG->getTargetConstant(ConstantVal, SDLoc(Offset),
1803 Offset.getValueType());
1804 }
1805
1806 unsigned Opcode = 0;
1807 switch (Load->getMemoryVT().getSimpleVT().SimpleTy) {
1808 case MVT::i8:
1809 if (Simm12 && SignExtend)
1810 Opcode = RISCV::CV_LB_ri_inc;
1811 else if (Simm12 && !SignExtend)
1812 Opcode = RISCV::CV_LBU_ri_inc;
1813 else if (!Simm12 && SignExtend)
1814 Opcode = RISCV::CV_LB_rr_inc;
1815 else
1816 Opcode = RISCV::CV_LBU_rr_inc;
1817 break;
1818 case MVT::i16:
1819 if (Simm12 && SignExtend)
1820 Opcode = RISCV::CV_LH_ri_inc;
1821 else if (Simm12 && !SignExtend)
1822 Opcode = RISCV::CV_LHU_ri_inc;
1823 else if (!Simm12 && SignExtend)
1824 Opcode = RISCV::CV_LH_rr_inc;
1825 else
1826 Opcode = RISCV::CV_LHU_rr_inc;
1827 break;
1828 case MVT::i32:
1829 if (Simm12)
1830 Opcode = RISCV::CV_LW_ri_inc;
1831 else
1832 Opcode = RISCV::CV_LW_rr_inc;
1833 break;
1834 default:
1835 break;
1836 }
1837 if (!Opcode)
1838 break;
1839
1840 ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, XLenVT, XLenVT,
1841 Chain.getSimpleValueType(), Base,
1842 Offset, Chain));
1843 return;
1844 }
1845 break;
1846 }
1847 case RISCVISD::LD_RV32: {
1848 assert(Subtarget->hasStdExtZilsd() && "LD_RV32 is only used with Zilsd");
1849
1851 SDValue Chain = Node->getOperand(0);
1852 SDValue Addr = Node->getOperand(1);
1854
1855 SDValue Ops[] = {Base, Offset, Chain};
1856 MachineSDNode *New = CurDAG->getMachineNode(
1857 RISCV::LD_RV32, DL, {MVT::Untyped, MVT::Other}, Ops);
1858 SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL,
1859 MVT::i32, SDValue(New, 0));
1860 SDValue Hi = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_odd, DL,
1861 MVT::i32, SDValue(New, 0));
1862 CurDAG->setNodeMemRefs(New, {cast<MemSDNode>(Node)->getMemOperand()});
1863 ReplaceUses(SDValue(Node, 0), Lo);
1864 ReplaceUses(SDValue(Node, 1), Hi);
1865 ReplaceUses(SDValue(Node, 2), SDValue(New, 1));
1866 CurDAG->RemoveDeadNode(Node);
1867 return;
1868 }
1869 case RISCVISD::SD_RV32: {
1871 SDValue Chain = Node->getOperand(0);
1872 SDValue Addr = Node->getOperand(3);
1874
1875 SDValue Lo = Node->getOperand(1);
1876 SDValue Hi = Node->getOperand(2);
1877
1878 SDValue RegPair;
1879 // Peephole to use X0_Pair for storing zero.
1881 RegPair = CurDAG->getRegister(RISCV::X0_Pair, MVT::Untyped);
1882 } else {
1883 SDValue Ops[] = {
1884 CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32), Lo,
1885 CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32), Hi,
1886 CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
1887
1888 RegPair = SDValue(CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
1889 MVT::Untyped, Ops),
1890 0);
1891 }
1892
1893 MachineSDNode *New = CurDAG->getMachineNode(RISCV::SD_RV32, DL, MVT::Other,
1894 {RegPair, Base, Offset, Chain});
1895 CurDAG->setNodeMemRefs(New, {cast<MemSDNode>(Node)->getMemOperand()});
1896 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
1897 CurDAG->RemoveDeadNode(Node);
1898 return;
1899 }
1901 unsigned IntNo = Node->getConstantOperandVal(0);
1902 switch (IntNo) {
1903 // By default we do not custom select any intrinsic.
1904 default:
1905 break;
1906 case Intrinsic::riscv_vmsgeu:
1907 case Intrinsic::riscv_vmsge: {
1908 SDValue Src1 = Node->getOperand(1);
1909 SDValue Src2 = Node->getOperand(2);
1910 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu;
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 int64_t CVal = 0;
1918 MVT Src1VT = Src1.getSimpleValueType();
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, VMNANDOpcode, VMSetOpcode, VMSGTOpcode;
1933 switch (RISCVTargetLowering::getLMUL(Src1VT)) {
1934 default:
1935 llvm_unreachable("Unexpected LMUL!");
1936#define CASE_VMSLT_OPCODES(lmulenum, suffix) \
1937 case RISCVVType::lmulenum: \
1938 VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
1939 : RISCV::PseudoVMSLT_VX_##suffix; \
1940 VMSGTOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix \
1941 : RISCV::PseudoVMSGT_VX_##suffix; \
1942 break;
1943 CASE_VMSLT_OPCODES(LMUL_F8, MF8)
1944 CASE_VMSLT_OPCODES(LMUL_F4, MF4)
1945 CASE_VMSLT_OPCODES(LMUL_F2, MF2)
1946 CASE_VMSLT_OPCODES(LMUL_1, M1)
1947 CASE_VMSLT_OPCODES(LMUL_2, M2)
1948 CASE_VMSLT_OPCODES(LMUL_4, M4)
1949 CASE_VMSLT_OPCODES(LMUL_8, M8)
1950#undef CASE_VMSLT_OPCODES
1951 }
1952 // Mask operations use the LMUL from the mask type.
1953 switch (RISCVTargetLowering::getLMUL(VT)) {
1954 default:
1955 llvm_unreachable("Unexpected LMUL!");
1956#define CASE_VMNAND_VMSET_OPCODES(lmulenum, suffix) \
1957 case RISCVVType::lmulenum: \
1958 VMNANDOpcode = RISCV::PseudoVMNAND_MM_##suffix; \
1959 VMSetOpcode = RISCV::PseudoVMSET_M_##suffix; \
1960 break;
1961 CASE_VMNAND_VMSET_OPCODES(LMUL_F8, B64)
1962 CASE_VMNAND_VMSET_OPCODES(LMUL_F4, B32)
1963 CASE_VMNAND_VMSET_OPCODES(LMUL_F2, B16)
1964 CASE_VMNAND_VMSET_OPCODES(LMUL_1, B8)
1965 CASE_VMNAND_VMSET_OPCODES(LMUL_2, B4)
1966 CASE_VMNAND_VMSET_OPCODES(LMUL_4, B2)
1967 CASE_VMNAND_VMSET_OPCODES(LMUL_8, B1)
1968#undef CASE_VMNAND_VMSET_OPCODES
1969 }
1970 SDValue SEW = CurDAG->getTargetConstant(
1971 Log2_32(Src1VT.getScalarSizeInBits()), DL, XLenVT);
1972 SDValue MaskSEW = CurDAG->getTargetConstant(0, DL, XLenVT);
1973 SDValue VL;
1974 selectVLOp(Node->getOperand(3), VL);
1975
1976 // If vmsge(u) with minimum value, expand it to vmset.
1977 if (IsCmpMinimum) {
1979 CurDAG->getMachineNode(VMSetOpcode, DL, VT, VL, MaskSEW));
1980 return;
1981 }
1982
1983 if (IsCmpConstant) {
1984 SDValue Imm =
1985 selectImm(CurDAG, SDLoc(Src2), XLenVT, CVal - 1, *Subtarget);
1986
1987 ReplaceNode(Node, CurDAG->getMachineNode(VMSGTOpcode, DL, VT,
1988 {Src1, Imm, VL, SEW}));
1989 return;
1990 }
1991
1992 // Expand to
1993 // vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
1994 SDValue Cmp = SDValue(
1995 CurDAG->getMachineNode(VMSLTOpcode, DL, VT, {Src1, Src2, VL, SEW}),
1996 0);
1997 ReplaceNode(Node, CurDAG->getMachineNode(VMNANDOpcode, DL, VT,
1998 {Cmp, Cmp, VL, MaskSEW}));
1999 return;
2000 }
2001 case Intrinsic::riscv_vmsgeu_mask:
2002 case Intrinsic::riscv_vmsge_mask: {
2003 SDValue Src1 = Node->getOperand(2);
2004 SDValue Src2 = Node->getOperand(3);
2005 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu_mask;
2006 bool IsCmpConstant = false;
2007 bool IsCmpMinimum = false;
2008 // Only custom select scalar second operand.
2009 if (Src2.getValueType() != XLenVT)
2010 break;
2011 // Small constants are handled with patterns.
2012 MVT Src1VT = Src1.getSimpleValueType();
2013 int64_t CVal = 0;
2014 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
2015 IsCmpConstant = true;
2016 CVal = C->getSExtValue();
2017 if (CVal >= -15 && CVal <= 16) {
2018 if (!IsUnsigned || CVal != 0)
2019 break;
2020 IsCmpMinimum = true;
2021 } else if (!IsUnsigned && CVal == APInt::getSignedMinValue(
2022 Src1VT.getScalarSizeInBits())
2023 .getSExtValue()) {
2024 IsCmpMinimum = true;
2025 }
2026 }
2027 unsigned VMSLTOpcode, VMSLTMaskOpcode, VMXOROpcode, VMANDNOpcode,
2028 VMOROpcode, VMSGTMaskOpcode;
2029 switch (RISCVTargetLowering::getLMUL(Src1VT)) {
2030 default:
2031 llvm_unreachable("Unexpected LMUL!");
2032#define CASE_VMSLT_OPCODES(lmulenum, suffix) \
2033 case RISCVVType::lmulenum: \
2034 VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
2035 : RISCV::PseudoVMSLT_VX_##suffix; \
2036 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix##_MASK \
2037 : RISCV::PseudoVMSLT_VX_##suffix##_MASK; \
2038 VMSGTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix##_MASK \
2039 : RISCV::PseudoVMSGT_VX_##suffix##_MASK; \
2040 break;
2041 CASE_VMSLT_OPCODES(LMUL_F8, MF8)
2042 CASE_VMSLT_OPCODES(LMUL_F4, MF4)
2043 CASE_VMSLT_OPCODES(LMUL_F2, MF2)
2044 CASE_VMSLT_OPCODES(LMUL_1, M1)
2045 CASE_VMSLT_OPCODES(LMUL_2, M2)
2046 CASE_VMSLT_OPCODES(LMUL_4, M4)
2047 CASE_VMSLT_OPCODES(LMUL_8, M8)
2048#undef CASE_VMSLT_OPCODES
2049 }
2050 // Mask operations use the LMUL from the mask type.
2051 switch (RISCVTargetLowering::getLMUL(VT)) {
2052 default:
2053 llvm_unreachable("Unexpected LMUL!");
2054#define CASE_VMXOR_VMANDN_VMOR_OPCODES(lmulenum, suffix) \
2055 case RISCVVType::lmulenum: \
2056 VMXOROpcode = RISCV::PseudoVMXOR_MM_##suffix; \
2057 VMANDNOpcode = RISCV::PseudoVMANDN_MM_##suffix; \
2058 VMOROpcode = RISCV::PseudoVMOR_MM_##suffix; \
2059 break;
2060 CASE_VMXOR_VMANDN_VMOR_OPCODES(LMUL_F8, B64)
2061 CASE_VMXOR_VMANDN_VMOR_OPCODES(LMUL_F4, B32)
2062 CASE_VMXOR_VMANDN_VMOR_OPCODES(LMUL_F2, B16)
2067#undef CASE_VMXOR_VMANDN_VMOR_OPCODES
2068 }
2069 SDValue SEW = CurDAG->getTargetConstant(
2070 Log2_32(Src1VT.getScalarSizeInBits()), DL, XLenVT);
2071 SDValue MaskSEW = CurDAG->getTargetConstant(0, DL, XLenVT);
2072 SDValue VL;
2073 selectVLOp(Node->getOperand(5), VL);
2074 SDValue MaskedOff = Node->getOperand(1);
2075 SDValue Mask = Node->getOperand(4);
2076
2077 // If vmsge(u) with minimum value, expand it to vmor mask, maskedoff.
2078 if (IsCmpMinimum) {
2079 // We don't need vmor if the MaskedOff and the Mask are the same
2080 // value.
2081 if (Mask == MaskedOff) {
2082 ReplaceUses(Node, Mask.getNode());
2083 return;
2084 }
2086 CurDAG->getMachineNode(VMOROpcode, DL, VT,
2087 {Mask, MaskedOff, VL, MaskSEW}));
2088 return;
2089 }
2090
2091 // If the MaskedOff value and the Mask are the same value use
2092 // vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt
2093 // This avoids needing to copy v0 to vd before starting the next sequence.
2094 if (Mask == MaskedOff) {
2095 SDValue Cmp = SDValue(
2096 CurDAG->getMachineNode(VMSLTOpcode, DL, VT, {Src1, Src2, VL, SEW}),
2097 0);
2098 ReplaceNode(Node, CurDAG->getMachineNode(VMANDNOpcode, DL, VT,
2099 {Mask, Cmp, VL, MaskSEW}));
2100 return;
2101 }
2102
2103 SDValue PolicyOp =
2104 CurDAG->getTargetConstant(RISCVVType::TAIL_AGNOSTIC, DL, XLenVT);
2105
2106 if (IsCmpConstant) {
2107 SDValue Imm =
2108 selectImm(CurDAG, SDLoc(Src2), XLenVT, CVal - 1, *Subtarget);
2109
2110 ReplaceNode(Node, CurDAG->getMachineNode(
2111 VMSGTMaskOpcode, DL, VT,
2112 {MaskedOff, Src1, Imm, Mask, VL, SEW, PolicyOp}));
2113 return;
2114 }
2115
2116 // Otherwise use
2117 // vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
2118 // The result is mask undisturbed.
2119 // We use the same instructions to emulate mask agnostic behavior, because
2120 // the agnostic result can be either undisturbed or all 1.
2121 SDValue Cmp = SDValue(CurDAG->getMachineNode(VMSLTMaskOpcode, DL, VT,
2122 {MaskedOff, Src1, Src2, Mask,
2123 VL, SEW, PolicyOp}),
2124 0);
2125 // vmxor.mm vd, vd, v0 is used to update active value.
2126 ReplaceNode(Node, CurDAG->getMachineNode(VMXOROpcode, DL, VT,
2127 {Cmp, Mask, VL, MaskSEW}));
2128 return;
2129 }
2130 case Intrinsic::riscv_vsetvli:
2131 case Intrinsic::riscv_vsetvlimax:
2132 return selectVSETVLI(Node);
2133 }
2134 break;
2135 }
2137 unsigned IntNo = Node->getConstantOperandVal(1);
2138 switch (IntNo) {
2139 // By default we do not custom select any intrinsic.
2140 default:
2141 break;
2142 case Intrinsic::riscv_vlseg2:
2143 case Intrinsic::riscv_vlseg3:
2144 case Intrinsic::riscv_vlseg4:
2145 case Intrinsic::riscv_vlseg5:
2146 case Intrinsic::riscv_vlseg6:
2147 case Intrinsic::riscv_vlseg7:
2148 case Intrinsic::riscv_vlseg8: {
2149 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2150 /*IsStrided*/ false);
2151 return;
2152 }
2153 case Intrinsic::riscv_vlseg2_mask:
2154 case Intrinsic::riscv_vlseg3_mask:
2155 case Intrinsic::riscv_vlseg4_mask:
2156 case Intrinsic::riscv_vlseg5_mask:
2157 case Intrinsic::riscv_vlseg6_mask:
2158 case Intrinsic::riscv_vlseg7_mask:
2159 case Intrinsic::riscv_vlseg8_mask: {
2160 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2161 /*IsStrided*/ false);
2162 return;
2163 }
2164 case Intrinsic::riscv_vlsseg2:
2165 case Intrinsic::riscv_vlsseg3:
2166 case Intrinsic::riscv_vlsseg4:
2167 case Intrinsic::riscv_vlsseg5:
2168 case Intrinsic::riscv_vlsseg6:
2169 case Intrinsic::riscv_vlsseg7:
2170 case Intrinsic::riscv_vlsseg8: {
2171 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2172 /*IsStrided*/ true);
2173 return;
2174 }
2175 case Intrinsic::riscv_vlsseg2_mask:
2176 case Intrinsic::riscv_vlsseg3_mask:
2177 case Intrinsic::riscv_vlsseg4_mask:
2178 case Intrinsic::riscv_vlsseg5_mask:
2179 case Intrinsic::riscv_vlsseg6_mask:
2180 case Intrinsic::riscv_vlsseg7_mask:
2181 case Intrinsic::riscv_vlsseg8_mask: {
2182 selectVLSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2183 /*IsStrided*/ true);
2184 return;
2185 }
2186 case Intrinsic::riscv_vloxseg2:
2187 case Intrinsic::riscv_vloxseg3:
2188 case Intrinsic::riscv_vloxseg4:
2189 case Intrinsic::riscv_vloxseg5:
2190 case Intrinsic::riscv_vloxseg6:
2191 case Intrinsic::riscv_vloxseg7:
2192 case Intrinsic::riscv_vloxseg8:
2193 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2194 /*IsOrdered*/ true);
2195 return;
2196 case Intrinsic::riscv_vluxseg2:
2197 case Intrinsic::riscv_vluxseg3:
2198 case Intrinsic::riscv_vluxseg4:
2199 case Intrinsic::riscv_vluxseg5:
2200 case Intrinsic::riscv_vluxseg6:
2201 case Intrinsic::riscv_vluxseg7:
2202 case Intrinsic::riscv_vluxseg8:
2203 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2204 /*IsOrdered*/ false);
2205 return;
2206 case Intrinsic::riscv_vloxseg2_mask:
2207 case Intrinsic::riscv_vloxseg3_mask:
2208 case Intrinsic::riscv_vloxseg4_mask:
2209 case Intrinsic::riscv_vloxseg5_mask:
2210 case Intrinsic::riscv_vloxseg6_mask:
2211 case Intrinsic::riscv_vloxseg7_mask:
2212 case Intrinsic::riscv_vloxseg8_mask:
2213 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2214 /*IsOrdered*/ true);
2215 return;
2216 case Intrinsic::riscv_vluxseg2_mask:
2217 case Intrinsic::riscv_vluxseg3_mask:
2218 case Intrinsic::riscv_vluxseg4_mask:
2219 case Intrinsic::riscv_vluxseg5_mask:
2220 case Intrinsic::riscv_vluxseg6_mask:
2221 case Intrinsic::riscv_vluxseg7_mask:
2222 case Intrinsic::riscv_vluxseg8_mask:
2223 selectVLXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2224 /*IsOrdered*/ false);
2225 return;
2226 case Intrinsic::riscv_vlseg8ff:
2227 case Intrinsic::riscv_vlseg7ff:
2228 case Intrinsic::riscv_vlseg6ff:
2229 case Intrinsic::riscv_vlseg5ff:
2230 case Intrinsic::riscv_vlseg4ff:
2231 case Intrinsic::riscv_vlseg3ff:
2232 case Intrinsic::riscv_vlseg2ff: {
2233 selectVLSEGFF(Node, getSegInstNF(IntNo), /*IsMasked*/ false);
2234 return;
2235 }
2236 case Intrinsic::riscv_vlseg8ff_mask:
2237 case Intrinsic::riscv_vlseg7ff_mask:
2238 case Intrinsic::riscv_vlseg6ff_mask:
2239 case Intrinsic::riscv_vlseg5ff_mask:
2240 case Intrinsic::riscv_vlseg4ff_mask:
2241 case Intrinsic::riscv_vlseg3ff_mask:
2242 case Intrinsic::riscv_vlseg2ff_mask: {
2243 selectVLSEGFF(Node, getSegInstNF(IntNo), /*IsMasked*/ true);
2244 return;
2245 }
2246 case Intrinsic::riscv_vloxei:
2247 case Intrinsic::riscv_vloxei_mask:
2248 case Intrinsic::riscv_vluxei:
2249 case Intrinsic::riscv_vluxei_mask: {
2250 bool IsMasked = IntNo == Intrinsic::riscv_vloxei_mask ||
2251 IntNo == Intrinsic::riscv_vluxei_mask;
2252 bool IsOrdered = IntNo == Intrinsic::riscv_vloxei ||
2253 IntNo == Intrinsic::riscv_vloxei_mask;
2254
2255 MVT VT = Node->getSimpleValueType(0);
2256 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2257
2258 unsigned CurOp = 2;
2260 Operands.push_back(Node->getOperand(CurOp++));
2261
2262 MVT IndexVT;
2263 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2264 /*IsStridedOrIndexed*/ true, Operands,
2265 /*IsLoad=*/true, &IndexVT);
2266
2268 "Element count mismatch");
2269
2272 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
2273 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
2274 report_fatal_error("The V extension does not support EEW=64 for index "
2275 "values when XLEN=32");
2276 }
2277 const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo(
2278 IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
2279 static_cast<unsigned>(IndexLMUL));
2280 MachineSDNode *Load =
2281 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2282
2283 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
2284
2285 ReplaceNode(Node, Load);
2286 return;
2287 }
2288 case Intrinsic::riscv_vlm:
2289 case Intrinsic::riscv_vle:
2290 case Intrinsic::riscv_vle_mask:
2291 case Intrinsic::riscv_vlse:
2292 case Intrinsic::riscv_vlse_mask: {
2293 bool IsMasked = IntNo == Intrinsic::riscv_vle_mask ||
2294 IntNo == Intrinsic::riscv_vlse_mask;
2295 bool IsStrided =
2296 IntNo == Intrinsic::riscv_vlse || IntNo == Intrinsic::riscv_vlse_mask;
2297
2298 MVT VT = Node->getSimpleValueType(0);
2299 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2300
2301 // The riscv_vlm intrinsic are always tail agnostic and no passthru
2302 // operand at the IR level. In pseudos, they have both policy and
2303 // passthru operand. The passthru operand is needed to track the
2304 // "tail undefined" state, and the policy is there just for
2305 // for consistency - it will always be "don't care" for the
2306 // unmasked form.
2307 bool HasPassthruOperand = IntNo != Intrinsic::riscv_vlm;
2308 unsigned CurOp = 2;
2310 if (HasPassthruOperand)
2311 Operands.push_back(Node->getOperand(CurOp++));
2312 else {
2313 // We eagerly lower to implicit_def (instead of undef), as we
2314 // otherwise fail to select nodes such as: nxv1i1 = undef
2315 SDNode *Passthru =
2316 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
2317 Operands.push_back(SDValue(Passthru, 0));
2318 }
2319 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
2320 Operands, /*IsLoad=*/true);
2321
2323 const RISCV::VLEPseudo *P =
2324 RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW,
2325 static_cast<unsigned>(LMUL));
2326 MachineSDNode *Load =
2327 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2328
2329 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
2330
2331 ReplaceNode(Node, Load);
2332 return;
2333 }
2334 case Intrinsic::riscv_vleff:
2335 case Intrinsic::riscv_vleff_mask: {
2336 bool IsMasked = IntNo == Intrinsic::riscv_vleff_mask;
2337
2338 MVT VT = Node->getSimpleValueType(0);
2339 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2340
2341 unsigned CurOp = 2;
2343 Operands.push_back(Node->getOperand(CurOp++));
2344 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2345 /*IsStridedOrIndexed*/ false, Operands,
2346 /*IsLoad=*/true);
2347
2349 const RISCV::VLEPseudo *P =
2350 RISCV::getVLEPseudo(IsMasked, /*Strided*/ false, /*FF*/ true,
2351 Log2SEW, static_cast<unsigned>(LMUL));
2352 MachineSDNode *Load = CurDAG->getMachineNode(
2353 P->Pseudo, DL, Node->getVTList(), Operands);
2354 CurDAG->setNodeMemRefs(Load, {cast<MemSDNode>(Node)->getMemOperand()});
2355
2356 ReplaceNode(Node, Load);
2357 return;
2358 }
2359 case Intrinsic::riscv_nds_vln:
2360 case Intrinsic::riscv_nds_vln_mask:
2361 case Intrinsic::riscv_nds_vlnu:
2362 case Intrinsic::riscv_nds_vlnu_mask: {
2363 bool IsMasked = IntNo == Intrinsic::riscv_nds_vln_mask ||
2364 IntNo == Intrinsic::riscv_nds_vlnu_mask;
2365 bool IsUnsigned = IntNo == Intrinsic::riscv_nds_vlnu ||
2366 IntNo == Intrinsic::riscv_nds_vlnu_mask;
2367
2368 MVT VT = Node->getSimpleValueType(0);
2369 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2370 unsigned CurOp = 2;
2372
2373 Operands.push_back(Node->getOperand(CurOp++));
2374 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2375 /*IsStridedOrIndexed=*/false, Operands,
2376 /*IsLoad=*/true);
2377
2379 const RISCV::NDSVLNPseudo *P = RISCV::getNDSVLNPseudo(
2380 IsMasked, IsUnsigned, Log2SEW, static_cast<unsigned>(LMUL));
2381 MachineSDNode *Load =
2382 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2383
2384 if (auto *MemOp = dyn_cast<MemSDNode>(Node))
2385 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
2386
2387 ReplaceNode(Node, Load);
2388 return;
2389 }
2390 }
2391 break;
2392 }
2393 case ISD::INTRINSIC_VOID: {
2394 unsigned IntNo = Node->getConstantOperandVal(1);
2395 switch (IntNo) {
2396 case Intrinsic::riscv_vsseg2:
2397 case Intrinsic::riscv_vsseg3:
2398 case Intrinsic::riscv_vsseg4:
2399 case Intrinsic::riscv_vsseg5:
2400 case Intrinsic::riscv_vsseg6:
2401 case Intrinsic::riscv_vsseg7:
2402 case Intrinsic::riscv_vsseg8: {
2403 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2404 /*IsStrided*/ false);
2405 return;
2406 }
2407 case Intrinsic::riscv_vsseg2_mask:
2408 case Intrinsic::riscv_vsseg3_mask:
2409 case Intrinsic::riscv_vsseg4_mask:
2410 case Intrinsic::riscv_vsseg5_mask:
2411 case Intrinsic::riscv_vsseg6_mask:
2412 case Intrinsic::riscv_vsseg7_mask:
2413 case Intrinsic::riscv_vsseg8_mask: {
2414 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2415 /*IsStrided*/ false);
2416 return;
2417 }
2418 case Intrinsic::riscv_vssseg2:
2419 case Intrinsic::riscv_vssseg3:
2420 case Intrinsic::riscv_vssseg4:
2421 case Intrinsic::riscv_vssseg5:
2422 case Intrinsic::riscv_vssseg6:
2423 case Intrinsic::riscv_vssseg7:
2424 case Intrinsic::riscv_vssseg8: {
2425 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2426 /*IsStrided*/ true);
2427 return;
2428 }
2429 case Intrinsic::riscv_vssseg2_mask:
2430 case Intrinsic::riscv_vssseg3_mask:
2431 case Intrinsic::riscv_vssseg4_mask:
2432 case Intrinsic::riscv_vssseg5_mask:
2433 case Intrinsic::riscv_vssseg6_mask:
2434 case Intrinsic::riscv_vssseg7_mask:
2435 case Intrinsic::riscv_vssseg8_mask: {
2436 selectVSSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2437 /*IsStrided*/ true);
2438 return;
2439 }
2440 case Intrinsic::riscv_vsoxseg2:
2441 case Intrinsic::riscv_vsoxseg3:
2442 case Intrinsic::riscv_vsoxseg4:
2443 case Intrinsic::riscv_vsoxseg5:
2444 case Intrinsic::riscv_vsoxseg6:
2445 case Intrinsic::riscv_vsoxseg7:
2446 case Intrinsic::riscv_vsoxseg8:
2447 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2448 /*IsOrdered*/ true);
2449 return;
2450 case Intrinsic::riscv_vsuxseg2:
2451 case Intrinsic::riscv_vsuxseg3:
2452 case Intrinsic::riscv_vsuxseg4:
2453 case Intrinsic::riscv_vsuxseg5:
2454 case Intrinsic::riscv_vsuxseg6:
2455 case Intrinsic::riscv_vsuxseg7:
2456 case Intrinsic::riscv_vsuxseg8:
2457 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ false,
2458 /*IsOrdered*/ false);
2459 return;
2460 case Intrinsic::riscv_vsoxseg2_mask:
2461 case Intrinsic::riscv_vsoxseg3_mask:
2462 case Intrinsic::riscv_vsoxseg4_mask:
2463 case Intrinsic::riscv_vsoxseg5_mask:
2464 case Intrinsic::riscv_vsoxseg6_mask:
2465 case Intrinsic::riscv_vsoxseg7_mask:
2466 case Intrinsic::riscv_vsoxseg8_mask:
2467 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2468 /*IsOrdered*/ true);
2469 return;
2470 case Intrinsic::riscv_vsuxseg2_mask:
2471 case Intrinsic::riscv_vsuxseg3_mask:
2472 case Intrinsic::riscv_vsuxseg4_mask:
2473 case Intrinsic::riscv_vsuxseg5_mask:
2474 case Intrinsic::riscv_vsuxseg6_mask:
2475 case Intrinsic::riscv_vsuxseg7_mask:
2476 case Intrinsic::riscv_vsuxseg8_mask:
2477 selectVSXSEG(Node, getSegInstNF(IntNo), /*IsMasked*/ true,
2478 /*IsOrdered*/ false);
2479 return;
2480 case Intrinsic::riscv_vsoxei:
2481 case Intrinsic::riscv_vsoxei_mask:
2482 case Intrinsic::riscv_vsuxei:
2483 case Intrinsic::riscv_vsuxei_mask: {
2484 bool IsMasked = IntNo == Intrinsic::riscv_vsoxei_mask ||
2485 IntNo == Intrinsic::riscv_vsuxei_mask;
2486 bool IsOrdered = IntNo == Intrinsic::riscv_vsoxei ||
2487 IntNo == Intrinsic::riscv_vsoxei_mask;
2488
2489 MVT VT = Node->getOperand(2)->getSimpleValueType(0);
2490 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2491
2492 unsigned CurOp = 2;
2494 Operands.push_back(Node->getOperand(CurOp++)); // Store value.
2495
2496 MVT IndexVT;
2497 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2498 /*IsStridedOrIndexed*/ true, Operands,
2499 /*IsLoad=*/false, &IndexVT);
2500
2502 "Element count mismatch");
2503
2506 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
2507 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
2508 report_fatal_error("The V extension does not support EEW=64 for index "
2509 "values when XLEN=32");
2510 }
2511 const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo(
2512 IsMasked, IsOrdered, IndexLog2EEW,
2513 static_cast<unsigned>(LMUL), static_cast<unsigned>(IndexLMUL));
2514 MachineSDNode *Store =
2515 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2516
2517 CurDAG->setNodeMemRefs(Store, {cast<MemSDNode>(Node)->getMemOperand()});
2518
2519 ReplaceNode(Node, Store);
2520 return;
2521 }
2522 case Intrinsic::riscv_vsm:
2523 case Intrinsic::riscv_vse:
2524 case Intrinsic::riscv_vse_mask:
2525 case Intrinsic::riscv_vsse:
2526 case Intrinsic::riscv_vsse_mask: {
2527 bool IsMasked = IntNo == Intrinsic::riscv_vse_mask ||
2528 IntNo == Intrinsic::riscv_vsse_mask;
2529 bool IsStrided =
2530 IntNo == Intrinsic::riscv_vsse || IntNo == Intrinsic::riscv_vsse_mask;
2531
2532 MVT VT = Node->getOperand(2)->getSimpleValueType(0);
2533 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2534
2535 unsigned CurOp = 2;
2537 Operands.push_back(Node->getOperand(CurOp++)); // Store value.
2538
2539 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided,
2540 Operands);
2541
2543 const RISCV::VSEPseudo *P = RISCV::getVSEPseudo(
2544 IsMasked, IsStrided, Log2SEW, static_cast<unsigned>(LMUL));
2545 MachineSDNode *Store =
2546 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2547 CurDAG->setNodeMemRefs(Store, {cast<MemSDNode>(Node)->getMemOperand()});
2548
2549 ReplaceNode(Node, Store);
2550 return;
2551 }
2552 case Intrinsic::riscv_sf_vc_x_se:
2553 case Intrinsic::riscv_sf_vc_i_se:
2555 return;
2556 }
2557 break;
2558 }
2559 case ISD::BITCAST: {
2560 MVT SrcVT = Node->getOperand(0).getSimpleValueType();
2561 // Just drop bitcasts between vectors if both are fixed or both are
2562 // scalable.
2563 if ((VT.isScalableVector() && SrcVT.isScalableVector()) ||
2564 (VT.isFixedLengthVector() && SrcVT.isFixedLengthVector())) {
2565 ReplaceUses(SDValue(Node, 0), Node->getOperand(0));
2566 CurDAG->RemoveDeadNode(Node);
2567 return;
2568 }
2569 break;
2570 }
2572 case RISCVISD::TUPLE_INSERT: {
2573 SDValue V = Node->getOperand(0);
2574 SDValue SubV = Node->getOperand(1);
2575 SDLoc DL(SubV);
2576 auto Idx = Node->getConstantOperandVal(2);
2577 MVT SubVecVT = SubV.getSimpleValueType();
2578
2579 const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering();
2580 MVT SubVecContainerVT = SubVecVT;
2581 // Establish the correct scalable-vector types for any fixed-length type.
2582 if (SubVecVT.isFixedLengthVector()) {
2583 SubVecContainerVT = TLI.getContainerForFixedLengthVector(SubVecVT);
2585 [[maybe_unused]] bool ExactlyVecRegSized =
2586 Subtarget->expandVScale(SubVecVT.getSizeInBits())
2587 .isKnownMultipleOf(Subtarget->expandVScale(VecRegSize));
2588 assert(isPowerOf2_64(Subtarget->expandVScale(SubVecVT.getSizeInBits())
2589 .getKnownMinValue()));
2590 assert(Idx == 0 && (ExactlyVecRegSized || V.isUndef()));
2591 }
2592 MVT ContainerVT = VT;
2593 if (VT.isFixedLengthVector())
2594 ContainerVT = TLI.getContainerForFixedLengthVector(VT);
2595
2596 const auto *TRI = Subtarget->getRegisterInfo();
2597 unsigned SubRegIdx;
2598 std::tie(SubRegIdx, Idx) =
2600 ContainerVT, SubVecContainerVT, Idx, TRI);
2601
2602 // If the Idx hasn't been completely eliminated then this is a subvector
2603 // insert which doesn't naturally align to a vector register. These must
2604 // be handled using instructions to manipulate the vector registers.
2605 if (Idx != 0)
2606 break;
2607
2608 RISCVVType::VLMUL SubVecLMUL =
2609 RISCVTargetLowering::getLMUL(SubVecContainerVT);
2610 [[maybe_unused]] bool IsSubVecPartReg =
2611 SubVecLMUL == RISCVVType::VLMUL::LMUL_F2 ||
2612 SubVecLMUL == RISCVVType::VLMUL::LMUL_F4 ||
2613 SubVecLMUL == RISCVVType::VLMUL::LMUL_F8;
2614 assert((V.getValueType().isRISCVVectorTuple() || !IsSubVecPartReg ||
2615 V.isUndef()) &&
2616 "Expecting lowering to have created legal INSERT_SUBVECTORs when "
2617 "the subvector is smaller than a full-sized register");
2618
2619 // If we haven't set a SubRegIdx, then we must be going between
2620 // equally-sized LMUL groups (e.g. VR -> VR). This can be done as a copy.
2621 if (SubRegIdx == RISCV::NoSubRegister) {
2622 unsigned InRegClassID =
2625 InRegClassID &&
2626 "Unexpected subvector extraction");
2627 SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT);
2628 SDNode *NewNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
2629 DL, VT, SubV, RC);
2630 ReplaceNode(Node, NewNode);
2631 return;
2632 }
2633
2634 SDValue Insert = CurDAG->getTargetInsertSubreg(SubRegIdx, DL, VT, V, SubV);
2635 ReplaceNode(Node, Insert.getNode());
2636 return;
2637 }
2639 case RISCVISD::TUPLE_EXTRACT: {
2640 SDValue V = Node->getOperand(0);
2641 auto Idx = Node->getConstantOperandVal(1);
2642 MVT InVT = V.getSimpleValueType();
2643 SDLoc DL(V);
2644
2645 const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering();
2646 MVT SubVecContainerVT = VT;
2647 // Establish the correct scalable-vector types for any fixed-length type.
2648 if (VT.isFixedLengthVector()) {
2649 assert(Idx == 0);
2650 SubVecContainerVT = TLI.getContainerForFixedLengthVector(VT);
2651 }
2652 if (InVT.isFixedLengthVector())
2653 InVT = TLI.getContainerForFixedLengthVector(InVT);
2654
2655 const auto *TRI = Subtarget->getRegisterInfo();
2656 unsigned SubRegIdx;
2657 std::tie(SubRegIdx, Idx) =
2659 InVT, SubVecContainerVT, Idx, TRI);
2660
2661 // If the Idx hasn't been completely eliminated then this is a subvector
2662 // extract which doesn't naturally align to a vector register. These must
2663 // be handled using instructions to manipulate the vector registers.
2664 if (Idx != 0)
2665 break;
2666
2667 // If we haven't set a SubRegIdx, then we must be going between
2668 // equally-sized LMUL types (e.g. VR -> VR). This can be done as a copy.
2669 if (SubRegIdx == RISCV::NoSubRegister) {
2670 unsigned InRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(InVT);
2672 InRegClassID &&
2673 "Unexpected subvector extraction");
2674 SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT);
2675 SDNode *NewNode =
2676 CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
2677 ReplaceNode(Node, NewNode);
2678 return;
2679 }
2680
2681 SDValue Extract = CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, V);
2682 ReplaceNode(Node, Extract.getNode());
2683 return;
2684 }
2685 case RISCVISD::VMV_S_X_VL:
2686 case RISCVISD::VFMV_S_F_VL:
2687 case RISCVISD::VMV_V_X_VL:
2688 case RISCVISD::VFMV_V_F_VL: {
2689 // Try to match splat of a scalar load to a strided load with stride of x0.
2690 bool IsScalarMove = Node->getOpcode() == RISCVISD::VMV_S_X_VL ||
2691 Node->getOpcode() == RISCVISD::VFMV_S_F_VL;
2692 if (!Node->getOperand(0).isUndef())
2693 break;
2694 SDValue Src = Node->getOperand(1);
2695 auto *Ld = dyn_cast<LoadSDNode>(Src);
2696 // Can't fold load update node because the second
2697 // output is used so that load update node can't be removed.
2698 if (!Ld || Ld->isIndexed())
2699 break;
2700 EVT MemVT = Ld->getMemoryVT();
2701 // The memory VT should be the same size as the element type.
2702 if (MemVT.getStoreSize() != VT.getVectorElementType().getStoreSize())
2703 break;
2704 if (!IsProfitableToFold(Src, Node, Node) ||
2705 !IsLegalToFold(Src, Node, Node, TM.getOptLevel()))
2706 break;
2707
2708 SDValue VL;
2709 if (IsScalarMove) {
2710 // We could deal with more VL if we update the VSETVLI insert pass to
2711 // avoid introducing more VSETVLI.
2712 if (!isOneConstant(Node->getOperand(2)))
2713 break;
2714 selectVLOp(Node->getOperand(2), VL);
2715 } else
2716 selectVLOp(Node->getOperand(2), VL);
2717
2718 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2719 SDValue SEW = CurDAG->getTargetConstant(Log2SEW, DL, XLenVT);
2720
2721 // If VL=1, then we don't need to do a strided load and can just do a
2722 // regular load.
2723 bool IsStrided = !isOneConstant(VL);
2724
2725 // Only do a strided load if we have optimized zero-stride vector load.
2726 if (IsStrided && !Subtarget->hasOptimizedZeroStrideLoad())
2727 break;
2728
2730 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT), 0),
2731 Ld->getBasePtr()};
2732 if (IsStrided)
2733 Operands.push_back(CurDAG->getRegister(RISCV::X0, XLenVT));
2735 SDValue PolicyOp = CurDAG->getTargetConstant(Policy, DL, XLenVT);
2736 Operands.append({VL, SEW, PolicyOp, Ld->getChain()});
2737
2739 const RISCV::VLEPseudo *P = RISCV::getVLEPseudo(
2740 /*IsMasked*/ false, IsStrided, /*FF*/ false,
2741 Log2SEW, static_cast<unsigned>(LMUL));
2742 MachineSDNode *Load =
2743 CurDAG->getMachineNode(P->Pseudo, DL, {VT, MVT::Other}, Operands);
2744 // Update the chain.
2745 ReplaceUses(Src.getValue(1), SDValue(Load, 1));
2746 // Record the mem-refs
2747 CurDAG->setNodeMemRefs(Load, {Ld->getMemOperand()});
2748 // Replace the splat with the vlse.
2749 ReplaceNode(Node, Load);
2750 return;
2751 }
2752 case ISD::PREFETCH:
2753 unsigned Locality = Node->getConstantOperandVal(3);
2754 if (Locality > 2)
2755 break;
2756
2757 auto *LoadStoreMem = cast<MemSDNode>(Node);
2758 MachineMemOperand *MMO = LoadStoreMem->getMemOperand();
2760
2761 int NontemporalLevel = 0;
2762 switch (Locality) {
2763 case 0:
2764 NontemporalLevel = 3; // NTL.ALL
2765 break;
2766 case 1:
2767 NontemporalLevel = 1; // NTL.PALL
2768 break;
2769 case 2:
2770 NontemporalLevel = 0; // NTL.P1
2771 break;
2772 default:
2773 llvm_unreachable("unexpected locality value.");
2774 }
2775
2776 if (NontemporalLevel & 0b1)
2778 if (NontemporalLevel & 0b10)
2780 break;
2781 }
2782
2783 // Select the default instruction.
2784 SelectCode(Node);
2785}
2786
2788 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
2789 std::vector<SDValue> &OutOps) {
2790 // Always produce a register and immediate operand, as expected by
2791 // RISCVAsmPrinter::PrintAsmMemoryOperand.
2792 switch (ConstraintID) {
2795 SDValue Op0, Op1;
2796 [[maybe_unused]] bool Found = SelectAddrRegImm(Op, Op0, Op1);
2797 assert(Found && "SelectAddrRegImm should always succeed");
2798 OutOps.push_back(Op0);
2799 OutOps.push_back(Op1);
2800 return false;
2801 }
2803 OutOps.push_back(Op);
2804 OutOps.push_back(
2805 CurDAG->getTargetConstant(0, SDLoc(Op), Subtarget->getXLenVT()));
2806 return false;
2807 default:
2808 report_fatal_error("Unexpected asm memory constraint " +
2809 InlineAsm::getMemConstraintName(ConstraintID));
2810 }
2811
2812 return true;
2813}
2814
2816 SDValue &Offset) {
2817 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2818 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
2819 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT());
2820 return true;
2821 }
2822
2823 return false;
2824}
2825
2826// Fold constant addresses.
2827static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
2828 const MVT VT, const RISCVSubtarget *Subtarget,
2830 bool IsPrefetch = false) {
2831 if (!isa<ConstantSDNode>(Addr))
2832 return false;
2833
2834 int64_t CVal = cast<ConstantSDNode>(Addr)->getSExtValue();
2835
2836 // If the constant is a simm12, we can fold the whole constant and use X0 as
2837 // the base. If the constant can be materialized with LUI+simm12, use LUI as
2838 // the base. We can't use generateInstSeq because it favors LUI+ADDIW.
2839 int64_t Lo12 = SignExtend64<12>(CVal);
2840 int64_t Hi = (uint64_t)CVal - (uint64_t)Lo12;
2841 if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
2842 if (IsPrefetch && (Lo12 & 0b11111) != 0)
2843 return false;
2844 if (Hi) {
2845 int64_t Hi20 = (Hi >> 12) & 0xfffff;
2846 Base = SDValue(
2847 CurDAG->getMachineNode(RISCV::LUI, DL, VT,
2848 CurDAG->getTargetConstant(Hi20, DL, VT)),
2849 0);
2850 } else {
2851 Base = CurDAG->getRegister(RISCV::X0, VT);
2852 }
2853 Offset = CurDAG->getSignedTargetConstant(Lo12, DL, VT);
2854 return true;
2855 }
2856
2857 // Ask how constant materialization would handle this constant.
2858 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(CVal, *Subtarget);
2859
2860 // If the last instruction would be an ADDI, we can fold its immediate and
2861 // emit the rest of the sequence as the base.
2862 if (Seq.back().getOpcode() != RISCV::ADDI)
2863 return false;
2864 Lo12 = Seq.back().getImm();
2865 if (IsPrefetch && (Lo12 & 0b11111) != 0)
2866 return false;
2867
2868 // Drop the last instruction.
2869 Seq.pop_back();
2870 assert(!Seq.empty() && "Expected more instructions in sequence");
2871
2872 Base = selectImmSeq(CurDAG, DL, VT, Seq);
2873 Offset = CurDAG->getSignedTargetConstant(Lo12, DL, VT);
2874 return true;
2875}
2876
2877// Is this ADD instruction only used as the base pointer of scalar loads and
2878// stores?
2880 for (auto *User : Add->users()) {
2881 if (User->getOpcode() != ISD::LOAD && User->getOpcode() != ISD::STORE &&
2882 User->getOpcode() != RISCVISD::LD_RV32 &&
2883 User->getOpcode() != RISCVISD::SD_RV32 &&
2884 User->getOpcode() != ISD::ATOMIC_LOAD &&
2885 User->getOpcode() != ISD::ATOMIC_STORE)
2886 return false;
2887 EVT VT = cast<MemSDNode>(User)->getMemoryVT();
2888 if (!VT.isScalarInteger() && VT != MVT::f16 && VT != MVT::f32 &&
2889 VT != MVT::f64)
2890 return false;
2891 // Don't allow stores of the value. It must be used as the address.
2892 if (User->getOpcode() == ISD::STORE &&
2893 cast<StoreSDNode>(User)->getValue() == Add)
2894 return false;
2895 if (User->getOpcode() == ISD::ATOMIC_STORE &&
2896 cast<AtomicSDNode>(User)->getVal() == Add)
2897 return false;
2898 if (User->getOpcode() == RISCVISD::SD_RV32 &&
2899 (User->getOperand(0) == Add || User->getOperand(1) == Add))
2900 return false;
2901 if (isStrongerThanMonotonic(cast<MemSDNode>(User)->getSuccessOrdering()))
2902 return false;
2903 }
2904
2905 return true;
2906}
2907
2909 switch (User->getOpcode()) {
2910 default:
2911 return false;
2912 case ISD::LOAD:
2913 case RISCVISD::LD_RV32:
2914 case ISD::ATOMIC_LOAD:
2915 break;
2916 case ISD::STORE:
2917 // Don't allow stores of Add. It must only be used as the address.
2918 if (cast<StoreSDNode>(User)->getValue() == Add)
2919 return false;
2920 break;
2921 case RISCVISD::SD_RV32:
2922 // Don't allow stores of Add. It must only be used as the address.
2923 if (User->getOperand(0) == Add || User->getOperand(1) == Add)
2924 return false;
2925 break;
2926 case ISD::ATOMIC_STORE:
2927 // Don't allow stores of Add. It must only be used as the address.
2928 if (cast<AtomicSDNode>(User)->getVal() == Add)
2929 return false;
2930 break;
2931 }
2932
2933 return true;
2934}
2935
2936// To prevent SelectAddrRegImm from folding offsets that conflict with the
2937// fusion of PseudoMovAddr, check if the offset of every use of a given address
2938// is within the alignment.
2940 Align Alignment) {
2941 assert(Addr->getOpcode() == RISCVISD::ADD_LO);
2942 for (auto *User : Addr->users()) {
2943 // If the user is a load or store, then the offset is 0 which is always
2944 // within alignment.
2945 if (isRegImmLoadOrStore(User, Addr))
2946 continue;
2947
2948 if (CurDAG->isBaseWithConstantOffset(SDValue(User, 0))) {
2949 int64_t CVal = cast<ConstantSDNode>(User->getOperand(1))->getSExtValue();
2950 if (!isInt<12>(CVal) || Alignment <= CVal)
2951 return false;
2952
2953 // Make sure all uses are foldable load/stores.
2954 for (auto *AddUser : User->users())
2955 if (!isRegImmLoadOrStore(AddUser, SDValue(User, 0)))
2956 return false;
2957
2958 continue;
2959 }
2960
2961 return false;
2962 }
2963
2964 return true;
2965}
2966
2968 SDValue &Offset) {
2969 if (SelectAddrFrameIndex(Addr, Base, Offset))
2970 return true;
2971
2972 SDLoc DL(Addr);
2973 MVT VT = Addr.getSimpleValueType();
2974
2975 if (Addr.getOpcode() == RISCVISD::ADD_LO) {
2976 bool CanFold = true;
2977 // Unconditionally fold if operand 1 is not a global address (e.g.
2978 // externsymbol)
2979 if (auto *GA = dyn_cast<GlobalAddressSDNode>(Addr.getOperand(1))) {
2980 const DataLayout &DL = CurDAG->getDataLayout();
2981 Align Alignment = commonAlignment(
2982 GA->getGlobal()->getPointerAlignment(DL), GA->getOffset());
2983 if (!areOffsetsWithinAlignment(Addr, Alignment))
2984 CanFold = false;
2985 }
2986 if (CanFold) {
2987 Base = Addr.getOperand(0);
2988 Offset = Addr.getOperand(1);
2989 return true;
2990 }
2991 }
2992
2993 if (CurDAG->isBaseWithConstantOffset(Addr)) {
2994 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2995 if (isInt<12>(CVal)) {
2996 Base = Addr.getOperand(0);
2997 if (Base.getOpcode() == RISCVISD::ADD_LO) {
2998 SDValue LoOperand = Base.getOperand(1);
2999 if (auto *GA = dyn_cast<GlobalAddressSDNode>(LoOperand)) {
3000 // If the Lo in (ADD_LO hi, lo) is a global variable's address
3001 // (its low part, really), then we can rely on the alignment of that
3002 // variable to provide a margin of safety before low part can overflow
3003 // the 12 bits of the load/store offset. Check if CVal falls within
3004 // that margin; if so (low part + CVal) can't overflow.
3005 const DataLayout &DL = CurDAG->getDataLayout();
3006 Align Alignment = commonAlignment(
3007 GA->getGlobal()->getPointerAlignment(DL), GA->getOffset());
3008 if ((CVal == 0 || Alignment > CVal) &&
3009 areOffsetsWithinAlignment(Base, Alignment)) {
3010 int64_t CombinedOffset = CVal + GA->getOffset();
3011 Base = Base.getOperand(0);
3012 Offset = CurDAG->getTargetGlobalAddress(
3013 GA->getGlobal(), SDLoc(LoOperand), LoOperand.getValueType(),
3014 CombinedOffset, GA->getTargetFlags());
3015 return true;
3016 }
3017 }
3018 }
3019
3020 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
3021 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
3022 Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
3023 return true;
3024 }
3025 }
3026
3027 // Handle ADD with large immediates.
3028 if (Addr.getOpcode() == ISD::ADD && isa<ConstantSDNode>(Addr.getOperand(1))) {
3029 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
3030 assert(!isInt<12>(CVal) && "simm12 not already handled?");
3031
3032 // Handle immediates in the range [-4096,-2049] or [2048, 4094]. We can use
3033 // an ADDI for part of the offset and fold the rest into the load/store.
3034 // This mirrors the AddiPair PatFrag in RISCVInstrInfo.td.
3035 if (CVal >= -4096 && CVal <= 4094) {
3036 int64_t Adj = CVal < 0 ? -2048 : 2047;
3037 Base = SDValue(
3038 CurDAG->getMachineNode(RISCV::ADDI, DL, VT, Addr.getOperand(0),
3039 CurDAG->getSignedTargetConstant(Adj, DL, VT)),
3040 0);
3041 Offset = CurDAG->getSignedTargetConstant(CVal - Adj, DL, VT);
3042 return true;
3043 }
3044
3045 // For larger immediates, we might be able to save one instruction from
3046 // constant materialization by folding the Lo12 bits of the immediate into
3047 // the address. We should only do this if the ADD is only used by loads and
3048 // stores that can fold the lo12 bits. Otherwise, the ADD will get iseled
3049 // separately with the full materialized immediate creating extra
3050 // instructions.
3051 if (isWorthFoldingAdd(Addr) &&
3052 selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
3053 Offset, /*IsPrefetch=*/false)) {
3054 // Insert an ADD instruction with the materialized Hi52 bits.
3055 Base = SDValue(
3056 CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
3057 0);
3058 return true;
3059 }
3060 }
3061
3062 if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
3063 /*IsPrefetch=*/false))
3064 return true;
3065
3066 Base = Addr;
3067 Offset = CurDAG->getTargetConstant(0, DL, VT);
3068 return true;
3069}
3070
3071/// Similar to SelectAddrRegImm, except that the offset is restricted to uimm9.
3073 SDValue &Offset) {
3074 if (SelectAddrFrameIndex(Addr, Base, Offset))
3075 return true;
3076
3077 SDLoc DL(Addr);
3078 MVT VT = Addr.getSimpleValueType();
3079
3080 if (CurDAG->isBaseWithConstantOffset(Addr)) {
3081 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
3082 if (isUInt<9>(CVal)) {
3083 Base = Addr.getOperand(0);
3084
3085 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
3086 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
3087 Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
3088 return true;
3089 }
3090 }
3091
3092 Base = Addr;
3093 Offset = CurDAG->getTargetConstant(0, DL, VT);
3094 return true;
3095}
3096
3097/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
3098/// Offset should be all zeros.
3100 SDValue &Offset) {
3101 if (SelectAddrFrameIndex(Addr, Base, Offset))
3102 return true;
3103
3104 SDLoc DL(Addr);
3105 MVT VT = Addr.getSimpleValueType();
3106
3107 if (CurDAG->isBaseWithConstantOffset(Addr)) {
3108 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
3109 if (isInt<12>(CVal)) {
3110 Base = Addr.getOperand(0);
3111
3112 // Early-out if not a valid offset.
3113 if ((CVal & 0b11111) != 0) {
3114 Base = Addr;
3115 Offset = CurDAG->getTargetConstant(0, DL, VT);
3116 return true;
3117 }
3118
3119 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
3120 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
3121 Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
3122 return true;
3123 }
3124 }
3125
3126 // Handle ADD with large immediates.
3127 if (Addr.getOpcode() == ISD::ADD && isa<ConstantSDNode>(Addr.getOperand(1))) {
3128 int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
3129 assert(!isInt<12>(CVal) && "simm12 not already handled?");
3130
3131 // Handle immediates in the range [-4096,-2049] or [2017, 4065]. We can save
3132 // one instruction by folding adjustment (-2048 or 2016) into the address.
3133 if ((-2049 >= CVal && CVal >= -4096) || (4065 >= CVal && CVal >= 2017)) {
3134 int64_t Adj = CVal < 0 ? -2048 : 2016;
3135 int64_t AdjustedOffset = CVal - Adj;
3136 Base =
3137 SDValue(CurDAG->getMachineNode(
3138 RISCV::ADDI, DL, VT, Addr.getOperand(0),
3139 CurDAG->getSignedTargetConstant(AdjustedOffset, DL, VT)),
3140 0);
3141 Offset = CurDAG->getSignedTargetConstant(Adj, DL, VT);
3142 return true;
3143 }
3144
3145 if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr.getOperand(1), Base,
3146 Offset, /*IsPrefetch=*/true)) {
3147 // Insert an ADD instruction with the materialized Hi52 bits.
3148 Base = SDValue(
3149 CurDAG->getMachineNode(RISCV::ADD, DL, VT, Addr.getOperand(0), Base),
3150 0);
3151 return true;
3152 }
3153 }
3154
3155 if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
3156 /*IsPrefetch=*/true))
3157 return true;
3158
3159 Base = Addr;
3160 Offset = CurDAG->getTargetConstant(0, DL, VT);
3161 return true;
3162}
3163
3164/// Return true if this a load/store that we have a RegRegScale instruction for.
3166 const RISCVSubtarget &Subtarget) {
3167 if (User->getOpcode() != ISD::LOAD && User->getOpcode() != ISD::STORE)
3168 return false;
3169 EVT VT = cast<MemSDNode>(User)->getMemoryVT();
3170 if (!(VT.isScalarInteger() &&
3171 (Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls())) &&
3172 !((VT == MVT::f32 || VT == MVT::f64) &&
3173 Subtarget.hasVendorXTHeadFMemIdx()))
3174 return false;
3175 // Don't allow stores of the value. It must be used as the address.
3176 if (User->getOpcode() == ISD::STORE &&
3177 cast<StoreSDNode>(User)->getValue() == Add)
3178 return false;
3179
3180 return true;
3181}
3182
3183/// Is it profitable to fold this Add into RegRegScale load/store. If \p
3184/// Shift is non-null, then we have matched a shl+add. We allow reassociating
3185/// (add (add (shl A C2) B) C1) -> (add (add B C1) (shl A C2)) if there is a
3186/// single addi and we don't have a SHXADD instruction we could use.
3187/// FIXME: May still need to check how many and what kind of users the SHL has.
3189 SDValue Add,
3190 SDValue Shift = SDValue()) {
3191 bool FoundADDI = false;
3192 for (auto *User : Add->users()) {
3193 if (isRegRegScaleLoadOrStore(User, Add, Subtarget))
3194 continue;
3195
3196 // Allow a single ADDI that is used by loads/stores if we matched a shift.
3197 if (!Shift || FoundADDI || User->getOpcode() != ISD::ADD ||
3199 !isInt<12>(cast<ConstantSDNode>(User->getOperand(1))->getSExtValue()))
3200 return false;
3201
3202 FoundADDI = true;
3203
3204 // If we have a SHXADD instruction, prefer that over reassociating an ADDI.
3205 assert(Shift.getOpcode() == ISD::SHL);
3206 unsigned ShiftAmt = Shift.getConstantOperandVal(1);
3207 if ((ShiftAmt <= 3 &&
3208 (Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa())) ||
3209 (ShiftAmt >= 4 && ShiftAmt <= 7 && Subtarget.hasVendorXqciac()))
3210 return false;
3211
3212 // All users of the ADDI should be load/store.
3213 for (auto *ADDIUser : User->users())
3214 if (!isRegRegScaleLoadOrStore(ADDIUser, SDValue(User, 0), Subtarget))
3215 return false;
3216 }
3217
3218 return true;
3219}
3220
3222 unsigned MaxShiftAmount,
3223 SDValue &Base, SDValue &Index,
3224 SDValue &Scale) {
3225 if (Addr.getOpcode() != ISD::ADD)
3226 return false;
3227 SDValue LHS = Addr.getOperand(0);
3228 SDValue RHS = Addr.getOperand(1);
3229
3230 EVT VT = Addr.getSimpleValueType();
3231 auto SelectShl = [this, VT, MaxShiftAmount](SDValue N, SDValue &Index,
3232 SDValue &Shift) {
3233 if (N.getOpcode() != ISD::SHL || !isa<ConstantSDNode>(N.getOperand(1)))
3234 return false;
3235
3236 // Only match shifts by a value in range [0, MaxShiftAmount].
3237 unsigned ShiftAmt = N.getConstantOperandVal(1);
3238 if (ShiftAmt > MaxShiftAmount)
3239 return false;
3240
3241 Index = N.getOperand(0);
3242 Shift = CurDAG->getTargetConstant(ShiftAmt, SDLoc(N), VT);
3243 return true;
3244 };
3245
3246 if (auto *C1 = dyn_cast<ConstantSDNode>(RHS)) {
3247 // (add (add (shl A C2) B) C1) -> (add (add B C1) (shl A C2))
3248 if (LHS.getOpcode() == ISD::ADD &&
3249 !isa<ConstantSDNode>(LHS.getOperand(1)) &&
3250 isInt<12>(C1->getSExtValue())) {
3251 if (SelectShl(LHS.getOperand(1), Index, Scale) &&
3252 isWorthFoldingIntoRegRegScale(*Subtarget, LHS, LHS.getOperand(1))) {
3253 SDValue C1Val = CurDAG->getTargetConstant(*C1->getConstantIntValue(),
3254 SDLoc(Addr), VT);
3255 Base = SDValue(CurDAG->getMachineNode(RISCV::ADDI, SDLoc(Addr), VT,
3256 LHS.getOperand(0), C1Val),
3257 0);
3258 return true;
3259 }
3260
3261 // Add is commutative so we need to check both operands.
3262 if (SelectShl(LHS.getOperand(0), Index, Scale) &&
3263 isWorthFoldingIntoRegRegScale(*Subtarget, LHS, LHS.getOperand(0))) {
3264 SDValue C1Val = CurDAG->getTargetConstant(*C1->getConstantIntValue(),
3265 SDLoc(Addr), VT);
3266 Base = SDValue(CurDAG->getMachineNode(RISCV::ADDI, SDLoc(Addr), VT,
3267 LHS.getOperand(1), C1Val),
3268 0);
3269 return true;
3270 }
3271 }
3272
3273 // Don't match add with constants.
3274 // FIXME: Is this profitable for large constants that have 0s in the lower
3275 // 12 bits that we can materialize with LUI?
3276 return false;
3277 }
3278
3279 // Try to match a shift on the RHS.
3280 if (SelectShl(RHS, Index, Scale)) {
3281 if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr, RHS))
3282 return false;
3283 Base = LHS;
3284 return true;
3285 }
3286
3287 // Try to match a shift on the LHS.
3288 if (SelectShl(LHS, Index, Scale)) {
3289 if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr, LHS))
3290 return false;
3291 Base = RHS;
3292 return true;
3293 }
3294
3295 if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr))
3296 return false;
3297
3298 Base = LHS;
3299 Index = RHS;
3300 Scale = CurDAG->getTargetConstant(0, SDLoc(Addr), VT);
3301 return true;
3302}
3303
3305 unsigned MaxShiftAmount,
3306 unsigned Bits, SDValue &Base,
3307 SDValue &Index,
3308 SDValue &Scale) {
3309 if (!SelectAddrRegRegScale(Addr, MaxShiftAmount, Base, Index, Scale))
3310 return false;
3311
3312 if (Index.getOpcode() == ISD::AND) {
3313 auto *C = dyn_cast<ConstantSDNode>(Index.getOperand(1));
3314 if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) {
3315 Index = Index.getOperand(0);
3316 return true;
3317 }
3318 }
3319
3320 return false;
3321}
3322
3324 SDValue &Offset) {
3325 if (Addr.getOpcode() != ISD::ADD)
3326 return false;
3327
3328 if (isa<ConstantSDNode>(Addr.getOperand(1)))
3329 return false;
3330
3331 Base = Addr.getOperand(0);
3332 Offset = Addr.getOperand(1);
3333 return true;
3334}
3335
3337 SDValue &ShAmt) {
3338 ShAmt = N;
3339
3340 // Peek through zext.
3341 if (ShAmt->getOpcode() == ISD::ZERO_EXTEND)
3342 ShAmt = ShAmt.getOperand(0);
3343
3344 // Shift instructions on RISC-V only read the lower 5 or 6 bits of the shift
3345 // amount. If there is an AND on the shift amount, we can bypass it if it
3346 // doesn't affect any of those bits.
3347 if (ShAmt.getOpcode() == ISD::AND &&
3348 isa<ConstantSDNode>(ShAmt.getOperand(1))) {
3349 const APInt &AndMask = ShAmt.getConstantOperandAPInt(1);
3350
3351 // Since the max shift amount is a power of 2 we can subtract 1 to make a
3352 // mask that covers the bits needed to represent all shift amounts.
3353 assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
3354 APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
3355
3356 if (ShMask.isSubsetOf(AndMask)) {
3357 ShAmt = ShAmt.getOperand(0);
3358 } else {
3359 // SimplifyDemandedBits may have optimized the mask so try restoring any
3360 // bits that are known zero.
3361 KnownBits Known = CurDAG->computeKnownBits(ShAmt.getOperand(0));
3362 if (!ShMask.isSubsetOf(AndMask | Known.Zero))
3363 return true;
3364 ShAmt = ShAmt.getOperand(0);
3365 }
3366 }
3367
3368 if (ShAmt.getOpcode() == ISD::ADD &&
3369 isa<ConstantSDNode>(ShAmt.getOperand(1))) {
3370 uint64_t Imm = ShAmt.getConstantOperandVal(1);
3371 // If we are shifting by X+N where N == 0 mod Size, then just shift by X
3372 // to avoid the ADD.
3373 if (Imm != 0 && Imm % ShiftWidth == 0) {
3374 ShAmt = ShAmt.getOperand(0);
3375 return true;
3376 }
3377 } else if (ShAmt.getOpcode() == ISD::SUB &&
3378 isa<ConstantSDNode>(ShAmt.getOperand(0))) {
3379 uint64_t Imm = ShAmt.getConstantOperandVal(0);
3380 // If we are shifting by N-X where N == 0 mod Size, then just shift by -X to
3381 // generate a NEG instead of a SUB of a constant.
3382 if (Imm != 0 && Imm % ShiftWidth == 0) {
3383 SDLoc DL(ShAmt);
3384 EVT VT = ShAmt.getValueType();
3385 SDValue Zero = CurDAG->getRegister(RISCV::X0, VT);
3386 unsigned NegOpc = VT == MVT::i64 ? RISCV::SUBW : RISCV::SUB;
3387 MachineSDNode *Neg = CurDAG->getMachineNode(NegOpc, DL, VT, Zero,
3388 ShAmt.getOperand(1));
3389 ShAmt = SDValue(Neg, 0);
3390 return true;
3391 }
3392 // If we are shifting by N-X where N == -1 mod Size, then just shift by ~X
3393 // to generate a NOT instead of a SUB of a constant.
3394 if (Imm % ShiftWidth == ShiftWidth - 1) {
3395 SDLoc DL(ShAmt);
3396 EVT VT = ShAmt.getValueType();
3397 MachineSDNode *Not = CurDAG->getMachineNode(
3398 RISCV::XORI, DL, VT, ShAmt.getOperand(1),
3399 CurDAG->getAllOnesConstant(DL, VT, /*isTarget=*/true));
3400 ShAmt = SDValue(Not, 0);
3401 return true;
3402 }
3403 }
3404
3405 return true;
3406}
3407
3408/// RISC-V doesn't have general instructions for integer setne/seteq, but we can
3409/// check for equality with 0. This function emits instructions that convert the
3410/// seteq/setne into something that can be compared with 0.
3411/// \p ExpectedCCVal indicates the condition code to attempt to match (e.g.
3412/// ISD::SETNE).
3414 SDValue &Val) {
3415 assert(ISD::isIntEqualitySetCC(ExpectedCCVal) &&
3416 "Unexpected condition code!");
3417
3418 // We're looking for a setcc.
3419 if (N->getOpcode() != ISD::SETCC)
3420 return false;
3421
3422 // Must be an equality comparison.
3423 ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
3424 if (CCVal != ExpectedCCVal)
3425 return false;
3426
3427 SDValue LHS = N->getOperand(0);
3428 SDValue RHS = N->getOperand(1);
3429
3430 if (!LHS.getValueType().isScalarInteger())
3431 return false;
3432
3433 // If the RHS side is 0, we don't need any extra instructions, return the LHS.
3434 if (isNullConstant(RHS)) {
3435 Val = LHS;
3436 return true;
3437 }
3438
3439 SDLoc DL(N);
3440
3441 if (auto *C = dyn_cast<ConstantSDNode>(RHS)) {
3442 int64_t CVal = C->getSExtValue();
3443 // If the RHS is -2048, we can use xori to produce 0 if the LHS is -2048 and
3444 // non-zero otherwise.
3445 if (CVal == -2048) {
3446 Val = SDValue(
3447 CurDAG->getMachineNode(
3448 RISCV::XORI, DL, N->getValueType(0), LHS,
3449 CurDAG->getSignedTargetConstant(CVal, DL, N->getValueType(0))),
3450 0);
3451 return true;
3452 }
3453 // If the RHS is [-2047,2048], we can use addi with -RHS to produce 0 if the
3454 // LHS is equal to the RHS and non-zero otherwise.
3455 if (isInt<12>(CVal) || CVal == 2048) {
3456 Val = SDValue(
3457 CurDAG->getMachineNode(
3458 RISCV::ADDI, DL, N->getValueType(0), LHS,
3459 CurDAG->getSignedTargetConstant(-CVal, DL, N->getValueType(0))),
3460 0);
3461 return true;
3462 }
3463 if (isPowerOf2_64(CVal) && Subtarget->hasStdExtZbs()) {
3464 Val = SDValue(
3465 CurDAG->getMachineNode(
3466 RISCV::BINVI, DL, N->getValueType(0), LHS,
3467 CurDAG->getTargetConstant(Log2_64(CVal), DL, N->getValueType(0))),
3468 0);
3469 return true;
3470 }
3471 // Same as the addi case above but for larger immediates (signed 26-bit) use
3472 // the QC_E_ADDI instruction from the Xqcilia extension, if available. Avoid
3473 // anything which can be done with a single lui as it might be compressible.
3474 if (Subtarget->hasVendorXqcilia() && isInt<26>(CVal) &&
3475 (CVal & 0xFFF) != 0) {
3476 Val = SDValue(
3477 CurDAG->getMachineNode(
3478 RISCV::QC_E_ADDI, DL, N->getValueType(0), LHS,
3479 CurDAG->getSignedTargetConstant(-CVal, DL, N->getValueType(0))),
3480 0);
3481 return true;
3482 }
3483 }
3484
3485 // If nothing else we can XOR the LHS and RHS to produce zero if they are
3486 // equal and a non-zero value if they aren't.
3487 Val = SDValue(
3488 CurDAG->getMachineNode(RISCV::XOR, DL, N->getValueType(0), LHS, RHS), 0);
3489 return true;
3490}
3491
3493 if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
3494 cast<VTSDNode>(N.getOperand(1))->getVT().getSizeInBits() == Bits) {
3495 Val = N.getOperand(0);
3496 return true;
3497 }
3498
3499 auto UnwrapShlSra = [](SDValue N, unsigned ShiftAmt) {
3500 if (N.getOpcode() != ISD::SRA || !isa<ConstantSDNode>(N.getOperand(1)))
3501 return N;
3502
3503 SDValue N0 = N.getOperand(0);
3504 if (N0.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N0.getOperand(1)) &&
3505 N.getConstantOperandVal(1) == ShiftAmt &&
3506 N0.getConstantOperandVal(1) == ShiftAmt)
3507 return N0.getOperand(0);
3508
3509 return N;
3510 };
3511
3512 MVT VT = N.getSimpleValueType();
3513 if (CurDAG->ComputeNumSignBits(N) > (VT.getSizeInBits() - Bits)) {
3514 Val = UnwrapShlSra(N, VT.getSizeInBits() - Bits);
3515 return true;
3516 }
3517
3518 return false;
3519}
3520
3522 if (N.getOpcode() == ISD::AND) {
3523 auto *C = dyn_cast<ConstantSDNode>(N.getOperand(1));
3524 if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) {
3525 Val = N.getOperand(0);
3526 return true;
3527 }
3528 }
3529 MVT VT = N.getSimpleValueType();
3530 APInt Mask = APInt::getBitsSetFrom(VT.getSizeInBits(), Bits);
3531 if (CurDAG->MaskedValueIsZero(N, Mask)) {
3532 Val = N;
3533 return true;
3534 }
3535
3536 return false;
3537}
3538
3539/// Look for various patterns that can be done with a SHL that can be folded
3540/// into a SHXADD. \p ShAmt contains 1, 2, or 3 and is set based on which
3541/// SHXADD we are trying to match.
3543 SDValue &Val) {
3544 if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) {
3545 SDValue N0 = N.getOperand(0);
3546
3547 if (bool LeftShift = N0.getOpcode() == ISD::SHL;
3548 (LeftShift || N0.getOpcode() == ISD::SRL) &&
3550 uint64_t Mask = N.getConstantOperandVal(1);
3551 unsigned C2 = N0.getConstantOperandVal(1);
3552
3553 unsigned XLen = Subtarget->getXLen();
3554 if (LeftShift)
3555 Mask &= maskTrailingZeros<uint64_t>(C2);
3556 else
3557 Mask &= maskTrailingOnes<uint64_t>(XLen - C2);
3558
3559 if (isShiftedMask_64(Mask)) {
3560 unsigned Leading = XLen - llvm::bit_width(Mask);
3561 unsigned Trailing = llvm::countr_zero(Mask);
3562 if (Trailing != ShAmt)
3563 return false;
3564
3565 unsigned Opcode;
3566 // Look for (and (shl y, c2), c1) where c1 is a shifted mask with no
3567 // leading zeros and c3 trailing zeros. We can use an SRLI by c3-c2
3568 // followed by a SHXADD with c3 for the X amount.
3569 if (LeftShift && Leading == 0 && C2 < Trailing)
3570 Opcode = RISCV::SRLI;
3571 // Look for (and (shl y, c2), c1) where c1 is a shifted mask with 32-c2
3572 // leading zeros and c3 trailing zeros. We can use an SRLIW by c3-c2
3573 // followed by a SHXADD with c3 for the X amount.
3574 else if (LeftShift && Leading == 32 - C2 && C2 < Trailing)
3575 Opcode = RISCV::SRLIW;
3576 // Look for (and (shr y, c2), c1) where c1 is a shifted mask with c2
3577 // leading zeros and c3 trailing zeros. We can use an SRLI by c2+c3
3578 // followed by a SHXADD using c3 for the X amount.
3579 else if (!LeftShift && Leading == C2)
3580 Opcode = RISCV::SRLI;
3581 // Look for (and (shr y, c2), c1) where c1 is a shifted mask with 32+c2
3582 // leading zeros and c3 trailing zeros. We can use an SRLIW by c2+c3
3583 // followed by a SHXADD using c3 for the X amount.
3584 else if (!LeftShift && Leading == 32 + C2)
3585 Opcode = RISCV::SRLIW;
3586 else
3587 return false;
3588
3589 SDLoc DL(N);
3590 EVT VT = N.getValueType();
3591 ShAmt = LeftShift ? Trailing - C2 : Trailing + C2;
3592 Val = SDValue(
3593 CurDAG->getMachineNode(Opcode, DL, VT, N0.getOperand(0),
3594 CurDAG->getTargetConstant(ShAmt, DL, VT)),
3595 0);
3596 return true;
3597 }
3598 } else if (N0.getOpcode() == ISD::SRA && N0.hasOneUse() &&
3600 uint64_t Mask = N.getConstantOperandVal(1);
3601 unsigned C2 = N0.getConstantOperandVal(1);
3602
3603 // Look for (and (sra y, c2), c1) where c1 is a shifted mask with c3
3604 // leading zeros and c4 trailing zeros. If c2 is greater than c3, we can
3605 // use (srli (srai y, c2 - c3), c3 + c4) followed by a SHXADD with c4 as
3606 // the X amount.
3607 if (isShiftedMask_64(Mask)) {
3608 unsigned XLen = Subtarget->getXLen();
3609 unsigned Leading = XLen - llvm::bit_width(Mask);
3610 unsigned Trailing = llvm::countr_zero(Mask);
3611 if (C2 > Leading && Leading > 0 && Trailing == ShAmt) {
3612 SDLoc DL(N);
3613 EVT VT = N.getValueType();
3614 Val = SDValue(CurDAG->getMachineNode(
3615 RISCV::SRAI, DL, VT, N0.getOperand(0),
3616 CurDAG->getTargetConstant(C2 - Leading, DL, VT)),
3617 0);
3618 Val = SDValue(CurDAG->getMachineNode(
3619 RISCV::SRLI, DL, VT, Val,
3620 CurDAG->getTargetConstant(Leading + ShAmt, DL, VT)),
3621 0);
3622 return true;
3623 }
3624 }
3625 }
3626 } else if (bool LeftShift = N.getOpcode() == ISD::SHL;
3627 (LeftShift || N.getOpcode() == ISD::SRL) &&
3628 isa<ConstantSDNode>(N.getOperand(1))) {
3629 SDValue N0 = N.getOperand(0);
3630 if (N0.getOpcode() == ISD::AND && N0.hasOneUse() &&
3632 uint64_t Mask = N0.getConstantOperandVal(1);
3633 if (isShiftedMask_64(Mask)) {
3634 unsigned C1 = N.getConstantOperandVal(1);
3635 unsigned XLen = Subtarget->getXLen();
3636 unsigned Leading = XLen - llvm::bit_width(Mask);
3637 unsigned Trailing = llvm::countr_zero(Mask);
3638 // Look for (shl (and X, Mask), C1) where Mask has 32 leading zeros and
3639 // C3 trailing zeros. If C1+C3==ShAmt we can use SRLIW+SHXADD.
3640 if (LeftShift && Leading == 32 && Trailing > 0 &&
3641 (Trailing + C1) == ShAmt) {
3642 SDLoc DL(N);
3643 EVT VT = N.getValueType();
3644 Val = SDValue(CurDAG->getMachineNode(
3645 RISCV::SRLIW, DL, VT, N0.getOperand(0),
3646 CurDAG->getTargetConstant(Trailing, DL, VT)),
3647 0);
3648 return true;
3649 }
3650 // Look for (srl (and X, Mask), C1) where Mask has 32 leading zeros and
3651 // C3 trailing zeros. If C3-C1==ShAmt we can use SRLIW+SHXADD.
3652 if (!LeftShift && Leading == 32 && Trailing > C1 &&
3653 (Trailing - C1) == ShAmt) {
3654 SDLoc DL(N);
3655 EVT VT = N.getValueType();
3656 Val = SDValue(CurDAG->getMachineNode(
3657 RISCV::SRLIW, DL, VT, N0.getOperand(0),
3658 CurDAG->getTargetConstant(Trailing, DL, VT)),
3659 0);
3660 return true;
3661 }
3662 }
3663 }
3664 }
3665
3666 return false;
3667}
3668
3669/// Look for various patterns that can be done with a SHL that can be folded
3670/// into a SHXADD_UW. \p ShAmt contains 1, 2, or 3 and is set based on which
3671/// SHXADD_UW we are trying to match.
3673 SDValue &Val) {
3674 if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1)) &&
3675 N.hasOneUse()) {
3676 SDValue N0 = N.getOperand(0);
3677 if (N0.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N0.getOperand(1)) &&
3678 N0.hasOneUse()) {
3679 uint64_t Mask = N.getConstantOperandVal(1);
3680 unsigned C2 = N0.getConstantOperandVal(1);
3681
3682 Mask &= maskTrailingZeros<uint64_t>(C2);
3683
3684 // Look for (and (shl y, c2), c1) where c1 is a shifted mask with
3685 // 32-ShAmt leading zeros and c2 trailing zeros. We can use SLLI by
3686 // c2-ShAmt followed by SHXADD_UW with ShAmt for the X amount.
3687 if (isShiftedMask_64(Mask)) {
3688 unsigned Leading = llvm::countl_zero(Mask);
3689 unsigned Trailing = llvm::countr_zero(Mask);
3690 if (Leading == 32 - ShAmt && Trailing == C2 && Trailing > ShAmt) {
3691 SDLoc DL(N);
3692 EVT VT = N.getValueType();
3693 Val = SDValue(CurDAG->getMachineNode(
3694 RISCV::SLLI, DL, VT, N0.getOperand(0),
3695 CurDAG->getTargetConstant(C2 - ShAmt, DL, VT)),
3696 0);
3697 return true;
3698 }
3699 }
3700 }
3701 }
3702
3703 return false;
3704}
3705
3707 assert(N->getOpcode() == ISD::OR || N->getOpcode() == RISCVISD::OR_VL);
3708 if (N->getFlags().hasDisjoint())
3709 return true;
3710 return CurDAG->haveNoCommonBitsSet(N->getOperand(0), N->getOperand(1));
3711}
3712
3713bool RISCVDAGToDAGISel::selectImm64IfCheaper(int64_t Imm, int64_t OrigImm,
3714 SDValue N, SDValue &Val) {
3715 int OrigCost = RISCVMatInt::getIntMatCost(APInt(64, OrigImm), 64, *Subtarget,
3716 /*CompressionCost=*/true);
3717 int Cost = RISCVMatInt::getIntMatCost(APInt(64, Imm), 64, *Subtarget,
3718 /*CompressionCost=*/true);
3719 if (OrigCost <= Cost)
3720 return false;
3721
3722 Val = selectImm(CurDAG, SDLoc(N), N->getSimpleValueType(0), Imm, *Subtarget);
3723 return true;
3724}
3725
3727 if (!isa<ConstantSDNode>(N))
3728 return false;
3729 int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
3730 if ((Imm >> 31) != 1)
3731 return false;
3732
3733 for (const SDNode *U : N->users()) {
3734 switch (U->getOpcode()) {
3735 case ISD::ADD:
3736 break;
3737 case ISD::OR:
3738 if (orDisjoint(U))
3739 break;
3740 return false;
3741 default:
3742 return false;
3743 }
3744 }
3745
3746 return selectImm64IfCheaper(0xffffffff00000000 | Imm, Imm, N, Val);
3747}
3748
3750 if (!isa<ConstantSDNode>(N))
3751 return false;
3752 int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
3753 if (isInt<32>(Imm))
3754 return false;
3755
3756 for (const SDNode *U : N->users()) {
3757 switch (U->getOpcode()) {
3758 case ISD::ADD:
3759 break;
3760 case RISCVISD::VMV_V_X_VL:
3761 if (!all_of(U->users(), [](const SDNode *V) {
3762 return V->getOpcode() == ISD::ADD ||
3763 V->getOpcode() == RISCVISD::ADD_VL;
3764 }))
3765 return false;
3766 break;
3767 default:
3768 return false;
3769 }
3770 }
3771
3772 return selectImm64IfCheaper(-Imm, Imm, N, Val);
3773}
3774
3776 if (!isa<ConstantSDNode>(N))
3777 return false;
3778 int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
3779
3780 // For 32-bit signed constants, we can only substitute LUI+ADDI with LUI.
3781 if (isInt<32>(Imm) && ((Imm & 0xfff) != 0xfff || Imm == -1))
3782 return false;
3783
3784 // Abandon this transform if the constant is needed elsewhere.
3785 for (const SDNode *U : N->users()) {
3786 switch (U->getOpcode()) {
3787 case ISD::AND:
3788 case ISD::OR:
3789 case ISD::XOR:
3790 if (!(Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbkb()))
3791 return false;
3792 break;
3793 case RISCVISD::VMV_V_X_VL:
3794 if (!Subtarget->hasStdExtZvkb())
3795 return false;
3796 if (!all_of(U->users(), [](const SDNode *V) {
3797 return V->getOpcode() == ISD::AND ||
3798 V->getOpcode() == RISCVISD::AND_VL;
3799 }))
3800 return false;
3801 break;
3802 default:
3803 return false;
3804 }
3805 }
3806
3807 if (isInt<32>(Imm)) {
3808 Val =
3809 selectImm(CurDAG, SDLoc(N), N->getSimpleValueType(0), ~Imm, *Subtarget);
3810 return true;
3811 }
3812
3813 // For 64-bit constants, the instruction sequences get complex,
3814 // so we select inverted only if it's cheaper.
3815 return selectImm64IfCheaper(~Imm, Imm, N, Val);
3816}
3817
3818static bool vectorPseudoHasAllNBitUsers(SDNode *User, unsigned UserOpNo,
3819 unsigned Bits,
3820 const TargetInstrInfo *TII) {
3821 unsigned MCOpcode = RISCV::getRVVMCOpcode(User->getMachineOpcode());
3822
3823 if (!MCOpcode)
3824 return false;
3825
3826 const MCInstrDesc &MCID = TII->get(User->getMachineOpcode());
3827 const uint64_t TSFlags = MCID.TSFlags;
3828 if (!RISCVII::hasSEWOp(TSFlags))
3829 return false;
3830 assert(RISCVII::hasVLOp(TSFlags));
3831
3832 unsigned ChainOpIdx = User->getNumOperands() - 1;
3833 bool HasChainOp = User->getOperand(ChainOpIdx).getValueType() == MVT::Other;
3834 bool HasVecPolicyOp = RISCVII::hasVecPolicyOp(TSFlags);
3835 unsigned VLIdx = User->getNumOperands() - HasVecPolicyOp - HasChainOp - 2;
3836 const unsigned Log2SEW = User->getConstantOperandVal(VLIdx + 1);
3837
3838 if (UserOpNo == VLIdx)
3839 return false;
3840
3841 auto NumDemandedBits =
3842 RISCV::getVectorLowDemandedScalarBits(MCOpcode, Log2SEW);
3843 return NumDemandedBits && Bits >= *NumDemandedBits;
3844}
3845
3846// Return true if all users of this SDNode* only consume the lower \p Bits.
3847// This can be used to form W instructions for add/sub/mul/shl even when the
3848// root isn't a sext_inreg. This can allow the ADDW/SUBW/MULW/SLLIW to CSE if
3849// SimplifyDemandedBits has made it so some users see a sext_inreg and some
3850// don't. The sext_inreg+add/sub/mul/shl will get selected, but still leave
3851// the add/sub/mul/shl to become non-W instructions. By checking the users we
3852// may be able to use a W instruction and CSE with the other instruction if
3853// this has happened. We could try to detect that the CSE opportunity exists
3854// before doing this, but that would be more complicated.
3856 const unsigned Depth) const {
3857 assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB ||
3858 Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL ||
3859 Node->getOpcode() == ISD::SRL || Node->getOpcode() == ISD::AND ||
3860 Node->getOpcode() == ISD::OR || Node->getOpcode() == ISD::XOR ||
3861 Node->getOpcode() == ISD::SIGN_EXTEND_INREG ||
3862 isa<ConstantSDNode>(Node) || Depth != 0) &&
3863 "Unexpected opcode");
3864
3866 return false;
3867
3868 // The PatFrags that call this may run before RISCVGenDAGISel.inc has checked
3869 // the VT. Ensure the type is scalar to avoid wasting time on vectors.
3870 if (Depth == 0 && !Node->getValueType(0).isScalarInteger())
3871 return false;
3872
3873 for (SDUse &Use : Node->uses()) {
3874 SDNode *User = Use.getUser();
3875 // Users of this node should have already been instruction selected
3876 if (!User->isMachineOpcode())
3877 return false;
3878
3879 // TODO: Add more opcodes?
3880 switch (User->getMachineOpcode()) {
3881 default:
3883 break;
3884 return false;
3885 case RISCV::ADDW:
3886 case RISCV::ADDIW:
3887 case RISCV::SUBW:
3888 case RISCV::MULW:
3889 case RISCV::SLLW:
3890 case RISCV::SLLIW:
3891 case RISCV::SRAW:
3892 case RISCV::SRAIW:
3893 case RISCV::SRLW:
3894 case RISCV::SRLIW:
3895 case RISCV::DIVW:
3896 case RISCV::DIVUW:
3897 case RISCV::REMW:
3898 case RISCV::REMUW:
3899 case RISCV::ROLW:
3900 case RISCV::RORW:
3901 case RISCV::RORIW:
3902 case RISCV::CLZW:
3903 case RISCV::CTZW:
3904 case RISCV::CPOPW:
3905 case RISCV::SLLI_UW:
3906 case RISCV::FMV_W_X:
3907 case RISCV::FCVT_H_W:
3908 case RISCV::FCVT_H_W_INX:
3909 case RISCV::FCVT_H_WU:
3910 case RISCV::FCVT_H_WU_INX:
3911 case RISCV::FCVT_S_W:
3912 case RISCV::FCVT_S_W_INX:
3913 case RISCV::FCVT_S_WU:
3914 case RISCV::FCVT_S_WU_INX:
3915 case RISCV::FCVT_D_W:
3916 case RISCV::FCVT_D_W_INX:
3917 case RISCV::FCVT_D_WU:
3918 case RISCV::FCVT_D_WU_INX:
3919 case RISCV::TH_REVW:
3920 case RISCV::TH_SRRIW:
3921 if (Bits >= 32)
3922 break;
3923 return false;
3924 case RISCV::SLL:
3925 case RISCV::SRA:
3926 case RISCV::SRL:
3927 case RISCV::ROL:
3928 case RISCV::ROR:
3929 case RISCV::BSET:
3930 case RISCV::BCLR:
3931 case RISCV::BINV:
3932 // Shift amount operands only use log2(Xlen) bits.
3933 if (Use.getOperandNo() == 1 && Bits >= Log2_32(Subtarget->getXLen()))
3934 break;
3935 return false;
3936 case RISCV::SLLI:
3937 // SLLI only uses the lower (XLen - ShAmt) bits.
3938 if (Bits >= Subtarget->getXLen() - User->getConstantOperandVal(1))
3939 break;
3940 return false;
3941 case RISCV::ANDI:
3942 if (Bits >= (unsigned)llvm::bit_width(User->getConstantOperandVal(1)))
3943 break;
3944 goto RecCheck;
3945 case RISCV::ORI: {
3946 uint64_t Imm = cast<ConstantSDNode>(User->getOperand(1))->getSExtValue();
3947 if (Bits >= (unsigned)llvm::bit_width<uint64_t>(~Imm))
3948 break;
3949 [[fallthrough]];
3950 }
3951 case RISCV::AND:
3952 case RISCV::OR:
3953 case RISCV::XOR:
3954 case RISCV::XORI:
3955 case RISCV::ANDN:
3956 case RISCV::ORN:
3957 case RISCV::XNOR:
3958 case RISCV::SH1ADD:
3959 case RISCV::SH2ADD:
3960 case RISCV::SH3ADD:
3961 RecCheck:
3962 if (hasAllNBitUsers(User, Bits, Depth + 1))
3963 break;
3964 return false;
3965 case RISCV::SRLI: {
3966 unsigned ShAmt = User->getConstantOperandVal(1);
3967 // If we are shifting right by less than Bits, and users don't demand any
3968 // bits that were shifted into [Bits-1:0], then we can consider this as an
3969 // N-Bit user.
3970 if (Bits > ShAmt && hasAllNBitUsers(User, Bits - ShAmt, Depth + 1))
3971 break;
3972 return false;
3973 }
3974 case RISCV::SEXT_B:
3975 case RISCV::PACKH:
3976 if (Bits >= 8)
3977 break;
3978 return false;
3979 case RISCV::SEXT_H:
3980 case RISCV::FMV_H_X:
3981 case RISCV::ZEXT_H_RV32:
3982 case RISCV::ZEXT_H_RV64:
3983 case RISCV::PACKW:
3984 if (Bits >= 16)
3985 break;
3986 return false;
3987 case RISCV::PACK:
3988 if (Bits >= (Subtarget->getXLen() / 2))
3989 break;
3990 return false;
3991 case RISCV::ADD_UW:
3992 case RISCV::SH1ADD_UW:
3993 case RISCV::SH2ADD_UW:
3994 case RISCV::SH3ADD_UW:
3995 // The first operand to add.uw/shXadd.uw is implicitly zero extended from
3996 // 32 bits.
3997 if (Use.getOperandNo() == 0 && Bits >= 32)
3998 break;
3999 return false;
4000 case RISCV::SB:
4001 if (Use.getOperandNo() == 0 && Bits >= 8)
4002 break;
4003 return false;
4004 case RISCV::SH:
4005 if (Use.getOperandNo() == 0 && Bits >= 16)
4006 break;
4007 return false;
4008 case RISCV::SW:
4009 if (Use.getOperandNo() == 0 && Bits >= 32)
4010 break;
4011 return false;
4012 case RISCV::TH_EXT:
4013 case RISCV::TH_EXTU: {
4014 unsigned Msb = User->getConstantOperandVal(1);
4015 unsigned Lsb = User->getConstantOperandVal(2);
4016 // Behavior of Msb < Lsb is not well documented.
4017 if (Msb >= Lsb && Bits > Msb)
4018 break;
4019 return false;
4020 }
4021 }
4022 }
4023
4024 return true;
4025}
4026
4027// Select a constant that can be represented as (sign_extend(imm5) << imm2).
4029 SDValue &Shl2) {
4030 auto *C = dyn_cast<ConstantSDNode>(N);
4031 if (!C)
4032 return false;
4033
4034 int64_t Offset = C->getSExtValue();
4035 for (unsigned Shift = 0; Shift < 4; Shift++) {
4036 if (isInt<5>(Offset >> Shift) && ((Offset % (1LL << Shift)) == 0)) {
4037 EVT VT = N->getValueType(0);
4038 Simm5 = CurDAG->getSignedTargetConstant(Offset >> Shift, SDLoc(N), VT);
4039 Shl2 = CurDAG->getTargetConstant(Shift, SDLoc(N), VT);
4040 return true;
4041 }
4042 }
4043
4044 return false;
4045}
4046
4047// Select VL as a 5 bit immediate or a value that will become a register. This
4048// allows us to choose between VSETIVLI or VSETVLI later.
4050 auto *C = dyn_cast<ConstantSDNode>(N);
4051 if (C && isUInt<5>(C->getZExtValue())) {
4052 VL = CurDAG->getTargetConstant(C->getZExtValue(), SDLoc(N),
4053 N->getValueType(0));
4054 } else if (C && C->isAllOnes()) {
4055 // Treat all ones as VLMax.
4056 VL = CurDAG->getSignedTargetConstant(RISCV::VLMaxSentinel, SDLoc(N),
4057 N->getValueType(0));
4058 } else if (isa<RegisterSDNode>(N) &&
4059 cast<RegisterSDNode>(N)->getReg() == RISCV::X0) {
4060 // All our VL operands use an operand that allows GPRNoX0 or an immediate
4061 // as the register class. Convert X0 to a special immediate to pass the
4062 // MachineVerifier. This is recognized specially by the vsetvli insertion
4063 // pass.
4064 VL = CurDAG->getSignedTargetConstant(RISCV::VLMaxSentinel, SDLoc(N),
4065 N->getValueType(0));
4066 } else {
4067 VL = N;
4068 }
4069
4070 return true;
4071}
4072
4074 if (N.getOpcode() == ISD::INSERT_SUBVECTOR) {
4075 if (!N.getOperand(0).isUndef())
4076 return SDValue();
4077 N = N.getOperand(1);
4078 }
4079 SDValue Splat = N;
4080 if ((Splat.getOpcode() != RISCVISD::VMV_V_X_VL &&
4081 Splat.getOpcode() != RISCVISD::VMV_S_X_VL) ||
4082 !Splat.getOperand(0).isUndef())
4083 return SDValue();
4084 assert(Splat.getNumOperands() == 3 && "Unexpected number of operands");
4085 return Splat;
4086}
4087
4090 if (!Splat)
4091 return false;
4092
4093 SplatVal = Splat.getOperand(1);
4094 return true;
4095}
4096
4098 SelectionDAG &DAG,
4099 const RISCVSubtarget &Subtarget,
4100 std::function<bool(int64_t)> ValidateImm,
4101 bool Decrement = false) {
4103 if (!Splat || !isa<ConstantSDNode>(Splat.getOperand(1)))
4104 return false;
4105
4106 const unsigned SplatEltSize = Splat.getScalarValueSizeInBits();
4107 assert(Subtarget.getXLenVT() == Splat.getOperand(1).getSimpleValueType() &&
4108 "Unexpected splat operand type");
4109
4110 // The semantics of RISCVISD::VMV_V_X_VL is that when the operand
4111 // type is wider than the resulting vector element type: an implicit
4112 // truncation first takes place. Therefore, perform a manual
4113 // truncation/sign-extension in order to ignore any truncated bits and catch
4114 // any zero-extended immediate.
4115 // For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first
4116 // sign-extending to (XLenVT -1).
4117 APInt SplatConst = Splat.getConstantOperandAPInt(1).sextOrTrunc(SplatEltSize);
4118
4119 int64_t SplatImm = SplatConst.getSExtValue();
4120
4121 if (!ValidateImm(SplatImm))
4122 return false;
4123
4124 if (Decrement)
4125 SplatImm -= 1;
4126
4127 SplatVal =
4128 DAG.getSignedTargetConstant(SplatImm, SDLoc(N), Subtarget.getXLenVT());
4129 return true;
4130}
4131
4133 return selectVSplatImmHelper(N, SplatVal, *CurDAG, *Subtarget,
4134 [](int64_t Imm) { return isInt<5>(Imm); });
4135}
4136
4138 return selectVSplatImmHelper(
4139 N, SplatVal, *CurDAG, *Subtarget,
4140 [](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; },
4141 /*Decrement=*/true);
4142}
4143
4145 return selectVSplatImmHelper(
4146 N, SplatVal, *CurDAG, *Subtarget,
4147 [](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; },
4148 /*Decrement=*/false);
4149}
4150
4152 SDValue &SplatVal) {
4153 return selectVSplatImmHelper(
4154 N, SplatVal, *CurDAG, *Subtarget,
4155 [](int64_t Imm) {
4156 return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16);
4157 },
4158 /*Decrement=*/true);
4159}
4160
4162 SDValue &SplatVal) {
4163 return selectVSplatImmHelper(
4164 N, SplatVal, *CurDAG, *Subtarget,
4165 [Bits](int64_t Imm) { return isUIntN(Bits, Imm); });
4166}
4167
4170 return Splat && selectNegImm(Splat.getOperand(1), SplatVal);
4171}
4172
4174 auto IsExtOrTrunc = [](SDValue N) {
4175 switch (N->getOpcode()) {
4176 case ISD::SIGN_EXTEND:
4177 case ISD::ZERO_EXTEND:
4178 // There's no passthru on these _VL nodes so any VL/mask is ok, since any
4179 // inactive elements will be undef.
4180 case RISCVISD::TRUNCATE_VECTOR_VL:
4181 case RISCVISD::VSEXT_VL:
4182 case RISCVISD::VZEXT_VL:
4183 return true;
4184 default:
4185 return false;
4186 }
4187 };
4188
4189 // We can have multiple nested nodes, so unravel them all if needed.
4190 while (IsExtOrTrunc(N)) {
4191 if (!N.hasOneUse() || N.getScalarValueSizeInBits() < 8)
4192 return false;
4193 N = N->getOperand(0);
4194 }
4195
4196 return selectVSplat(N, SplatVal);
4197}
4198
4200 // Allow bitcasts from XLenVT -> FP.
4201 if (N.getOpcode() == ISD::BITCAST &&
4202 N.getOperand(0).getValueType() == Subtarget->getXLenVT()) {
4203 Imm = N.getOperand(0);
4204 return true;
4205 }
4206 // Allow moves from XLenVT to FP.
4207 if (N.getOpcode() == RISCVISD::FMV_H_X ||
4208 N.getOpcode() == RISCVISD::FMV_W_X_RV64) {
4209 Imm = N.getOperand(0);
4210 return true;
4211 }
4212
4213 // Otherwise, look for FP constants that can materialized with scalar int.
4215 if (!CFP)
4216 return false;
4217 const APFloat &APF = CFP->getValueAPF();
4218 // td can handle +0.0 already.
4219 if (APF.isPosZero())
4220 return false;
4221
4222 MVT VT = CFP->getSimpleValueType(0);
4223
4224 MVT XLenVT = Subtarget->getXLenVT();
4225 if (VT == MVT::f64 && !Subtarget->is64Bit()) {
4226 assert(APF.isNegZero() && "Unexpected constant.");
4227 return false;
4228 }
4229 SDLoc DL(N);
4230 Imm = selectImm(CurDAG, DL, XLenVT, APF.bitcastToAPInt().getSExtValue(),
4231 *Subtarget);
4232 return true;
4233}
4234
4236 SDValue &Imm) {
4237 if (auto *C = dyn_cast<ConstantSDNode>(N)) {
4238 int64_t ImmVal = SignExtend64(C->getSExtValue(), Width);
4239
4240 if (!isInt<5>(ImmVal))
4241 return false;
4242
4243 Imm = CurDAG->getSignedTargetConstant(ImmVal, SDLoc(N),
4244 Subtarget->getXLenVT());
4245 return true;
4246 }
4247
4248 return false;
4249}
4250
4251// Try to remove sext.w if the input is a W instruction or can be made into
4252// a W instruction cheaply.
4253bool RISCVDAGToDAGISel::doPeepholeSExtW(SDNode *N) {
4254 // Look for the sext.w pattern, addiw rd, rs1, 0.
4255 if (N->getMachineOpcode() != RISCV::ADDIW ||
4256 !isNullConstant(N->getOperand(1)))
4257 return false;
4258
4259 SDValue N0 = N->getOperand(0);
4260 if (!N0.isMachineOpcode())
4261 return false;
4262
4263 switch (N0.getMachineOpcode()) {
4264 default:
4265 break;
4266 case RISCV::ADD:
4267 case RISCV::ADDI:
4268 case RISCV::SUB:
4269 case RISCV::MUL:
4270 case RISCV::SLLI: {
4271 // Convert sext.w+add/sub/mul to their W instructions. This will create
4272 // a new independent instruction. This improves latency.
4273 unsigned Opc;
4274 switch (N0.getMachineOpcode()) {
4275 default:
4276 llvm_unreachable("Unexpected opcode!");
4277 case RISCV::ADD: Opc = RISCV::ADDW; break;
4278 case RISCV::ADDI: Opc = RISCV::ADDIW; break;
4279 case RISCV::SUB: Opc = RISCV::SUBW; break;
4280 case RISCV::MUL: Opc = RISCV::MULW; break;
4281 case RISCV::SLLI: Opc = RISCV::SLLIW; break;
4282 }
4283
4284 SDValue N00 = N0.getOperand(0);
4285 SDValue N01 = N0.getOperand(1);
4286
4287 // Shift amount needs to be uimm5.
4288 if (N0.getMachineOpcode() == RISCV::SLLI &&
4289 !isUInt<5>(cast<ConstantSDNode>(N01)->getSExtValue()))
4290 break;
4291
4292 SDNode *Result =
4293 CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0),
4294 N00, N01);
4295 ReplaceUses(N, Result);
4296 return true;
4297 }
4298 case RISCV::ADDW:
4299 case RISCV::ADDIW:
4300 case RISCV::SUBW:
4301 case RISCV::MULW:
4302 case RISCV::SLLIW:
4303 case RISCV::PACKW:
4304 case RISCV::TH_MULAW:
4305 case RISCV::TH_MULAH:
4306 case RISCV::TH_MULSW:
4307 case RISCV::TH_MULSH:
4308 if (N0.getValueType() == MVT::i32)
4309 break;
4310
4311 // Result is already sign extended just remove the sext.w.
4312 // NOTE: We only handle the nodes that are selected with hasAllWUsers.
4313 ReplaceUses(N, N0.getNode());
4314 return true;
4315 }
4316
4317 return false;
4318}
4319
4320static bool usesAllOnesMask(SDValue MaskOp) {
4321 const auto IsVMSet = [](unsigned Opc) {
4322 return Opc == RISCV::PseudoVMSET_M_B1 || Opc == RISCV::PseudoVMSET_M_B16 ||
4323 Opc == RISCV::PseudoVMSET_M_B2 || Opc == RISCV::PseudoVMSET_M_B32 ||
4324 Opc == RISCV::PseudoVMSET_M_B4 || Opc == RISCV::PseudoVMSET_M_B64 ||
4325 Opc == RISCV::PseudoVMSET_M_B8;
4326 };
4327
4328 // TODO: Check that the VMSET is the expected bitwidth? The pseudo has
4329 // undefined behaviour if it's the wrong bitwidth, so we could choose to
4330 // assume that it's all-ones? Same applies to its VL.
4331 return MaskOp->isMachineOpcode() && IsVMSet(MaskOp.getMachineOpcode());
4332}
4333
4334static bool isImplicitDef(SDValue V) {
4335 if (!V.isMachineOpcode())
4336 return false;
4337 if (V.getMachineOpcode() == TargetOpcode::REG_SEQUENCE) {
4338 for (unsigned I = 1; I < V.getNumOperands(); I += 2)
4339 if (!isImplicitDef(V.getOperand(I)))
4340 return false;
4341 return true;
4342 }
4343 return V.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;
4344}
4345
4346// Optimize masked RVV pseudo instructions with a known all-ones mask to their
4347// corresponding "unmasked" pseudo versions.
4348bool RISCVDAGToDAGISel::doPeepholeMaskedRVV(MachineSDNode *N) {
4349 const RISCV::RISCVMaskedPseudoInfo *I =
4350 RISCV::getMaskedPseudoInfo(N->getMachineOpcode());
4351 if (!I)
4352 return false;
4353
4354 unsigned MaskOpIdx = I->MaskOpIdx;
4355 if (!usesAllOnesMask(N->getOperand(MaskOpIdx)))
4356 return false;
4357
4358 // There are two classes of pseudos in the table - compares and
4359 // everything else. See the comment on RISCVMaskedPseudo for details.
4360 const unsigned Opc = I->UnmaskedPseudo;
4361 const MCInstrDesc &MCID = TII->get(Opc);
4362 const bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(MCID);
4363
4364 const MCInstrDesc &MaskedMCID = TII->get(N->getMachineOpcode());
4365 const bool MaskedHasPassthru = RISCVII::isFirstDefTiedToFirstUse(MaskedMCID);
4366
4367 assert((RISCVII::hasVecPolicyOp(MaskedMCID.TSFlags) ||
4369 "Unmasked pseudo has policy but masked pseudo doesn't?");
4370 assert(RISCVII::hasVecPolicyOp(MCID.TSFlags) == HasPassthru &&
4371 "Unexpected pseudo structure");
4372 assert(!(HasPassthru && !MaskedHasPassthru) &&
4373 "Unmasked pseudo has passthru but masked pseudo doesn't?");
4374
4376 // Skip the passthru operand at index 0 if the unmasked don't have one.
4377 bool ShouldSkip = !HasPassthru && MaskedHasPassthru;
4378 bool DropPolicy = !RISCVII::hasVecPolicyOp(MCID.TSFlags) &&
4379 RISCVII::hasVecPolicyOp(MaskedMCID.TSFlags);
4380 bool HasChainOp =
4381 N->getOperand(N->getNumOperands() - 1).getValueType() == MVT::Other;
4382 unsigned LastOpNum = N->getNumOperands() - 1 - HasChainOp;
4383 for (unsigned I = ShouldSkip, E = N->getNumOperands(); I != E; I++) {
4384 // Skip the mask
4385 SDValue Op = N->getOperand(I);
4386 if (I == MaskOpIdx)
4387 continue;
4388 if (DropPolicy && I == LastOpNum)
4389 continue;
4390 Ops.push_back(Op);
4391 }
4392
4393 MachineSDNode *Result =
4394 CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
4395
4396 if (!N->memoperands_empty())
4397 CurDAG->setNodeMemRefs(Result, N->memoperands());
4398
4399 Result->setFlags(N->getFlags());
4400 ReplaceUses(N, Result);
4401
4402 return true;
4403}
4404
4405/// If our passthru is an implicit_def, use noreg instead. This side
4406/// steps issues with MachineCSE not being able to CSE expressions with
4407/// IMPLICIT_DEF operands while preserving the semantic intent. See
4408/// pr64282 for context. Note that this transform is the last one
4409/// performed at ISEL DAG to DAG.
4410bool RISCVDAGToDAGISel::doPeepholeNoRegPassThru() {
4411 bool MadeChange = false;
4412 SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end();
4413
4414 while (Position != CurDAG->allnodes_begin()) {
4415 SDNode *N = &*--Position;
4416 if (N->use_empty() || !N->isMachineOpcode())
4417 continue;
4418
4419 const unsigned Opc = N->getMachineOpcode();
4420 if (!RISCVVPseudosTable::getPseudoInfo(Opc) ||
4422 !isImplicitDef(N->getOperand(0)))
4423 continue;
4424
4426 Ops.push_back(CurDAG->getRegister(RISCV::NoRegister, N->getValueType(0)));
4427 for (unsigned I = 1, E = N->getNumOperands(); I != E; I++) {
4428 SDValue Op = N->getOperand(I);
4429 Ops.push_back(Op);
4430 }
4431
4432 MachineSDNode *Result =
4433 CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
4434 Result->setFlags(N->getFlags());
4435 CurDAG->setNodeMemRefs(Result, cast<MachineSDNode>(N)->memoperands());
4436 ReplaceUses(N, Result);
4437 MadeChange = true;
4438 }
4439 return MadeChange;
4440}
4441
4442
4443// This pass converts a legalized DAG into a RISCV-specific DAG, ready
4444// for instruction scheduling.
4446 CodeGenOptLevel OptLevel) {
4447 return new RISCVDAGToDAGISelLegacy(TM, OptLevel);
4448}
4449
4451
4456
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:119
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
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
Definition APInt.h:435
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:219
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
Definition APInt.h:510
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 trySignedBitfieldInsertInMask(SDNode *Node)
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 tryBitfieldInsertOpFromOrAndImm(SDNode *Node)
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)
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.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
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:1727
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:260
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:270
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:342
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:157
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:336
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:203
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:212
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:577
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:851
#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:390
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition ValueTypes.h:157
Matching combinators.
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.