LLVM 23.0.0git
MipsSEISelLowering.cpp
Go to the documentation of this file.
1//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===//
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// Subclass of MipsTargetLowering specialized for mips32/64.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsSEISelLowering.h"
14#include "MipsMachineFunction.h"
15#include "MipsRegisterInfo.h"
16#include "MipsSubtarget.h"
17#include "llvm/ADT/APInt.h"
18#include "llvm/ADT/STLExtras.h"
35#include "llvm/IR/DebugLoc.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/IntrinsicsMips.h"
40#include "llvm/Support/Debug.h"
44#include <algorithm>
45#include <cassert>
46#include <cstddef>
47#include <cstdint>
48#include <iterator>
49#include <utility>
50
51using namespace llvm;
52
53#define DEBUG_TYPE "mips-isel"
54
55static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
56 cl::desc("Expand double precision loads and "
57 "stores to their single precision "
58 "counterparts"));
59
60// Widen the v2 vectors to the register width, i.e. v2i16 -> v8i16,
61// v2i32 -> v4i32, etc, to ensure the correct rail size is used, i.e.
62// INST.h for v16, INST.w for v32, INST.d for v64.
65 if (this->Subtarget.hasMSA()) {
66 switch (VT.SimpleTy) {
67 // Leave v2i1 vectors to be promoted to larger ones.
68 // Other i1 types will be promoted by default.
69 case MVT::v2i1:
70 return TypePromoteInteger;
71 break;
72 // 16-bit vector types (v2 and longer)
73 case MVT::v2i8:
74 // 32-bit vector types (v2 and longer)
75 case MVT::v2i16:
76 case MVT::v4i8:
77 // 64-bit vector types (v2 and longer)
78 case MVT::v2i32:
79 case MVT::v4i16:
80 case MVT::v8i8:
81 return TypeWidenVector;
82 break;
83 // Only word (.w) and doubleword (.d) are available for floating point
84 // vectors. That means floating point vectors should be either v2f64
85 // or v4f32.
86 // Here we only explicitly widen the f32 types - f16 will be promoted
87 // by default.
88 case MVT::v2f32:
89 case MVT::v3f32:
90 return TypeWidenVector;
91 // v2i64 is already 128-bit wide.
92 default:
93 break;
94 }
95 }
97}
98
100 const MipsSubtarget &STI)
101 : MipsTargetLowering(TM, STI) {
102 // Set up the register classes
103 addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
104
105 if (Subtarget.isGP64bit())
106 addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
107
108 if (Subtarget.hasDSP() || Subtarget.hasMSA()) {
109 // Expand all truncating stores and extending loads.
112 setTruncStoreAction(VT0, VT1, Expand);
116 }
117 }
118 }
119
120 if (Subtarget.hasDSP()) {
121 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
122
123 for (const auto &VecTy : VecTys) {
124 addRegisterClass(VecTy, &Mips::DSPRRegClass);
125
126 // Expand all builtin opcodes.
127 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
129
135 }
136
139
140 if (Subtarget.hasMips32r2()) {
143 }
144 }
145
146 if (Subtarget.hasDSPR2())
147 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
148
149 if (Subtarget.hasMSA()) {
150 addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass);
151 addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass);
152 addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass);
153 addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass);
154 addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass);
155 addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
156 addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
157
158 // We're using soft promotion for f16, but msa has some instructions for
159 // conversion to/from f16. Mark those conversions as custom so we can take
160 // advantage of these instructions.
161 for (MVT VT : {MVT::f32, MVT::f64}) {
164 }
165
168 }
169
170 if (!Subtarget.useSoftFloat()) {
171 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
172
173 // When dealing with single precision only, use libcalls
174 if (!Subtarget.isSingleFloat()) {
175 if (Subtarget.isFP64bit())
176 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
177 else
178 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
179 }
180
183 setOperationAction(Op, MVT::f32, Legal);
184 setOperationAction(Op, MVT::f64, Legal);
185 }
186 }
187
188 // Targets with 64bits integer registers, but no 64bit floating point register
189 // do not support conversion between them
190 if (Subtarget.isGP64bit() && Subtarget.isSingleFloat() &&
191 !Subtarget.useSoftFloat()) {
196 }
197
202
203 if (Subtarget.hasCnMips())
205 else if (Subtarget.isR5900()) {
206 // R5900 doesn't have DMULT/DMULTU/DDIV/DDIVU - expand to 32-bit ops
214 } else if (Subtarget.isGP64bit())
216
217 if (Subtarget.isGP64bit() && !Subtarget.isR5900()) {
224 }
225
228
232 if (Subtarget.hasMips32r6()) {
235 } else {
238 }
239
241
245
246 if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() &&
247 !Subtarget.hasMips64()) {
249 }
250
251 if (NoDPLoadStore) {
254 }
255
256 if (Subtarget.hasMips32r6()) {
257 // MIPS32r6 replaces the accumulator-based multiplies with a three register
258 // instruction
264
265 // MIPS32r6 replaces the accumulator-based division/remainder with separate
266 // three register division and remainder instructions.
273
274 // MIPS32r6 replaces conditional moves with an equivalent that removes the
275 // need for three GPR read ports.
279
283
284 assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6");
288
290
291 // Floating point > and >= are supported via < and <=
300
309 }
310
311 if (Subtarget.hasMips64r6()) {
312 // MIPS64r6 replaces the accumulator-based multiplies with a three register
313 // instruction
319
320 // MIPS32r6 replaces the accumulator-based division/remainder with separate
321 // three register division and remainder instructions.
328
329 // MIPS64r6 replaces conditional moves with an equivalent that removes the
330 // need for three GPR read ports.
334 }
335
336 if (Subtarget.isR5900()) {
337 // R5900 FPU only supports 4 compare conditions: C.F, C.EQ, C.OLT, C.OLE
338 // (and their inversions via bc1t/bc1f). Expand all conditions that would
339 // require C.UN, C.UEQ, C.ULT, or C.ULE instructions (not available on
340 // R5900). The legalizer resolves these via operand swapping, condition
341 // inversion, and decomposition into supported conditions.
353
354 // R5900 FPU does not support IEEE 754 special values (NaN, infinity). Use
355 // custom lowering to decide per-instruction: hardware when nnan+ninf flags
356 // guarantee no NaN or infinity, software libcall otherwise.
362 }
363
364 computeRegisterProperties(Subtarget.getRegisterInfo());
365}
366
367const MipsTargetLowering *
369 const MipsSubtarget &STI) {
370 return new MipsSETargetLowering(TM, STI);
371}
372
375 if (VT == MVT::Untyped)
376 return Subtarget.hasDSP() ? &Mips::ACC64DSPRegClass : &Mips::ACC64RegClass;
377
379}
380
381// Enable MSA support for the given integer type and Register class.
384 addRegisterClass(Ty, RC);
385
386 // Expand all builtin opcodes.
387 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
389
397
419
420 if (Ty == MVT::v4i32 || Ty == MVT::v2i64) {
425 }
426
433}
434
435// Enable MSA support for the given floating-point type and Register class.
473
474SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
477
478 EVT ResTy = Op->getValueType(0);
479 SDLoc DL(Op);
480
481 // Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the
482 // floating point register are undefined. Not really an issue as sel.d, which
483 // is produced from an FSELECT node, only looks at bit 0.
484 SDValue Tmp = DAG.getNode(MipsISD::MTC1_D64, DL, MVT::f64, Op->getOperand(0));
485 return DAG.getNode(MipsISD::FSELECT, DL, ResTy, Tmp, Op->getOperand(1),
486 Op->getOperand(2));
487}
488
489// Lower FP16_TO_FP (the soft-promote-half representation of an f16 -> f32/f64
490// conversion).
491SDValue MipsSETargetLowering::lowerFP16_TO_FP(SDValue Op,
492 SelectionDAG &DAG) const {
493 SDLoc DL(Op);
494 EVT ResTy = Op.getValueType();
495 assert((ResTy == MVT::f32 || ResTy == MVT::f64) && "Unexpected FP16_TO_FP");
496
497 // The operand type is i32 because i16 isn't actually legal on MIPS.
498 SDValue In = Op.getOperand(0);
499 assert(In.getValueType() == MVT::i32 && "Unexpected FP16_TO_FP operand type");
500
501 // Splat into a v8i16 (the 32-bit In value is truncated to the lower 16 bits).
502 SDValue Splatted = DAG.getSplatBuildVector(MVT::v8i16, DL, In);
503
504 // Bitcast from v8i16 to v8f16.
505 SDValue HVec = DAG.getNode(ISD::BITCAST, DL, MVT::v8f16, Splatted);
506
507 // Convert from v8f16 to v4f32.
508 SDValue F32Vec = DAG.getNode(
509 ISD::INTRINSIC_WO_CHAIN, DL, MVT::v4f32,
510 DAG.getConstant(Intrinsic::mips_fexupr_w, DL, MVT::i32), HVec);
511 SDValue Res;
512 if (ResTy == MVT::f32) {
513 // Every lane has the converted value, just read it from lane 0.
514 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, F32Vec,
515 DAG.getVectorIdxConstant(0, DL));
516 } else {
517 // Convert from v4f32 to v2f64.
518 SDValue F64Vec = DAG.getNode(
519 ISD::INTRINSIC_WO_CHAIN, DL, MVT::v2f64,
520 DAG.getConstant(Intrinsic::mips_fexupr_d, DL, MVT::i32), F32Vec);
521 // Every lane has the converted value, just read it from lane 0.
522 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64, F64Vec,
523 DAG.getVectorIdxConstant(0, DL));
524 }
525
526 return Res;
527}
528
529// Lower FP_TO_FP16 (the soft-promote-half representation of an f32/f64 -> f16
530// conversion)
531SDValue MipsSETargetLowering::lowerFP_TO_FP16(SDValue Op,
532 SelectionDAG &DAG) const {
533 SDLoc DL(Op);
534 EVT ResTy = Op.getValueType();
535 SDValue In = Op.getOperand(0);
536 assert((In.getValueType() == MVT::f32 || In.getValueType() == MVT::f64) &&
537 "Unexpected FP_TO_FP16");
538
539 SDValue F32Vec;
540 if (In.getValueType() == MVT::f64) {
541 // Splat f64 to v2f64, then convert to v4f32.
542 SDValue F64Vec = DAG.getSplatBuildVector(MVT::v2f64, DL, In);
543 F32Vec = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::v4f32,
544 DAG.getConstant(Intrinsic::mips_fexdo_w, DL, MVT::i32),
545 F64Vec, F64Vec);
546 } else {
547 // Splat f32 to v4f32.
548 F32Vec = DAG.getSplatBuildVector(MVT::v4f32, DL, In);
549 }
550
551 // Then convert from v4f32 to v8f16.
552 SDValue HVec = DAG.getNode(
553 ISD::INTRINSIC_WO_CHAIN, DL, MVT::v8f16,
554 DAG.getConstant(Intrinsic::mips_fexdo_h, DL, MVT::i32), F32Vec, F32Vec);
555
556 // Finally cast to v8i16 (f16 is soft-promoted).
557 SDValue IVec = DAG.getNode(ISD::BITCAST, DL, MVT::v8i16, HVec);
558 SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResTy, IVec,
559 DAG.getVectorIdxConstant(0, DL));
560
561 return Res;
562}
563
565 EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {
567
568 if (Subtarget.systemSupportsUnalignedAccess()) {
569 // MIPS32r6/MIPS64r6 is required to support unaligned access. It's
570 // implementation defined whether this is handled by hardware, software, or
571 // a hybrid of the two but it's expected that most implementations will
572 // handle the majority of cases in hardware.
573 if (Fast)
574 *Fast = 1;
575 return true;
576 } else if (Subtarget.hasMips32r6()) {
577 return false;
578 }
579
580 switch (SVT) {
581 case MVT::i64:
582 case MVT::i32:
583 if (Fast)
584 *Fast = 1;
585 return true;
586 default:
587 return false;
588 }
589}
590
592 SelectionDAG &DAG) const {
593 switch(Op.getOpcode()) {
594 case ISD::LOAD: return lowerLOAD(Op, DAG);
595 case ISD::STORE: return lowerSTORE(Op, DAG);
596 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
597 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
598 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
599 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
600 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
601 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
602 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
603 DAG);
604 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
605 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
606 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
607 case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
608 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
609 case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
610 case ISD::SELECT:
611 return lowerSELECT(Op, DAG);
612 case ISD::FP16_TO_FP:
614 return lowerFP16_TO_FP(Op, DAG);
615 case ISD::FP_TO_FP16:
617 return lowerFP_TO_FP16(Op, DAG);
618 case ISD::BITCAST: return lowerBITCAST(Op, DAG);
619 case ISD::FADD:
620 return lowerR5900FPOp(Op, DAG, RTLIB::ADD_F32);
621 case ISD::FSUB:
622 return lowerR5900FPOp(Op, DAG, RTLIB::SUB_F32);
623 case ISD::FMUL:
624 return lowerR5900FPOp(Op, DAG, RTLIB::MUL_F32);
625 case ISD::FDIV:
626 return lowerR5900FPOp(Op, DAG, RTLIB::DIV_F32);
627 case ISD::FSQRT:
628 return lowerR5900FPOp(Op, DAG, RTLIB::SQRT_F32);
629 }
630
632}
633
634SDValue MipsSETargetLowering::lowerR5900FPOp(SDValue Op, SelectionDAG &DAG,
635 RTLIB::Libcall LC) const {
637 SDNodeFlags Flags = Op->getFlags();
638
639 if (Flags.hasNoNaNs() && Flags.hasNoInfs()) {
640 // Use the hardware FPU instruction if the operation is guaranteed to have
641 // no NaN or infinity inputs/outputs (nnan+ninf flags).
642 return Op;
643 }
644
645 // Fall back to a software libcall for IEEE correctness.
646 SDLoc DL(Op);
647 MVT VT = Op.getSimpleValueType();
648 SmallVector<SDValue, 2> Ops(Op->op_begin(), Op->op_end());
650 auto [Result, Chain] = makeLibCall(DAG, LC, VT, Ops, CallOptions, DL);
651 return Result;
652}
653
654// Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT
655//
656// Performs the following transformations:
657// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its
658// sign/zero-extension is completely overwritten by the new one performed by
659// the ISD::AND.
660// - Removes redundant zero extensions performed by an ISD::AND.
663 const MipsSubtarget &Subtarget) {
664 if (!Subtarget.hasMSA())
665 return SDValue();
666
667 SDValue Op0 = N->getOperand(0);
668 SDValue Op1 = N->getOperand(1);
669 unsigned Op0Opcode = Op0->getOpcode();
670
671 // (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d)
672 // where $d + 1 == 2^n and n == 32
673 // or $d + 1 == 2^n and n <= 32 and ZExt
674 // -> (MipsVExtractZExt $a, $b, $c)
675 if (Op0Opcode == MipsISD::VEXTRACT_SEXT_ELT ||
676 Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT) {
678
679 if (!Mask)
680 return SDValue();
681
682 int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2();
683
684 if (Log2IfPositive <= 0)
685 return SDValue(); // Mask+1 is not a power of 2
686
687 SDValue Op0Op2 = Op0->getOperand(2);
688 EVT ExtendTy = cast<VTSDNode>(Op0Op2)->getVT();
689 unsigned ExtendTySize = ExtendTy.getSizeInBits();
690 unsigned Log2 = Log2IfPositive;
691
692 if ((Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT && Log2 >= ExtendTySize) ||
693 Log2 == ExtendTySize) {
694 SDValue Ops[] = { Op0->getOperand(0), Op0->getOperand(1), Op0Op2 };
695 return DAG.getNode(MipsISD::VEXTRACT_ZEXT_ELT, SDLoc(Op0),
696 Op0->getVTList(),
697 ArrayRef(Ops, Op0->getNumOperands()));
698 }
699 }
700
701 return SDValue();
702}
703
704// Determine if the specified node is a constant vector splat.
705//
706// Returns true and sets Imm if:
707// * N is a ISD::BUILD_VECTOR representing a constant splat
708//
709// This function is quite similar to MipsSEDAGToDAGISel::selectVSplat. The
710// differences are that it assumes the MSA has already been checked and the
711// arbitrary requirement for a maximum of 32-bit integers isn't applied (and
712// must not be in order for binsri.d to be selectable).
713static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian) {
715
716 if (!Node)
717 return false;
718
719 APInt SplatValue, SplatUndef;
720 unsigned SplatBitSize;
721 bool HasAnyUndefs;
722
723 if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
724 8, !IsLittleEndian))
725 return false;
726
727 Imm = SplatValue;
728
729 return true;
730}
731
732// Test whether the given node is an all-ones build_vector.
734 // Look through bitcasts. Endianness doesn't matter because we are looking
735 // for an all-ones value.
736 if (N->getOpcode() == ISD::BITCAST)
737 N = N->getOperand(0);
738
740
741 if (!BVN)
742 return false;
743
744 APInt SplatValue, SplatUndef;
745 unsigned SplatBitSize;
746 bool HasAnyUndefs;
747
748 // Endianness doesn't matter in this context because we are looking for
749 // an all-ones value.
750 if (BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs))
751 return SplatValue.isAllOnes();
752
753 return false;
754}
755
756// Test whether N is the bitwise inverse of OfNode.
757static bool isBitwiseInverse(SDValue N, SDValue OfNode) {
758 if (N->getOpcode() != ISD::XOR)
759 return false;
760
761 if (isVectorAllOnes(N->getOperand(0)))
762 return N->getOperand(1) == OfNode;
763
764 if (isVectorAllOnes(N->getOperand(1)))
765 return N->getOperand(0) == OfNode;
766
767 return false;
768}
769
770// Perform combines where ISD::OR is the root node.
771//
772// Performs the following transformations:
773// - (or (and $a, $mask), (and $b, $inv_mask)) => (vselect $mask, $a, $b)
774// where $inv_mask is the bitwise inverse of $mask and the 'or' has a 128-bit
775// vector type.
778 const MipsSubtarget &Subtarget) {
779 if (!Subtarget.hasMSA())
780 return SDValue();
781
782 EVT Ty = N->getValueType(0);
783
784 if (!Ty.is128BitVector())
785 return SDValue();
786
787 SDValue Op0 = N->getOperand(0);
788 SDValue Op1 = N->getOperand(1);
789
790 if (Op0->getOpcode() == ISD::AND && Op1->getOpcode() == ISD::AND) {
791 SDValue Op0Op0 = Op0->getOperand(0);
792 SDValue Op0Op1 = Op0->getOperand(1);
793 SDValue Op1Op0 = Op1->getOperand(0);
794 SDValue Op1Op1 = Op1->getOperand(1);
795 bool IsLittleEndian = !Subtarget.isLittle();
796
797 SDValue IfSet, IfClr, Cond;
798 bool IsConstantMask = false;
799 APInt Mask, InvMask;
800
801 // If Op0Op0 is an appropriate mask, try to find it's inverse in either
802 // Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, while
803 // looking.
804 // IfClr will be set if we find a valid match.
805 if (isVSplat(Op0Op0, Mask, IsLittleEndian)) {
806 Cond = Op0Op0;
807 IfSet = Op0Op1;
808
809 if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
810 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
811 IfClr = Op1Op1;
812 else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
813 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
814 IfClr = Op1Op0;
815
816 IsConstantMask = true;
817 }
818
819 // If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the same
820 // thing again using this mask.
821 // IfClr will be set if we find a valid match.
822 if (!IfClr.getNode() && isVSplat(Op0Op1, Mask, IsLittleEndian)) {
823 Cond = Op0Op1;
824 IfSet = Op0Op0;
825
826 if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
827 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
828 IfClr = Op1Op1;
829 else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
830 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
831 IfClr = Op1Op0;
832
833 IsConstantMask = true;
834 }
835
836 // If IfClr is not yet set, try looking for a non-constant match.
837 // IfClr will be set if we find a valid match amongst the eight
838 // possibilities.
839 if (!IfClr.getNode()) {
840 if (isBitwiseInverse(Op0Op0, Op1Op0)) {
841 Cond = Op1Op0;
842 IfSet = Op1Op1;
843 IfClr = Op0Op1;
844 } else if (isBitwiseInverse(Op0Op1, Op1Op0)) {
845 Cond = Op1Op0;
846 IfSet = Op1Op1;
847 IfClr = Op0Op0;
848 } else if (isBitwiseInverse(Op0Op0, Op1Op1)) {
849 Cond = Op1Op1;
850 IfSet = Op1Op0;
851 IfClr = Op0Op1;
852 } else if (isBitwiseInverse(Op0Op1, Op1Op1)) {
853 Cond = Op1Op1;
854 IfSet = Op1Op0;
855 IfClr = Op0Op0;
856 } else if (isBitwiseInverse(Op1Op0, Op0Op0)) {
857 Cond = Op0Op0;
858 IfSet = Op0Op1;
859 IfClr = Op1Op1;
860 } else if (isBitwiseInverse(Op1Op1, Op0Op0)) {
861 Cond = Op0Op0;
862 IfSet = Op0Op1;
863 IfClr = Op1Op0;
864 } else if (isBitwiseInverse(Op1Op0, Op0Op1)) {
865 Cond = Op0Op1;
866 IfSet = Op0Op0;
867 IfClr = Op1Op1;
868 } else if (isBitwiseInverse(Op1Op1, Op0Op1)) {
869 Cond = Op0Op1;
870 IfSet = Op0Op0;
871 IfClr = Op1Op0;
872 }
873 }
874
875 // At this point, IfClr will be set if we have a valid match.
876 if (!IfClr.getNode())
877 return SDValue();
878
879 assert(Cond.getNode() && IfSet.getNode());
880
881 // Fold degenerate cases.
882 if (IsConstantMask) {
883 if (Mask.isAllOnes())
884 return IfSet;
885 else if (Mask == 0)
886 return IfClr;
887 }
888
889 // Transform the DAG into an equivalent VSELECT.
890 return DAG.getNode(ISD::VSELECT, SDLoc(N), Ty, Cond, IfSet, IfClr);
891 }
892
893 return SDValue();
894}
895
897 SelectionDAG &DAG,
898 const MipsSubtarget &Subtarget) {
899 // Estimate the number of operations the below transform will turn a
900 // constant multiply into. The number is approximately equal to the minimal
901 // number of powers of two that constant can be broken down to by adding
902 // or subtracting them.
903 //
904 // If we have taken more than 12[1] / 8[2] steps to attempt the
905 // optimization for a native sized value, it is more than likely that this
906 // optimization will make things worse.
907 //
908 // [1] MIPS64 requires 6 instructions at most to materialize any constant,
909 // multiplication requires at least 4 cycles, but another cycle (or two)
910 // to retrieve the result from the HI/LO registers.
911 //
912 // [2] For MIPS32, more than 8 steps is expensive as the constant could be
913 // materialized in 2 instructions, multiplication requires at least 4
914 // cycles, but another cycle (or two) to retrieve the result from the
915 // HI/LO registers.
916 //
917 // TODO:
918 // - MaxSteps needs to consider the `VT` of the constant for the current
919 // target.
920 // - Consider to perform this optimization after type legalization.
921 // That allows to remove a workaround for types not supported natively.
922 // - Take in account `-Os, -Oz` flags because this optimization
923 // increases code size.
924 unsigned MaxSteps = Subtarget.isABI_O32() ? 8 : 12;
925
926 SmallVector<APInt, 16> WorkStack(1, C);
927 unsigned Steps = 0;
928 unsigned BitWidth = C.getBitWidth();
929
930 while (!WorkStack.empty()) {
931 APInt Val = WorkStack.pop_back_val();
932
933 if (Val == 0 || Val == 1)
934 continue;
935
936 if (Steps >= MaxSteps)
937 return false;
938
939 if (Val.isPowerOf2()) {
940 ++Steps;
941 continue;
942 }
943
944 APInt Floor = APInt(BitWidth, 1) << Val.logBase2();
945 APInt Ceil = Val.isNegative() ? APInt(BitWidth, 0)
946 : APInt(BitWidth, 1) << C.ceilLogBase2();
947 if ((Val - Floor).ule(Ceil - Val)) {
948 WorkStack.push_back(Floor);
949 WorkStack.push_back(Val - Floor);
950 } else {
951 WorkStack.push_back(Ceil);
952 WorkStack.push_back(Ceil - Val);
953 }
954
955 ++Steps;
956 }
957
958 // If the value being multiplied is not supported natively, we have to pay
959 // an additional legalization cost, conservatively assume an increase in the
960 // cost of 3 instructions per step. This values for this heuristic were
961 // determined experimentally.
962 unsigned RegisterSize = DAG.getTargetLoweringInfo()
963 .getRegisterType(*DAG.getContext(), VT)
964 .getSizeInBits();
965 Steps *= (VT.getSizeInBits() != RegisterSize) * 3;
966 if (Steps > 27)
967 return false;
968
969 return true;
970}
971
973 EVT ShiftTy, SelectionDAG &DAG) {
974 // Return 0.
975 if (C == 0)
976 return DAG.getConstant(0, DL, VT);
977
978 // Return x.
979 if (C == 1)
980 return X;
981
982 // If c is power of 2, return (shl x, log2(c)).
983 if (C.isPowerOf2())
984 return DAG.getNode(ISD::SHL, DL, VT, X,
985 DAG.getConstant(C.logBase2(), DL, ShiftTy));
986
987 unsigned BitWidth = C.getBitWidth();
988 APInt Floor = APInt(BitWidth, 1) << C.logBase2();
989 APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) :
990 APInt(BitWidth, 1) << C.ceilLogBase2();
991
992 // If |c - floor_c| <= |c - ceil_c|,
993 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
994 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
995 if ((C - Floor).ule(Ceil - C)) {
996 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
997 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
998 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
999 }
1000
1001 // If |c - floor_c| > |c - ceil_c|,
1002 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
1003 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
1004 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
1005 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
1006}
1007
1010 const MipsSETargetLowering *TL,
1011 const MipsSubtarget &Subtarget) {
1012 EVT VT = N->getValueType(0);
1013
1014 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
1016 C->getAPIntValue(), VT, DAG, Subtarget))
1017 return genConstMult(N->getOperand(0), C->getAPIntValue(), SDLoc(N), VT,
1019 DAG);
1020
1021 return SDValue(N, 0);
1022}
1023
1025 SelectionDAG &DAG,
1026 const MipsSubtarget &Subtarget) {
1027 // See if this is a vector splat immediate node.
1028 APInt SplatValue, SplatUndef;
1029 unsigned SplatBitSize;
1030 bool HasAnyUndefs;
1031 unsigned EltSize = Ty.getScalarSizeInBits();
1032 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
1033
1034 if (!Subtarget.hasDSP())
1035 return SDValue();
1036
1037 if (!BV ||
1038 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
1039 EltSize, !Subtarget.isLittle()) ||
1040 (SplatBitSize != EltSize) ||
1041 (SplatValue.getZExtValue() >= EltSize))
1042 return SDValue();
1043
1044 SDLoc DL(N);
1045 return DAG.getNode(Opc, DL, Ty, N->getOperand(0),
1046 DAG.getConstant(SplatValue.getZExtValue(), DL, MVT::i32));
1047}
1048
1051 const MipsSubtarget &Subtarget) {
1052 EVT Ty = N->getValueType(0);
1053
1054 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
1055 return SDValue();
1056
1057 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
1058}
1059
1060// Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold
1061// constant splats into MipsISD::SHRA_DSP for DSPr2.
1062//
1063// Performs the following transformations:
1064// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its
1065// sign/zero-extension is completely overwritten by the new one performed by
1066// the ISD::SRA and ISD::SHL nodes.
1067// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL
1068// sequence.
1069//
1070// See performDSPShiftCombine for more information about the transformation
1071// used for DSPr2.
1074 const MipsSubtarget &Subtarget) {
1075 EVT Ty = N->getValueType(0);
1076
1077 if (Subtarget.hasMSA()) {
1078 SDValue Op0 = N->getOperand(0);
1079 SDValue Op1 = N->getOperand(1);
1080
1081 // (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d)
1082 // where $d + sizeof($c) == 32
1083 // or $d + sizeof($c) <= 32 and SExt
1084 // -> (MipsVExtractSExt $a, $b, $c)
1085 if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(1)) {
1086 SDValue Op0Op0 = Op0->getOperand(0);
1088
1089 if (!ShAmount)
1090 return SDValue();
1091
1092 if (Op0Op0->getOpcode() != MipsISD::VEXTRACT_SEXT_ELT &&
1093 Op0Op0->getOpcode() != MipsISD::VEXTRACT_ZEXT_ELT)
1094 return SDValue();
1095
1096 EVT ExtendTy = cast<VTSDNode>(Op0Op0->getOperand(2))->getVT();
1097 unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits();
1098
1099 if (TotalBits == 32 ||
1100 (Op0Op0->getOpcode() == MipsISD::VEXTRACT_SEXT_ELT &&
1101 TotalBits <= 32)) {
1102 SDValue Ops[] = { Op0Op0->getOperand(0), Op0Op0->getOperand(1),
1103 Op0Op0->getOperand(2) };
1104 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, SDLoc(Op0Op0),
1105 Op0Op0->getVTList(),
1106 ArrayRef(Ops, Op0Op0->getNumOperands()));
1107 }
1108 }
1109 }
1110
1111 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget.hasDSPR2()))
1112 return SDValue();
1113
1114 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
1115}
1116
1117
1120 const MipsSubtarget &Subtarget) {
1121 EVT Ty = N->getValueType(0);
1122
1123 if (((Ty != MVT::v2i16) || !Subtarget.hasDSPR2()) && (Ty != MVT::v4i8))
1124 return SDValue();
1125
1126 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
1127}
1128
1130 bool IsV216 = (Ty == MVT::v2i16);
1131
1132 switch (CC) {
1133 case ISD::SETEQ:
1134 case ISD::SETNE: return true;
1135 case ISD::SETLT:
1136 case ISD::SETLE:
1137 case ISD::SETGT:
1138 case ISD::SETGE: return IsV216;
1139 case ISD::SETULT:
1140 case ISD::SETULE:
1141 case ISD::SETUGT:
1142 case ISD::SETUGE: return !IsV216;
1143 default: return false;
1144 }
1145}
1146
1148 EVT Ty = N->getValueType(0);
1149
1150 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
1151 return SDValue();
1152
1153 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
1154 return SDValue();
1155
1156 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
1157 N->getOperand(1), N->getOperand(2));
1158}
1159
1161 EVT Ty = N->getValueType(0);
1162
1163 if (Ty == MVT::v2i16 || Ty == MVT::v4i8) {
1164 SDValue SetCC = N->getOperand(0);
1165
1166 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
1167 return SDValue();
1168
1169 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
1170 SetCC.getOperand(0), SetCC.getOperand(1),
1171 N->getOperand(1), N->getOperand(2), SetCC.getOperand(2));
1172 }
1173
1174 return SDValue();
1175}
1176
1178 const MipsSubtarget &Subtarget) {
1179 EVT Ty = N->getValueType(0);
1180
1181 if (Subtarget.hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
1182 // Try the following combines:
1183 // (xor (or $a, $b), (build_vector allones))
1184 // (xor (or $a, $b), (bitcast (build_vector allones)))
1185 SDValue Op0 = N->getOperand(0);
1186 SDValue Op1 = N->getOperand(1);
1187 SDValue NotOp;
1188
1190 NotOp = Op1;
1191 else if (ISD::isBuildVectorAllOnes(Op1.getNode()))
1192 NotOp = Op0;
1193 else
1194 return SDValue();
1195
1196 if (NotOp->getOpcode() == ISD::OR)
1197 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0),
1198 NotOp->getOperand(1));
1199 }
1200
1201 return SDValue();
1202}
1203
1204// Convert (fp_to_uint (fp16_to_fp x)) into (fp_to_sint (fp16_to_fp x)).
1206 SDValue Src = N->getOperand(0);
1207 EVT VT = N->getValueType(0);
1208
1209 // Use a trick from TargetLowering::expandFP_TO_UINT: we know that every
1210 // integer value that can be represented by f16 is <= 65504, i.e. a signed
1211 // integer of 17 bits or more can represent all values and fptoui and fptosi
1212 // are equivalent.
1213 //
1214 // NOTE: the result of fptoui is poison when the value does not fit in the
1215 // destination type (e.g. because it is negative).
1216 if (Src.getOpcode() != ISD::FP16_TO_FP || VT.getScalarSizeInBits() < 17)
1217 return SDValue();
1218 return DAG.getNode(ISD::FP_TO_SINT, SDLoc(N), VT, Src);
1219}
1220
1221SDValue
1223 SelectionDAG &DAG = DCI.DAG;
1224 SDValue Val;
1225
1226 switch (N->getOpcode()) {
1227 case ISD::AND:
1228 Val = performANDCombine(N, DAG, DCI, Subtarget);
1229 break;
1230 case ISD::OR:
1231 Val = performORCombine(N, DAG, DCI, Subtarget);
1232 break;
1233 case ISD::MUL:
1234 return performMULCombine(N, DAG, DCI, this, Subtarget);
1235 case ISD::SHL:
1236 Val = performSHLCombine(N, DAG, DCI, Subtarget);
1237 break;
1238 case ISD::SRA:
1239 return performSRACombine(N, DAG, DCI, Subtarget);
1240 case ISD::SRL:
1241 return performSRLCombine(N, DAG, DCI, Subtarget);
1242 case ISD::VSELECT:
1243 return performVSELECTCombine(N, DAG);
1244 case ISD::XOR:
1245 Val = performXORCombine(N, DAG, Subtarget);
1246 break;
1247 case ISD::SETCC:
1248 Val = performSETCCCombine(N, DAG);
1249 break;
1250 case ISD::FP_TO_UINT:
1251 Val = performFP_TO_UINTCombine(N, DAG);
1252 break;
1253 }
1254
1255 if (Val.getNode()) {
1256 LLVM_DEBUG(dbgs() << "\nMipsSE DAG Combine:\n";
1257 N->printrWithDepth(dbgs(), &DAG); dbgs() << "\n=> \n";
1258 Val.getNode()->printrWithDepth(dbgs(), &DAG); dbgs() << "\n");
1259 return Val;
1260 }
1261
1263}
1264
1267 MachineBasicBlock *BB) const {
1268 switch (MI.getOpcode()) {
1269 default:
1271 case Mips::BPOSGE32_PSEUDO:
1272 return emitBPOSGE32(MI, BB);
1273 case Mips::SNZ_B_PSEUDO:
1274 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
1275 case Mips::SNZ_H_PSEUDO:
1276 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
1277 case Mips::SNZ_W_PSEUDO:
1278 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
1279 case Mips::SNZ_D_PSEUDO:
1280 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
1281 case Mips::SNZ_V_PSEUDO:
1282 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
1283 case Mips::SZ_B_PSEUDO:
1284 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
1285 case Mips::SZ_H_PSEUDO:
1286 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
1287 case Mips::SZ_W_PSEUDO:
1288 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
1289 case Mips::SZ_D_PSEUDO:
1290 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
1291 case Mips::SZ_V_PSEUDO:
1292 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
1293 case Mips::COPY_FW_PSEUDO:
1294 return emitCOPY_FW(MI, BB);
1295 case Mips::COPY_FD_PSEUDO:
1296 return emitCOPY_FD(MI, BB);
1297 case Mips::INSERT_FW_PSEUDO:
1298 return emitINSERT_FW(MI, BB);
1299 case Mips::INSERT_FD_PSEUDO:
1300 return emitINSERT_FD(MI, BB);
1301 case Mips::INSERT_B_VIDX_PSEUDO:
1302 case Mips::INSERT_B_VIDX64_PSEUDO:
1303 return emitINSERT_DF_VIDX(MI, BB, 1, false);
1304 case Mips::INSERT_H_VIDX_PSEUDO:
1305 case Mips::INSERT_H_VIDX64_PSEUDO:
1306 return emitINSERT_DF_VIDX(MI, BB, 2, false);
1307 case Mips::INSERT_W_VIDX_PSEUDO:
1308 case Mips::INSERT_W_VIDX64_PSEUDO:
1309 return emitINSERT_DF_VIDX(MI, BB, 4, false);
1310 case Mips::INSERT_D_VIDX_PSEUDO:
1311 case Mips::INSERT_D_VIDX64_PSEUDO:
1312 return emitINSERT_DF_VIDX(MI, BB, 8, false);
1313 case Mips::INSERT_FW_VIDX_PSEUDO:
1314 case Mips::INSERT_FW_VIDX64_PSEUDO:
1315 return emitINSERT_DF_VIDX(MI, BB, 4, true);
1316 case Mips::INSERT_FD_VIDX_PSEUDO:
1317 case Mips::INSERT_FD_VIDX64_PSEUDO:
1318 return emitINSERT_DF_VIDX(MI, BB, 8, true);
1319 case Mips::FILL_FW_PSEUDO:
1320 return emitFILL_FW(MI, BB);
1321 case Mips::FILL_FD_PSEUDO:
1322 return emitFILL_FD(MI, BB);
1323 case Mips::FEXP2_W_1_PSEUDO:
1324 return emitFEXP2_W_1(MI, BB);
1325 case Mips::FEXP2_D_1_PSEUDO:
1326 return emitFEXP2_D_1(MI, BB);
1327 }
1328}
1329
1330bool MipsSETargetLowering::isEligibleForTailCallOptimization(
1331 const CCState &CCInfo, unsigned NextStackOffset,
1332 const MipsFunctionInfo &FI) const {
1333 // Exception has to be cleared with eret.
1334 if (FI.isISR())
1335 return false;
1336
1337 // Return false if either the callee or caller has a byval argument.
1338 if (CCInfo.getInRegsParamsCount() > 0 || FI.hasByvalArg())
1339 return false;
1340
1341 // Return true if the callee's argument area is no larger than the caller's.
1342 return NextStackOffset <= FI.getIncomingArgSize();
1343}
1344
1345void MipsSETargetLowering::
1346getOpndList(SmallVectorImpl<SDValue> &Ops,
1347 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
1348 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
1349 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
1350 SDValue Chain) const {
1351 Ops.push_back(Callee);
1352 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
1353 InternalLinkage, IsCallReloc, CLI, Callee,
1354 Chain);
1355}
1356
1357SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
1358 LoadSDNode &Nd = *cast<LoadSDNode>(Op);
1359
1360 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
1361 return MipsTargetLowering::lowerLOAD(Op, DAG);
1362
1363 // Replace a double precision load with two i32 loads and a buildpair64.
1364 SDLoc DL(Op);
1365 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
1366 EVT PtrVT = Ptr.getValueType();
1367
1368 // i32 load from lower address.
1369 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, MachinePointerInfo(),
1370 Nd.getAlign(), Nd.getMemOperand()->getFlags());
1371
1372 // i32 load from higher address.
1373 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, DL, PtrVT));
1374 SDValue Hi = DAG.getLoad(
1375 MVT::i32, DL, Lo.getValue(1), Ptr, MachinePointerInfo(),
1377
1378 if (!Subtarget.isLittle())
1379 std::swap(Lo, Hi);
1380
1381 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
1382 SDValue Ops[2] = {BP, Hi.getValue(1)};
1383 return DAG.getMergeValues(Ops, DL);
1384}
1385
1386SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
1387 StoreSDNode &Nd = *cast<StoreSDNode>(Op);
1388
1389 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
1391
1392 // Replace a double precision store with two extractelement64s and i32 stores.
1393 SDLoc DL(Op);
1394 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
1395 EVT PtrVT = Ptr.getValueType();
1396 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
1397 Val, DAG.getConstant(0, DL, MVT::i32));
1398 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
1399 Val, DAG.getConstant(1, DL, MVT::i32));
1400
1401 if (!Subtarget.isLittle())
1402 std::swap(Lo, Hi);
1403
1404 // i32 store to lower address.
1405 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(), Nd.getAlign(),
1406 Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
1407
1408 // i32 store to higher address.
1409 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, DL, PtrVT));
1410 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
1411 commonAlignment(Nd.getAlign(), 4),
1412 Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
1413}
1414
1415SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op,
1416 SelectionDAG &DAG) const {
1417 SDLoc DL(Op);
1418 MVT Src = Op.getOperand(0).getValueType().getSimpleVT();
1419 MVT Dest = Op.getValueType().getSimpleVT();
1420
1421 // Bitcast i64 to double.
1422 if (Src == MVT::i64 && Dest == MVT::f64) {
1423 SDValue Lo, Hi;
1424 std::tie(Lo, Hi) =
1425 DAG.SplitScalar(Op.getOperand(0), DL, MVT::i32, MVT::i32);
1426 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
1427 }
1428
1429 // Bitcast double to i64.
1430 if (Src == MVT::f64 && Dest == MVT::i64) {
1431 // Skip lower bitcast when operand0 has converted float results to integer
1432 // which was done by function SoftenFloatResult.
1433 if (getTypeAction(*DAG.getContext(), Op.getOperand(0).getValueType()) ==
1435 return SDValue();
1436 SDValue Lo =
1437 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
1438 DAG.getConstant(0, DL, MVT::i32));
1439 SDValue Hi =
1440 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
1441 DAG.getConstant(1, DL, MVT::i32));
1442 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
1443 }
1444
1445 // Skip other cases of bitcast and use default lowering.
1446 return SDValue();
1447}
1448
1449SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
1450 bool HasLo, bool HasHi,
1451 SelectionDAG &DAG) const {
1452 // MIPS32r6/MIPS64r6 removed accumulator based multiplies.
1453 assert(!Subtarget.hasMips32r6());
1454
1455 EVT Ty = Op.getOperand(0).getValueType();
1456 SDLoc DL(Op);
1457 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
1458 Op.getOperand(0), Op.getOperand(1));
1459 SDValue Lo, Hi;
1460
1461 if (HasLo)
1462 Lo = DAG.getNode(MipsISD::MFLO, DL, Ty, Mult);
1463 if (HasHi)
1464 Hi = DAG.getNode(MipsISD::MFHI, DL, Ty, Mult);
1465
1466 if (!HasLo || !HasHi)
1467 return HasLo ? Lo : Hi;
1468
1469 SDValue Vals[] = { Lo, Hi };
1470 return DAG.getMergeValues(Vals, DL);
1471}
1472
1474 SDValue InLo, InHi;
1475 std::tie(InLo, InHi) = DAG.SplitScalar(In, DL, MVT::i32, MVT::i32);
1476 return DAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, InLo, InHi);
1477}
1478
1480 SDValue Lo = DAG.getNode(MipsISD::MFLO, DL, MVT::i32, Op);
1481 SDValue Hi = DAG.getNode(MipsISD::MFHI, DL, MVT::i32, Op);
1482 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
1483}
1484
1485// This function expands mips intrinsic nodes which have 64-bit input operands
1486// or output values.
1487//
1488// out64 = intrinsic-node in64
1489// =>
1490// lo = copy (extract-element (in64, 0))
1491// hi = copy (extract-element (in64, 1))
1492// mips-specific-node
1493// v0 = copy lo
1494// v1 = copy hi
1495// out64 = merge-values (v0, v1)
1496//
1498 SDLoc DL(Op);
1499 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
1501 unsigned OpNo = 0;
1502
1503 // See if Op has a chain input.
1504 if (HasChainIn)
1505 Ops.push_back(Op->getOperand(OpNo++));
1506
1507 // The next operand is the intrinsic opcode.
1508 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
1509
1510 // See if the next operand has type i64.
1511 SDValue Opnd = Op->getOperand(++OpNo), In64;
1512
1513 if (Opnd.getValueType() == MVT::i64)
1514 In64 = initAccumulator(Opnd, DL, DAG);
1515 else
1516 Ops.push_back(Opnd);
1517
1518 // Push the remaining operands.
1519 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
1520 Ops.push_back(Op->getOperand(OpNo));
1521
1522 // Add In64 to the end of the list.
1523 if (In64.getNode())
1524 Ops.push_back(In64);
1525
1526 // Scan output.
1527 SmallVector<EVT, 2> ResTys;
1528
1529 for (EVT Ty : Op->values())
1530 ResTys.push_back((Ty == MVT::i64) ? MVT::Untyped : Ty);
1531
1532 // Create node.
1533 SDValue Val = DAG.getNode(Opc, DL, ResTys, Ops);
1534 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
1535
1536 if (!HasChainIn)
1537 return Out;
1538
1539 assert(Val->getValueType(1) == MVT::Other);
1540 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
1541 return DAG.getMergeValues(Vals, DL);
1542}
1543
1544// Lower an MSA copy intrinsic into the specified SelectionDAG node
1546 SDLoc DL(Op);
1547 SDValue Vec = Op->getOperand(1);
1548 SDValue Idx = Op->getOperand(2);
1549 EVT ResTy = Op->getValueType(0);
1550 EVT EltTy = Vec->getValueType(0).getVectorElementType();
1551
1552 SDValue Result = DAG.getNode(Opc, DL, ResTy, Vec, Idx,
1553 DAG.getValueType(EltTy));
1554
1555 return Result;
1556}
1557
1558static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) {
1559 EVT ResVecTy = Op->getValueType(0);
1560 EVT ViaVecTy = ResVecTy;
1561 bool BigEndian = !DAG.getSubtarget().getTargetTriple().isLittleEndian();
1562 SDLoc DL(Op);
1563
1564 // When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and
1565 // LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating
1566 // lanes.
1567 SDValue LaneA = Op->getOperand(OpNr);
1568 SDValue LaneB;
1569
1570 if (ResVecTy == MVT::v2i64) {
1571 // In case of the index being passed as an immediate value, set the upper
1572 // lane to 0 so that the splati.d instruction can be matched.
1573 if (isa<ConstantSDNode>(LaneA))
1574 LaneB = DAG.getConstant(0, DL, MVT::i32);
1575 // Having the index passed in a register, set the upper lane to the same
1576 // value as the lower - this results in the BUILD_VECTOR node not being
1577 // expanded through stack. This way we are able to pattern match the set of
1578 // nodes created here to splat.d.
1579 else
1580 LaneB = LaneA;
1581 ViaVecTy = MVT::v4i32;
1582 if(BigEndian)
1583 std::swap(LaneA, LaneB);
1584 } else
1585 LaneB = LaneA;
1586
1587 SDValue Ops[16] = { LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB,
1588 LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB };
1589
1590 SDValue Result = DAG.getBuildVector(
1591 ViaVecTy, DL, ArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1592
1593 if (ViaVecTy != ResVecTy) {
1594 SDValue One = DAG.getConstant(1, DL, ViaVecTy);
1595 Result = DAG.getNode(ISD::BITCAST, DL, ResVecTy,
1596 DAG.getNode(ISD::AND, DL, ViaVecTy, Result, One));
1597 }
1598
1599 return Result;
1600}
1601
1602static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG,
1603 bool IsSigned = false) {
1604 auto *CImm = cast<ConstantSDNode>(Op->getOperand(ImmOp));
1605 return DAG.getConstant(
1606 APInt(Op->getValueType(0).getScalarType().getSizeInBits(),
1607 IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
1608 SDLoc(Op), Op->getValueType(0));
1609}
1610
1611static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue,
1612 bool BigEndian, SelectionDAG &DAG) {
1613 EVT ViaVecTy = VecTy;
1614 SDValue SplatValueA = SplatValue;
1615 SDValue SplatValueB = SplatValue;
1616 SDLoc DL(SplatValue);
1617
1618 if (VecTy == MVT::v2i64) {
1619 // v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's.
1620 ViaVecTy = MVT::v4i32;
1621
1622 SplatValueA = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValue);
1623 SplatValueB = DAG.getNode(ISD::SRL, DL, MVT::i64, SplatValue,
1624 DAG.getConstant(32, DL, MVT::i32));
1625 SplatValueB = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValueB);
1626 }
1627
1628 // We currently hold the parts in little endian order. Swap them if
1629 // necessary.
1630 if (BigEndian)
1631 std::swap(SplatValueA, SplatValueB);
1632
1633 SDValue Ops[16] = { SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1634 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1635 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1636 SplatValueA, SplatValueB, SplatValueA, SplatValueB };
1637
1638 SDValue Result = DAG.getBuildVector(
1639 ViaVecTy, DL, ArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1640
1641 if (VecTy != ViaVecTy)
1642 Result = DAG.getNode(ISD::BITCAST, DL, VecTy, Result);
1643
1644 return Result;
1645}
1646
1648 unsigned Opc, SDValue Imm,
1649 bool BigEndian) {
1650 EVT VecTy = Op->getValueType(0);
1651 SDValue Exp2Imm;
1652 SDLoc DL(Op);
1653
1654 // The DAG Combiner can't constant fold bitcasted vectors yet so we must do it
1655 // here for now.
1656 if (VecTy == MVT::v2i64) {
1657 if (ConstantSDNode *CImm = dyn_cast<ConstantSDNode>(Imm)) {
1658 APInt BitImm = APInt(64, 1) << CImm->getAPIntValue();
1659
1660 SDValue BitImmHiOp = DAG.getConstant(BitImm.lshr(32).trunc(32), DL,
1661 MVT::i32);
1662 SDValue BitImmLoOp = DAG.getConstant(BitImm.trunc(32), DL, MVT::i32);
1663
1664 if (BigEndian)
1665 std::swap(BitImmLoOp, BitImmHiOp);
1666
1667 Exp2Imm = DAG.getNode(
1668 ISD::BITCAST, DL, MVT::v2i64,
1669 DAG.getBuildVector(MVT::v4i32, DL,
1670 {BitImmLoOp, BitImmHiOp, BitImmLoOp, BitImmHiOp}));
1671 }
1672 }
1673
1674 if (!Exp2Imm.getNode()) {
1675 // We couldnt constant fold, do a vector shift instead
1676
1677 // Extend i32 to i64 if necessary. Sign or zero extend doesn't matter since
1678 // only values 0-63 are valid.
1679 if (VecTy == MVT::v2i64)
1680 Imm = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Imm);
1681
1682 Exp2Imm = getBuildVectorSplat(VecTy, Imm, BigEndian, DAG);
1683
1684 Exp2Imm = DAG.getNode(ISD::SHL, DL, VecTy, DAG.getConstant(1, DL, VecTy),
1685 Exp2Imm);
1686 }
1687
1688 return DAG.getNode(Opc, DL, VecTy, Op->getOperand(1), Exp2Imm);
1689}
1690
1692 SDLoc DL(Op);
1693 EVT ResTy = Op->getValueType(0);
1694 SDValue Vec = Op->getOperand(2);
1695 bool BigEndian = !DAG.getSubtarget().getTargetTriple().isLittleEndian();
1696 MVT ResEltTy = ResTy == MVT::v2i64 ? MVT::i64 : MVT::i32;
1697 SDValue ConstValue = DAG.getConstant(Vec.getScalarValueSizeInBits() - 1,
1698 DL, ResEltTy);
1699 SDValue SplatVec = getBuildVectorSplat(ResTy, ConstValue, BigEndian, DAG);
1700
1701 return DAG.getNode(ISD::AND, DL, ResTy, Vec, SplatVec);
1702}
1703
1705 EVT ResTy = Op->getValueType(0);
1706 SDLoc DL(Op);
1707 SDValue One = DAG.getConstant(1, DL, ResTy);
1708 SDValue Bit = DAG.getNode(ISD::SHL, DL, ResTy, One, truncateVecElts(Op, DAG));
1709
1710 return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1),
1711 DAG.getNOT(DL, Bit, ResTy));
1712}
1713
1715 SDLoc DL(Op);
1716 EVT ResTy = Op->getValueType(0);
1717 APInt BitImm = APInt(ResTy.getScalarSizeInBits(), 1)
1718 << Op->getConstantOperandAPInt(2);
1719 SDValue BitMask = DAG.getConstant(~BitImm, DL, ResTy);
1720
1721 return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1), BitMask);
1722}
1723
1724SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
1725 SelectionDAG &DAG) const {
1726 SDLoc DL(Op);
1727 unsigned Intrinsic = Op->getConstantOperandVal(0);
1728 switch (Intrinsic) {
1729 default:
1730 return SDValue();
1731 case Intrinsic::mips_shilo:
1732 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
1733 case Intrinsic::mips_dpau_h_qbl:
1734 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
1735 case Intrinsic::mips_dpau_h_qbr:
1736 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
1737 case Intrinsic::mips_dpsu_h_qbl:
1738 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
1739 case Intrinsic::mips_dpsu_h_qbr:
1740 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
1741 case Intrinsic::mips_dpa_w_ph:
1742 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
1743 case Intrinsic::mips_dps_w_ph:
1744 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
1745 case Intrinsic::mips_dpax_w_ph:
1746 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
1747 case Intrinsic::mips_dpsx_w_ph:
1748 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
1749 case Intrinsic::mips_mulsa_w_ph:
1750 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
1751 case Intrinsic::mips_mult:
1752 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
1753 case Intrinsic::mips_multu:
1754 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
1755 case Intrinsic::mips_madd:
1756 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
1757 case Intrinsic::mips_maddu:
1758 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
1759 case Intrinsic::mips_msub:
1760 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
1761 case Intrinsic::mips_msubu:
1762 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
1763 case Intrinsic::mips_addv_b:
1764 case Intrinsic::mips_addv_h:
1765 case Intrinsic::mips_addv_w:
1766 case Intrinsic::mips_addv_d:
1767 return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1),
1768 Op->getOperand(2));
1769 case Intrinsic::mips_addvi_b:
1770 case Intrinsic::mips_addvi_h:
1771 case Intrinsic::mips_addvi_w:
1772 case Intrinsic::mips_addvi_d:
1773 return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1),
1774 lowerMSASplatImm(Op, 2, DAG));
1775 case Intrinsic::mips_and_v:
1776 return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1),
1777 Op->getOperand(2));
1778 case Intrinsic::mips_andi_b:
1779 return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1),
1780 lowerMSASplatImm(Op, 2, DAG));
1781 case Intrinsic::mips_bclr_b:
1782 case Intrinsic::mips_bclr_h:
1783 case Intrinsic::mips_bclr_w:
1784 case Intrinsic::mips_bclr_d:
1785 return lowerMSABitClear(Op, DAG);
1786 case Intrinsic::mips_bclri_b:
1787 case Intrinsic::mips_bclri_h:
1788 case Intrinsic::mips_bclri_w:
1789 case Intrinsic::mips_bclri_d:
1790 return lowerMSABitClearImm(Op, DAG);
1791 case Intrinsic::mips_binsli_b:
1792 case Intrinsic::mips_binsli_h:
1793 case Intrinsic::mips_binsli_w:
1794 case Intrinsic::mips_binsli_d: {
1795 // binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear)
1796 EVT VecTy = Op->getValueType(0);
1797 EVT EltTy = VecTy.getVectorElementType();
1798 if (Op->getConstantOperandVal(3) >= EltTy.getSizeInBits())
1799 report_fatal_error("Immediate out of range");
1801 Op->getConstantOperandVal(3) + 1);
1802 return DAG.getNode(ISD::VSELECT, DL, VecTy,
1803 DAG.getConstant(Mask, DL, VecTy, true),
1804 Op->getOperand(2), Op->getOperand(1));
1805 }
1806 case Intrinsic::mips_binsri_b:
1807 case Intrinsic::mips_binsri_h:
1808 case Intrinsic::mips_binsri_w:
1809 case Intrinsic::mips_binsri_d: {
1810 // binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear)
1811 EVT VecTy = Op->getValueType(0);
1812 EVT EltTy = VecTy.getVectorElementType();
1813 if (Op->getConstantOperandVal(3) >= EltTy.getSizeInBits())
1814 report_fatal_error("Immediate out of range");
1815 APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(),
1816 Op->getConstantOperandVal(3) + 1);
1817 return DAG.getNode(ISD::VSELECT, DL, VecTy,
1818 DAG.getConstant(Mask, DL, VecTy, true),
1819 Op->getOperand(2), Op->getOperand(1));
1820 }
1821 case Intrinsic::mips_bmnz_v:
1822 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
1823 Op->getOperand(2), Op->getOperand(1));
1824 case Intrinsic::mips_bmnzi_b:
1825 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1826 lowerMSASplatImm(Op, 3, DAG), Op->getOperand(2),
1827 Op->getOperand(1));
1828 case Intrinsic::mips_bmz_v:
1829 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
1830 Op->getOperand(1), Op->getOperand(2));
1831 case Intrinsic::mips_bmzi_b:
1832 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1833 lowerMSASplatImm(Op, 3, DAG), Op->getOperand(1),
1834 Op->getOperand(2));
1835 case Intrinsic::mips_bneg_b:
1836 case Intrinsic::mips_bneg_h:
1837 case Intrinsic::mips_bneg_w:
1838 case Intrinsic::mips_bneg_d: {
1839 EVT VecTy = Op->getValueType(0);
1840 SDValue One = DAG.getConstant(1, DL, VecTy);
1841
1842 return DAG.getNode(ISD::XOR, DL, VecTy, Op->getOperand(1),
1843 DAG.getNode(ISD::SHL, DL, VecTy, One,
1844 truncateVecElts(Op, DAG)));
1845 }
1846 case Intrinsic::mips_bnegi_b:
1847 case Intrinsic::mips_bnegi_h:
1848 case Intrinsic::mips_bnegi_w:
1849 case Intrinsic::mips_bnegi_d:
1850 return lowerMSABinaryBitImmIntr(Op, DAG, ISD::XOR, Op->getOperand(2),
1851 !Subtarget.isLittle());
1852 case Intrinsic::mips_bnz_b:
1853 case Intrinsic::mips_bnz_h:
1854 case Intrinsic::mips_bnz_w:
1855 case Intrinsic::mips_bnz_d:
1856 return DAG.getNode(MipsISD::VALL_NONZERO, DL, Op->getValueType(0),
1857 Op->getOperand(1));
1858 case Intrinsic::mips_bnz_v:
1859 return DAG.getNode(MipsISD::VANY_NONZERO, DL, Op->getValueType(0),
1860 Op->getOperand(1));
1861 case Intrinsic::mips_bsel_v:
1862 // bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1863 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1864 Op->getOperand(1), Op->getOperand(3),
1865 Op->getOperand(2));
1866 case Intrinsic::mips_bseli_b:
1867 // bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1868 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1869 Op->getOperand(1), lowerMSASplatImm(Op, 3, DAG),
1870 Op->getOperand(2));
1871 case Intrinsic::mips_bset_b:
1872 case Intrinsic::mips_bset_h:
1873 case Intrinsic::mips_bset_w:
1874 case Intrinsic::mips_bset_d: {
1875 EVT VecTy = Op->getValueType(0);
1876 SDValue One = DAG.getConstant(1, DL, VecTy);
1877
1878 return DAG.getNode(ISD::OR, DL, VecTy, Op->getOperand(1),
1879 DAG.getNode(ISD::SHL, DL, VecTy, One,
1880 truncateVecElts(Op, DAG)));
1881 }
1882 case Intrinsic::mips_bseti_b:
1883 case Intrinsic::mips_bseti_h:
1884 case Intrinsic::mips_bseti_w:
1885 case Intrinsic::mips_bseti_d:
1886 return lowerMSABinaryBitImmIntr(Op, DAG, ISD::OR, Op->getOperand(2),
1887 !Subtarget.isLittle());
1888 case Intrinsic::mips_bz_b:
1889 case Intrinsic::mips_bz_h:
1890 case Intrinsic::mips_bz_w:
1891 case Intrinsic::mips_bz_d:
1892 return DAG.getNode(MipsISD::VALL_ZERO, DL, Op->getValueType(0),
1893 Op->getOperand(1));
1894 case Intrinsic::mips_bz_v:
1895 return DAG.getNode(MipsISD::VANY_ZERO, DL, Op->getValueType(0),
1896 Op->getOperand(1));
1897 case Intrinsic::mips_ceq_b:
1898 case Intrinsic::mips_ceq_h:
1899 case Intrinsic::mips_ceq_w:
1900 case Intrinsic::mips_ceq_d:
1901 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1902 Op->getOperand(2), ISD::SETEQ);
1903 case Intrinsic::mips_ceqi_b:
1904 case Intrinsic::mips_ceqi_h:
1905 case Intrinsic::mips_ceqi_w:
1906 case Intrinsic::mips_ceqi_d:
1907 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1908 lowerMSASplatImm(Op, 2, DAG, true), ISD::SETEQ);
1909 case Intrinsic::mips_cle_s_b:
1910 case Intrinsic::mips_cle_s_h:
1911 case Intrinsic::mips_cle_s_w:
1912 case Intrinsic::mips_cle_s_d:
1913 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1914 Op->getOperand(2), ISD::SETLE);
1915 case Intrinsic::mips_clei_s_b:
1916 case Intrinsic::mips_clei_s_h:
1917 case Intrinsic::mips_clei_s_w:
1918 case Intrinsic::mips_clei_s_d:
1919 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1920 lowerMSASplatImm(Op, 2, DAG, true), ISD::SETLE);
1921 case Intrinsic::mips_cle_u_b:
1922 case Intrinsic::mips_cle_u_h:
1923 case Intrinsic::mips_cle_u_w:
1924 case Intrinsic::mips_cle_u_d:
1925 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1926 Op->getOperand(2), ISD::SETULE);
1927 case Intrinsic::mips_clei_u_b:
1928 case Intrinsic::mips_clei_u_h:
1929 case Intrinsic::mips_clei_u_w:
1930 case Intrinsic::mips_clei_u_d:
1931 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1932 lowerMSASplatImm(Op, 2, DAG), ISD::SETULE);
1933 case Intrinsic::mips_clt_s_b:
1934 case Intrinsic::mips_clt_s_h:
1935 case Intrinsic::mips_clt_s_w:
1936 case Intrinsic::mips_clt_s_d:
1937 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1938 Op->getOperand(2), ISD::SETLT);
1939 case Intrinsic::mips_clti_s_b:
1940 case Intrinsic::mips_clti_s_h:
1941 case Intrinsic::mips_clti_s_w:
1942 case Intrinsic::mips_clti_s_d:
1943 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1944 lowerMSASplatImm(Op, 2, DAG, true), ISD::SETLT);
1945 case Intrinsic::mips_clt_u_b:
1946 case Intrinsic::mips_clt_u_h:
1947 case Intrinsic::mips_clt_u_w:
1948 case Intrinsic::mips_clt_u_d:
1949 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1950 Op->getOperand(2), ISD::SETULT);
1951 case Intrinsic::mips_clti_u_b:
1952 case Intrinsic::mips_clti_u_h:
1953 case Intrinsic::mips_clti_u_w:
1954 case Intrinsic::mips_clti_u_d:
1955 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1956 lowerMSASplatImm(Op, 2, DAG), ISD::SETULT);
1957 case Intrinsic::mips_copy_s_b:
1958 case Intrinsic::mips_copy_s_h:
1959 case Intrinsic::mips_copy_s_w:
1960 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT);
1961 case Intrinsic::mips_copy_s_d:
1962 if (Subtarget.hasMips64())
1963 // Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64.
1964 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT);
1965 else {
1966 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
1967 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
1968 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
1969 Op->getValueType(0), Op->getOperand(1),
1970 Op->getOperand(2));
1971 }
1972 case Intrinsic::mips_copy_u_b:
1973 case Intrinsic::mips_copy_u_h:
1974 case Intrinsic::mips_copy_u_w:
1975 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT);
1976 case Intrinsic::mips_copy_u_d:
1977 if (Subtarget.hasMips64())
1978 // Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64.
1979 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT);
1980 else {
1981 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
1982 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
1983 // Note: When i64 is illegal, this results in copy_s.w instructions
1984 // instead of copy_u.w instructions. This makes no difference to the
1985 // behaviour since i64 is only illegal when the register file is 32-bit.
1986 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
1987 Op->getValueType(0), Op->getOperand(1),
1988 Op->getOperand(2));
1989 }
1990 case Intrinsic::mips_div_s_b:
1991 case Intrinsic::mips_div_s_h:
1992 case Intrinsic::mips_div_s_w:
1993 case Intrinsic::mips_div_s_d:
1994 return DAG.getNode(ISD::SDIV, DL, Op->getValueType(0), Op->getOperand(1),
1995 Op->getOperand(2));
1996 case Intrinsic::mips_div_u_b:
1997 case Intrinsic::mips_div_u_h:
1998 case Intrinsic::mips_div_u_w:
1999 case Intrinsic::mips_div_u_d:
2000 return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1),
2001 Op->getOperand(2));
2002 case Intrinsic::mips_fadd_w:
2003 case Intrinsic::mips_fadd_d:
2004 // TODO: If intrinsics have fast-math-flags, propagate them.
2005 return DAG.getNode(ISD::FADD, DL, Op->getValueType(0), Op->getOperand(1),
2006 Op->getOperand(2));
2007 // Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away
2008 case Intrinsic::mips_fceq_w:
2009 case Intrinsic::mips_fceq_d:
2010 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2011 Op->getOperand(2), ISD::SETOEQ);
2012 case Intrinsic::mips_fcle_w:
2013 case Intrinsic::mips_fcle_d:
2014 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2015 Op->getOperand(2), ISD::SETOLE);
2016 case Intrinsic::mips_fclt_w:
2017 case Intrinsic::mips_fclt_d:
2018 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2019 Op->getOperand(2), ISD::SETOLT);
2020 case Intrinsic::mips_fcne_w:
2021 case Intrinsic::mips_fcne_d:
2022 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2023 Op->getOperand(2), ISD::SETONE);
2024 case Intrinsic::mips_fcor_w:
2025 case Intrinsic::mips_fcor_d:
2026 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2027 Op->getOperand(2), ISD::SETO);
2028 case Intrinsic::mips_fcueq_w:
2029 case Intrinsic::mips_fcueq_d:
2030 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2031 Op->getOperand(2), ISD::SETUEQ);
2032 case Intrinsic::mips_fcule_w:
2033 case Intrinsic::mips_fcule_d:
2034 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2035 Op->getOperand(2), ISD::SETULE);
2036 case Intrinsic::mips_fcult_w:
2037 case Intrinsic::mips_fcult_d:
2038 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2039 Op->getOperand(2), ISD::SETULT);
2040 case Intrinsic::mips_fcun_w:
2041 case Intrinsic::mips_fcun_d:
2042 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2043 Op->getOperand(2), ISD::SETUO);
2044 case Intrinsic::mips_fcune_w:
2045 case Intrinsic::mips_fcune_d:
2046 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
2047 Op->getOperand(2), ISD::SETUNE);
2048 case Intrinsic::mips_fdiv_w:
2049 case Intrinsic::mips_fdiv_d:
2050 // TODO: If intrinsics have fast-math-flags, propagate them.
2051 return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1),
2052 Op->getOperand(2));
2053 case Intrinsic::mips_ffint_u_w:
2054 case Intrinsic::mips_ffint_u_d:
2055 return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0),
2056 Op->getOperand(1));
2057 case Intrinsic::mips_ffint_s_w:
2058 case Intrinsic::mips_ffint_s_d:
2059 return DAG.getNode(ISD::SINT_TO_FP, DL, Op->getValueType(0),
2060 Op->getOperand(1));
2061 case Intrinsic::mips_fill_b:
2062 case Intrinsic::mips_fill_h:
2063 case Intrinsic::mips_fill_w:
2064 case Intrinsic::mips_fill_d: {
2065 EVT ResTy = Op->getValueType(0);
2067 Op->getOperand(1));
2068
2069 // If ResTy is v2i64 then the type legalizer will break this node down into
2070 // an equivalent v4i32.
2071 return DAG.getBuildVector(ResTy, DL, Ops);
2072 }
2073 case Intrinsic::mips_fexp2_w:
2074 case Intrinsic::mips_fexp2_d: {
2075 // TODO: If intrinsics have fast-math-flags, propagate them.
2076 EVT ResTy = Op->getValueType(0);
2077 return DAG.getNode(
2078 ISD::FMUL, SDLoc(Op), ResTy, Op->getOperand(1),
2079 DAG.getNode(ISD::FEXP2, SDLoc(Op), ResTy, Op->getOperand(2)));
2080 }
2081 case Intrinsic::mips_flog2_w:
2082 case Intrinsic::mips_flog2_d:
2083 return DAG.getNode(ISD::FLOG2, DL, Op->getValueType(0), Op->getOperand(1));
2084 case Intrinsic::mips_fmadd_w:
2085 case Intrinsic::mips_fmadd_d:
2086 return DAG.getNode(ISD::FMA, SDLoc(Op), Op->getValueType(0),
2087 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
2088 case Intrinsic::mips_fmul_w:
2089 case Intrinsic::mips_fmul_d:
2090 // TODO: If intrinsics have fast-math-flags, propagate them.
2091 return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1),
2092 Op->getOperand(2));
2093 case Intrinsic::mips_fmsub_w:
2094 case Intrinsic::mips_fmsub_d: {
2095 // TODO: If intrinsics have fast-math-flags, propagate them.
2096 return DAG.getNode(MipsISD::FMS, SDLoc(Op), Op->getValueType(0),
2097 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
2098 }
2099 case Intrinsic::mips_frint_w:
2100 case Intrinsic::mips_frint_d:
2101 return DAG.getNode(ISD::FRINT, DL, Op->getValueType(0), Op->getOperand(1));
2102 case Intrinsic::mips_fsqrt_w:
2103 case Intrinsic::mips_fsqrt_d:
2104 return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1));
2105 case Intrinsic::mips_fsub_w:
2106 case Intrinsic::mips_fsub_d:
2107 // TODO: If intrinsics have fast-math-flags, propagate them.
2108 return DAG.getNode(ISD::FSUB, DL, Op->getValueType(0), Op->getOperand(1),
2109 Op->getOperand(2));
2110 case Intrinsic::mips_ftrunc_u_w:
2111 case Intrinsic::mips_ftrunc_u_d:
2112 return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0),
2113 Op->getOperand(1));
2114 case Intrinsic::mips_ftrunc_s_w:
2115 case Intrinsic::mips_ftrunc_s_d:
2116 return DAG.getNode(ISD::FP_TO_SINT, DL, Op->getValueType(0),
2117 Op->getOperand(1));
2118 case Intrinsic::mips_ilvev_b:
2119 case Intrinsic::mips_ilvev_h:
2120 case Intrinsic::mips_ilvev_w:
2121 case Intrinsic::mips_ilvev_d:
2122 return DAG.getNode(MipsISD::ILVEV, DL, Op->getValueType(0),
2123 Op->getOperand(1), Op->getOperand(2));
2124 case Intrinsic::mips_ilvl_b:
2125 case Intrinsic::mips_ilvl_h:
2126 case Intrinsic::mips_ilvl_w:
2127 case Intrinsic::mips_ilvl_d:
2128 return DAG.getNode(MipsISD::ILVL, DL, Op->getValueType(0),
2129 Op->getOperand(1), Op->getOperand(2));
2130 case Intrinsic::mips_ilvod_b:
2131 case Intrinsic::mips_ilvod_h:
2132 case Intrinsic::mips_ilvod_w:
2133 case Intrinsic::mips_ilvod_d:
2134 return DAG.getNode(MipsISD::ILVOD, DL, Op->getValueType(0),
2135 Op->getOperand(1), Op->getOperand(2));
2136 case Intrinsic::mips_ilvr_b:
2137 case Intrinsic::mips_ilvr_h:
2138 case Intrinsic::mips_ilvr_w:
2139 case Intrinsic::mips_ilvr_d:
2140 return DAG.getNode(MipsISD::ILVR, DL, Op->getValueType(0),
2141 Op->getOperand(1), Op->getOperand(2));
2142 case Intrinsic::mips_insert_b:
2143 case Intrinsic::mips_insert_h:
2144 case Intrinsic::mips_insert_w:
2145 case Intrinsic::mips_insert_d:
2146 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), Op->getValueType(0),
2147 Op->getOperand(1), Op->getOperand(3), Op->getOperand(2));
2148 case Intrinsic::mips_insve_b:
2149 case Intrinsic::mips_insve_h:
2150 case Intrinsic::mips_insve_w:
2151 case Intrinsic::mips_insve_d: {
2152 // Report an error for out of range values.
2153 int64_t Max;
2154 switch (Intrinsic) {
2155 case Intrinsic::mips_insve_b: Max = 15; break;
2156 case Intrinsic::mips_insve_h: Max = 7; break;
2157 case Intrinsic::mips_insve_w: Max = 3; break;
2158 case Intrinsic::mips_insve_d: Max = 1; break;
2159 default: llvm_unreachable("Unmatched intrinsic");
2160 }
2161 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2162 if (Value < 0 || Value > Max)
2163 report_fatal_error("Immediate out of range");
2164 return DAG.getNode(MipsISD::INSVE, DL, Op->getValueType(0),
2165 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3),
2166 DAG.getConstant(0, DL, MVT::i32));
2167 }
2168 case Intrinsic::mips_ldi_b:
2169 case Intrinsic::mips_ldi_h:
2170 case Intrinsic::mips_ldi_w:
2171 case Intrinsic::mips_ldi_d:
2172 return lowerMSASplatImm(Op, 1, DAG, true);
2173 case Intrinsic::mips_lsa:
2174 case Intrinsic::mips_dlsa: {
2175 EVT ResTy = Op->getValueType(0);
2176 return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1),
2177 DAG.getNode(ISD::SHL, SDLoc(Op), ResTy,
2178 Op->getOperand(2), Op->getOperand(3)));
2179 }
2180 case Intrinsic::mips_maddv_b:
2181 case Intrinsic::mips_maddv_h:
2182 case Intrinsic::mips_maddv_w:
2183 case Intrinsic::mips_maddv_d: {
2184 EVT ResTy = Op->getValueType(0);
2185 return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1),
2186 DAG.getNode(ISD::MUL, SDLoc(Op), ResTy,
2187 Op->getOperand(2), Op->getOperand(3)));
2188 }
2189 case Intrinsic::mips_max_s_b:
2190 case Intrinsic::mips_max_s_h:
2191 case Intrinsic::mips_max_s_w:
2192 case Intrinsic::mips_max_s_d:
2193 return DAG.getNode(ISD::SMAX, DL, Op->getValueType(0),
2194 Op->getOperand(1), Op->getOperand(2));
2195 case Intrinsic::mips_max_u_b:
2196 case Intrinsic::mips_max_u_h:
2197 case Intrinsic::mips_max_u_w:
2198 case Intrinsic::mips_max_u_d:
2199 return DAG.getNode(ISD::UMAX, DL, Op->getValueType(0),
2200 Op->getOperand(1), Op->getOperand(2));
2201 case Intrinsic::mips_maxi_s_b:
2202 case Intrinsic::mips_maxi_s_h:
2203 case Intrinsic::mips_maxi_s_w:
2204 case Intrinsic::mips_maxi_s_d:
2205 return DAG.getNode(ISD::SMAX, DL, Op->getValueType(0),
2206 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG, true));
2207 case Intrinsic::mips_maxi_u_b:
2208 case Intrinsic::mips_maxi_u_h:
2209 case Intrinsic::mips_maxi_u_w:
2210 case Intrinsic::mips_maxi_u_d:
2211 return DAG.getNode(ISD::UMAX, DL, Op->getValueType(0),
2212 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2213 case Intrinsic::mips_min_s_b:
2214 case Intrinsic::mips_min_s_h:
2215 case Intrinsic::mips_min_s_w:
2216 case Intrinsic::mips_min_s_d:
2217 return DAG.getNode(ISD::SMIN, DL, Op->getValueType(0),
2218 Op->getOperand(1), Op->getOperand(2));
2219 case Intrinsic::mips_min_u_b:
2220 case Intrinsic::mips_min_u_h:
2221 case Intrinsic::mips_min_u_w:
2222 case Intrinsic::mips_min_u_d:
2223 return DAG.getNode(ISD::UMIN, DL, Op->getValueType(0),
2224 Op->getOperand(1), Op->getOperand(2));
2225 case Intrinsic::mips_mini_s_b:
2226 case Intrinsic::mips_mini_s_h:
2227 case Intrinsic::mips_mini_s_w:
2228 case Intrinsic::mips_mini_s_d:
2229 return DAG.getNode(ISD::SMIN, DL, Op->getValueType(0),
2230 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG, true));
2231 case Intrinsic::mips_mini_u_b:
2232 case Intrinsic::mips_mini_u_h:
2233 case Intrinsic::mips_mini_u_w:
2234 case Intrinsic::mips_mini_u_d:
2235 return DAG.getNode(ISD::UMIN, DL, Op->getValueType(0),
2236 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2237 case Intrinsic::mips_mod_s_b:
2238 case Intrinsic::mips_mod_s_h:
2239 case Intrinsic::mips_mod_s_w:
2240 case Intrinsic::mips_mod_s_d:
2241 return DAG.getNode(ISD::SREM, DL, Op->getValueType(0), Op->getOperand(1),
2242 Op->getOperand(2));
2243 case Intrinsic::mips_mod_u_b:
2244 case Intrinsic::mips_mod_u_h:
2245 case Intrinsic::mips_mod_u_w:
2246 case Intrinsic::mips_mod_u_d:
2247 return DAG.getNode(ISD::UREM, DL, Op->getValueType(0), Op->getOperand(1),
2248 Op->getOperand(2));
2249 case Intrinsic::mips_mulv_b:
2250 case Intrinsic::mips_mulv_h:
2251 case Intrinsic::mips_mulv_w:
2252 case Intrinsic::mips_mulv_d:
2253 return DAG.getNode(ISD::MUL, DL, Op->getValueType(0), Op->getOperand(1),
2254 Op->getOperand(2));
2255 case Intrinsic::mips_msubv_b:
2256 case Intrinsic::mips_msubv_h:
2257 case Intrinsic::mips_msubv_w:
2258 case Intrinsic::mips_msubv_d: {
2259 EVT ResTy = Op->getValueType(0);
2260 return DAG.getNode(ISD::SUB, SDLoc(Op), ResTy, Op->getOperand(1),
2261 DAG.getNode(ISD::MUL, SDLoc(Op), ResTy,
2262 Op->getOperand(2), Op->getOperand(3)));
2263 }
2264 case Intrinsic::mips_nlzc_b:
2265 case Intrinsic::mips_nlzc_h:
2266 case Intrinsic::mips_nlzc_w:
2267 case Intrinsic::mips_nlzc_d:
2268 return DAG.getNode(ISD::CTLZ, DL, Op->getValueType(0), Op->getOperand(1));
2269 case Intrinsic::mips_nor_v: {
2270 SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2271 Op->getOperand(1), Op->getOperand(2));
2272 return DAG.getNOT(DL, Res, Res->getValueType(0));
2273 }
2274 case Intrinsic::mips_nori_b: {
2275 SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2276 Op->getOperand(1),
2277 lowerMSASplatImm(Op, 2, DAG));
2278 return DAG.getNOT(DL, Res, Res->getValueType(0));
2279 }
2280 case Intrinsic::mips_or_v:
2281 return DAG.getNode(ISD::OR, DL, Op->getValueType(0), Op->getOperand(1),
2282 Op->getOperand(2));
2283 case Intrinsic::mips_ori_b:
2284 return DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2285 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2286 case Intrinsic::mips_pckev_b:
2287 case Intrinsic::mips_pckev_h:
2288 case Intrinsic::mips_pckev_w:
2289 case Intrinsic::mips_pckev_d:
2290 return DAG.getNode(MipsISD::PCKEV, DL, Op->getValueType(0),
2291 Op->getOperand(1), Op->getOperand(2));
2292 case Intrinsic::mips_pckod_b:
2293 case Intrinsic::mips_pckod_h:
2294 case Intrinsic::mips_pckod_w:
2295 case Intrinsic::mips_pckod_d:
2296 return DAG.getNode(MipsISD::PCKOD, DL, Op->getValueType(0),
2297 Op->getOperand(1), Op->getOperand(2));
2298 case Intrinsic::mips_pcnt_b:
2299 case Intrinsic::mips_pcnt_h:
2300 case Intrinsic::mips_pcnt_w:
2301 case Intrinsic::mips_pcnt_d:
2302 return DAG.getNode(ISD::CTPOP, DL, Op->getValueType(0), Op->getOperand(1));
2303 case Intrinsic::mips_sat_s_b:
2304 case Intrinsic::mips_sat_s_h:
2305 case Intrinsic::mips_sat_s_w:
2306 case Intrinsic::mips_sat_s_d:
2307 case Intrinsic::mips_sat_u_b:
2308 case Intrinsic::mips_sat_u_h:
2309 case Intrinsic::mips_sat_u_w:
2310 case Intrinsic::mips_sat_u_d: {
2311 // Report an error for out of range values.
2312 int64_t Max;
2313 switch (Intrinsic) {
2314 case Intrinsic::mips_sat_s_b:
2315 case Intrinsic::mips_sat_u_b: Max = 7; break;
2316 case Intrinsic::mips_sat_s_h:
2317 case Intrinsic::mips_sat_u_h: Max = 15; break;
2318 case Intrinsic::mips_sat_s_w:
2319 case Intrinsic::mips_sat_u_w: Max = 31; break;
2320 case Intrinsic::mips_sat_s_d:
2321 case Intrinsic::mips_sat_u_d: Max = 63; break;
2322 default: llvm_unreachable("Unmatched intrinsic");
2323 }
2324 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2325 if (Value < 0 || Value > Max)
2326 report_fatal_error("Immediate out of range");
2327 return SDValue();
2328 }
2329 case Intrinsic::mips_shf_b:
2330 case Intrinsic::mips_shf_h:
2331 case Intrinsic::mips_shf_w: {
2332 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2333 if (Value < 0 || Value > 255)
2334 report_fatal_error("Immediate out of range");
2335 return DAG.getNode(MipsISD::SHF, DL, Op->getValueType(0),
2336 Op->getOperand(2), Op->getOperand(1));
2337 }
2338 case Intrinsic::mips_sldi_b:
2339 case Intrinsic::mips_sldi_h:
2340 case Intrinsic::mips_sldi_w:
2341 case Intrinsic::mips_sldi_d: {
2342 // Report an error for out of range values.
2343 int64_t Max;
2344 switch (Intrinsic) {
2345 case Intrinsic::mips_sldi_b: Max = 15; break;
2346 case Intrinsic::mips_sldi_h: Max = 7; break;
2347 case Intrinsic::mips_sldi_w: Max = 3; break;
2348 case Intrinsic::mips_sldi_d: Max = 1; break;
2349 default: llvm_unreachable("Unmatched intrinsic");
2350 }
2351 int64_t Value = cast<ConstantSDNode>(Op->getOperand(3))->getSExtValue();
2352 if (Value < 0 || Value > Max)
2353 report_fatal_error("Immediate out of range");
2354 return SDValue();
2355 }
2356 case Intrinsic::mips_sll_b:
2357 case Intrinsic::mips_sll_h:
2358 case Intrinsic::mips_sll_w:
2359 case Intrinsic::mips_sll_d:
2360 return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), Op->getOperand(1),
2361 truncateVecElts(Op, DAG));
2362 case Intrinsic::mips_slli_b:
2363 case Intrinsic::mips_slli_h:
2364 case Intrinsic::mips_slli_w:
2365 case Intrinsic::mips_slli_d:
2366 return DAG.getNode(ISD::SHL, DL, Op->getValueType(0),
2367 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2368 case Intrinsic::mips_splat_b:
2369 case Intrinsic::mips_splat_h:
2370 case Intrinsic::mips_splat_w:
2371 case Intrinsic::mips_splat_d:
2372 // We can't lower via VECTOR_SHUFFLE because it requires constant shuffle
2373 // masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because
2374 // EXTRACT_VECTOR_ELT can't extract i64's on MIPS32.
2375 // Instead we lower to MipsISD::VSHF and match from there.
2376 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2377 lowerMSASplatZExt(Op, 2, DAG), Op->getOperand(1),
2378 Op->getOperand(1));
2379 case Intrinsic::mips_splati_b:
2380 case Intrinsic::mips_splati_h:
2381 case Intrinsic::mips_splati_w:
2382 case Intrinsic::mips_splati_d:
2383 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2384 lowerMSASplatImm(Op, 2, DAG), Op->getOperand(1),
2385 Op->getOperand(1));
2386 case Intrinsic::mips_sra_b:
2387 case Intrinsic::mips_sra_h:
2388 case Intrinsic::mips_sra_w:
2389 case Intrinsic::mips_sra_d:
2390 return DAG.getNode(ISD::SRA, DL, Op->getValueType(0), Op->getOperand(1),
2391 truncateVecElts(Op, DAG));
2392 case Intrinsic::mips_srai_b:
2393 case Intrinsic::mips_srai_h:
2394 case Intrinsic::mips_srai_w:
2395 case Intrinsic::mips_srai_d:
2396 return DAG.getNode(ISD::SRA, DL, Op->getValueType(0),
2397 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2398 case Intrinsic::mips_srari_b:
2399 case Intrinsic::mips_srari_h:
2400 case Intrinsic::mips_srari_w:
2401 case Intrinsic::mips_srari_d: {
2402 // Report an error for out of range values.
2403 int64_t Max;
2404 switch (Intrinsic) {
2405 case Intrinsic::mips_srari_b: Max = 7; break;
2406 case Intrinsic::mips_srari_h: Max = 15; break;
2407 case Intrinsic::mips_srari_w: Max = 31; break;
2408 case Intrinsic::mips_srari_d: Max = 63; break;
2409 default: llvm_unreachable("Unmatched intrinsic");
2410 }
2411 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2412 if (Value < 0 || Value > Max)
2413 report_fatal_error("Immediate out of range");
2414 return SDValue();
2415 }
2416 case Intrinsic::mips_srl_b:
2417 case Intrinsic::mips_srl_h:
2418 case Intrinsic::mips_srl_w:
2419 case Intrinsic::mips_srl_d:
2420 return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), Op->getOperand(1),
2421 truncateVecElts(Op, DAG));
2422 case Intrinsic::mips_srli_b:
2423 case Intrinsic::mips_srli_h:
2424 case Intrinsic::mips_srli_w:
2425 case Intrinsic::mips_srli_d:
2426 return DAG.getNode(ISD::SRL, DL, Op->getValueType(0),
2427 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2428 case Intrinsic::mips_srlri_b:
2429 case Intrinsic::mips_srlri_h:
2430 case Intrinsic::mips_srlri_w:
2431 case Intrinsic::mips_srlri_d: {
2432 // Report an error for out of range values.
2433 int64_t Max;
2434 switch (Intrinsic) {
2435 case Intrinsic::mips_srlri_b: Max = 7; break;
2436 case Intrinsic::mips_srlri_h: Max = 15; break;
2437 case Intrinsic::mips_srlri_w: Max = 31; break;
2438 case Intrinsic::mips_srlri_d: Max = 63; break;
2439 default: llvm_unreachable("Unmatched intrinsic");
2440 }
2441 int64_t Value = cast<ConstantSDNode>(Op->getOperand(2))->getSExtValue();
2442 if (Value < 0 || Value > Max)
2443 report_fatal_error("Immediate out of range");
2444 return SDValue();
2445 }
2446 case Intrinsic::mips_subv_b:
2447 case Intrinsic::mips_subv_h:
2448 case Intrinsic::mips_subv_w:
2449 case Intrinsic::mips_subv_d:
2450 return DAG.getNode(ISD::SUB, DL, Op->getValueType(0), Op->getOperand(1),
2451 Op->getOperand(2));
2452 case Intrinsic::mips_subvi_b:
2453 case Intrinsic::mips_subvi_h:
2454 case Intrinsic::mips_subvi_w:
2455 case Intrinsic::mips_subvi_d:
2456 return DAG.getNode(ISD::SUB, DL, Op->getValueType(0),
2457 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2458 case Intrinsic::mips_vshf_b:
2459 case Intrinsic::mips_vshf_h:
2460 case Intrinsic::mips_vshf_w:
2461 case Intrinsic::mips_vshf_d:
2462 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2463 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
2464 case Intrinsic::mips_xor_v:
2465 return DAG.getNode(ISD::XOR, DL, Op->getValueType(0), Op->getOperand(1),
2466 Op->getOperand(2));
2467 case Intrinsic::mips_xori_b:
2468 return DAG.getNode(ISD::XOR, DL, Op->getValueType(0),
2469 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2470 case Intrinsic::thread_pointer: {
2471 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2472 return DAG.getNode(MipsISD::ThreadPointer, DL, PtrVT);
2473 }
2474 }
2475}
2476
2477static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr,
2478 const MipsSubtarget &Subtarget) {
2479 SDLoc DL(Op);
2480 SDValue ChainIn = Op->getOperand(0);
2481 SDValue Address = Op->getOperand(2);
2482 SDValue Offset = Op->getOperand(3);
2483 EVT ResTy = Op->getValueType(0);
2484 EVT PtrTy = Address->getValueType(0);
2485
2486 // For N64 addresses have the underlying type MVT::i64. This intrinsic
2487 // however takes an i32 signed constant offset. The actual type of the
2488 // intrinsic is a scaled signed i10.
2489 if (Subtarget.isABI_N64())
2490 Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset);
2491
2492 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
2493 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(),
2494 Align(16));
2495}
2496
2497SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
2498 SelectionDAG &DAG) const {
2499 unsigned Intr = Op->getConstantOperandVal(1);
2500 switch (Intr) {
2501 default:
2502 return SDValue();
2503 case Intrinsic::mips_extp:
2504 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
2505 case Intrinsic::mips_extpdp:
2506 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
2507 case Intrinsic::mips_extr_w:
2508 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
2509 case Intrinsic::mips_extr_r_w:
2510 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
2511 case Intrinsic::mips_extr_rs_w:
2512 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
2513 case Intrinsic::mips_extr_s_h:
2514 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
2515 case Intrinsic::mips_mthlip:
2516 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
2517 case Intrinsic::mips_mulsaq_s_w_ph:
2518 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
2519 case Intrinsic::mips_maq_s_w_phl:
2520 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
2521 case Intrinsic::mips_maq_s_w_phr:
2522 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
2523 case Intrinsic::mips_maq_sa_w_phl:
2524 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
2525 case Intrinsic::mips_maq_sa_w_phr:
2526 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
2527 case Intrinsic::mips_dpaq_s_w_ph:
2528 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
2529 case Intrinsic::mips_dpsq_s_w_ph:
2530 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
2531 case Intrinsic::mips_dpaq_sa_l_w:
2532 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
2533 case Intrinsic::mips_dpsq_sa_l_w:
2534 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
2535 case Intrinsic::mips_dpaqx_s_w_ph:
2536 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
2537 case Intrinsic::mips_dpaqx_sa_w_ph:
2538 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
2539 case Intrinsic::mips_dpsqx_s_w_ph:
2540 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
2541 case Intrinsic::mips_dpsqx_sa_w_ph:
2542 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
2543 case Intrinsic::mips_ld_b:
2544 case Intrinsic::mips_ld_h:
2545 case Intrinsic::mips_ld_w:
2546 case Intrinsic::mips_ld_d:
2547 return lowerMSALoadIntr(Op, DAG, Intr, Subtarget);
2548 }
2549}
2550
2552 const MipsSubtarget &Subtarget) {
2553 SDLoc DL(Op);
2554 SDValue ChainIn = Op->getOperand(0);
2555 SDValue Value = Op->getOperand(2);
2556 SDValue Address = Op->getOperand(3);
2557 SDValue Offset = Op->getOperand(4);
2558 EVT PtrTy = Address->getValueType(0);
2559
2560 // For N64 addresses have the underlying type MVT::i64. This intrinsic
2561 // however takes an i32 signed constant offset. The actual type of the
2562 // intrinsic is a scaled signed i10.
2563 if (Subtarget.isABI_N64())
2564 Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset);
2565
2566 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
2567
2568 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(),
2569 Align(16));
2570}
2571
2572SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
2573 SelectionDAG &DAG) const {
2574 unsigned Intr = Op->getConstantOperandVal(1);
2575 switch (Intr) {
2576 default:
2577 return SDValue();
2578 case Intrinsic::mips_st_b:
2579 case Intrinsic::mips_st_h:
2580 case Intrinsic::mips_st_w:
2581 case Intrinsic::mips_st_d:
2582 return lowerMSAStoreIntr(Op, DAG, Intr, Subtarget);
2583 }
2584}
2585
2586// Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT.
2587//
2588// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We
2589// choose to sign-extend but we could have equally chosen zero-extend. The
2590// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT
2591// result into this node later (possibly changing it to a zero-extend in the
2592// process).
2593SDValue MipsSETargetLowering::
2594lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const {
2595 SDLoc DL(Op);
2596 EVT ResTy = Op->getValueType(0);
2597 SDValue Op0 = Op->getOperand(0);
2598 EVT VecTy = Op0->getValueType(0);
2599
2600 if (!VecTy.is128BitVector())
2601 return SDValue();
2602
2603 if (ResTy.isInteger()) {
2604 SDValue Op1 = Op->getOperand(1);
2605 EVT EltTy = VecTy.getVectorElementType();
2606 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1,
2607 DAG.getValueType(EltTy));
2608 }
2609
2610 return Op;
2611}
2612
2613static bool isConstantOrUndef(const SDValue Op) {
2614 if (Op->isUndef())
2615 return true;
2617 return true;
2619 return true;
2620 return false;
2621}
2622
2624 for (unsigned i = 0; i < Op->getNumOperands(); ++i)
2625 if (isConstantOrUndef(Op->getOperand(i)))
2626 return true;
2627 return false;
2628}
2629
2630// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
2631// backend.
2632//
2633// Lowers according to the following rules:
2634// - Constant splats are legal as-is as long as the SplatBitSize is a power of
2635// 2 less than or equal to 64 and the value fits into a signed 10-bit
2636// immediate
2637// - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize
2638// is a power of 2 less than or equal to 64 and the value does not fit into a
2639// signed 10-bit immediate
2640// - Non-constant splats are legal as-is.
2641// - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT.
2642// - All others are illegal and must be expanded.
2643SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
2644 SelectionDAG &DAG) const {
2645 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
2646 EVT ResTy = Op->getValueType(0);
2647 SDLoc DL(Op);
2648 APInt SplatValue, SplatUndef;
2649 unsigned SplatBitSize;
2650 bool HasAnyUndefs;
2651
2652 if (!Subtarget.hasMSA() || !ResTy.is128BitVector())
2653 return SDValue();
2654
2655 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2656 HasAnyUndefs, 8,
2657 !Subtarget.isLittle()) && SplatBitSize <= 64) {
2658 // We can only cope with 8, 16, 32, or 64-bit elements
2659 if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
2660 SplatBitSize != 64)
2661 return SDValue();
2662
2663 // If the value isn't an integer type we will have to bitcast
2664 // from an integer type first. Also, if there are any undefs, we must
2665 // lower them to defined values first.
2666 if (ResTy.isInteger() && !HasAnyUndefs)
2667 return Op;
2668
2669 EVT ViaVecTy;
2670
2671 switch (SplatBitSize) {
2672 default:
2673 return SDValue();
2674 case 8:
2675 ViaVecTy = MVT::v16i8;
2676 break;
2677 case 16:
2678 ViaVecTy = MVT::v8i16;
2679 break;
2680 case 32:
2681 ViaVecTy = MVT::v4i32;
2682 break;
2683 case 64:
2684 // There's no fill.d to fall back on for 64-bit values
2685 return SDValue();
2686 }
2687
2688 // SelectionDAG::getConstant will promote SplatValue appropriately.
2689 SDValue Result = DAG.getConstant(SplatValue, DL, ViaVecTy);
2690
2691 // Bitcast to the type we originally wanted
2692 if (ViaVecTy != ResTy)
2693 Result = DAG.getNode(ISD::BITCAST, SDLoc(Node), ResTy, Result);
2694
2695 return Result;
2696 } else if (DAG.isSplatValue(Op, /* AllowUndefs */ false))
2697 return Op;
2698 else if (!isConstantOrUndefBUILD_VECTOR(Node)) {
2699 // Use INSERT_VECTOR_ELT operations rather than expand to stores.
2700 // The resulting code is the same length as the expansion, but it doesn't
2701 // use memory operations
2702 EVT ResTy = Node->getValueType(0);
2703
2704 assert(ResTy.isVector());
2705
2706 unsigned NumElts = ResTy.getVectorNumElements();
2707 SDValue Vector = DAG.getUNDEF(ResTy);
2708 for (unsigned i = 0; i < NumElts; ++i) {
2710 Node->getOperand(i),
2711 DAG.getConstant(i, DL, MVT::i32));
2712 }
2713 return Vector;
2714 }
2715
2716 return SDValue();
2717}
2718
2719// Lower VECTOR_SHUFFLE into SHF (if possible).
2720//
2721// SHF splits the vector into blocks of four elements, then shuffles these
2722// elements according to a <4 x i2> constant (encoded as an integer immediate).
2723//
2724// It is therefore possible to lower into SHF when the mask takes the form:
2725// <a, b, c, d, a+4, b+4, c+4, d+4, a+8, b+8, c+8, d+8, ...>
2726// When undef's appear they are treated as if they were whatever value is
2727// necessary in order to fit the above forms.
2728//
2729// For example:
2730// %2 = shufflevector <8 x i16> %0, <8 x i16> undef,
2731// <8 x i32> <i32 3, i32 2, i32 1, i32 0,
2732// i32 7, i32 6, i32 5, i32 4>
2733// is lowered to:
2734// (SHF_H $w0, $w1, 27)
2735// where the 27 comes from:
2736// 3 + (2 << 2) + (1 << 4) + (0 << 6)
2738 SmallVector<int, 16> Indices,
2739 SelectionDAG &DAG) {
2740 int SHFIndices[4] = { -1, -1, -1, -1 };
2741
2742 if (Indices.size() < 4)
2743 return SDValue();
2744
2745 for (unsigned i = 0; i < 4; ++i) {
2746 for (unsigned j = i; j < Indices.size(); j += 4) {
2747 int Idx = Indices[j];
2748
2749 // Convert from vector index to 4-element subvector index
2750 // If an index refers to an element outside of the subvector then give up
2751 if (Idx != -1) {
2752 Idx -= 4 * (j / 4);
2753 if (Idx < 0 || Idx >= 4)
2754 return SDValue();
2755 }
2756
2757 // If the mask has an undef, replace it with the current index.
2758 // Note that it might still be undef if the current index is also undef
2759 if (SHFIndices[i] == -1)
2760 SHFIndices[i] = Idx;
2761
2762 // Check that non-undef values are the same as in the mask. If they
2763 // aren't then give up
2764 if (!(Idx == -1 || Idx == SHFIndices[i]))
2765 return SDValue();
2766 }
2767 }
2768
2769 // Calculate the immediate. Replace any remaining undefs with zero
2770 APInt Imm(32, 0);
2771 for (int i = 3; i >= 0; --i) {
2772 int Idx = SHFIndices[i];
2773
2774 if (Idx == -1)
2775 Idx = 0;
2776
2777 Imm <<= 2;
2778 Imm |= Idx & 0x3;
2779 }
2780
2781 SDLoc DL(Op);
2782 return DAG.getNode(MipsISD::SHF, DL, ResTy,
2783 DAG.getTargetConstant(Imm, DL, MVT::i32),
2784 Op->getOperand(0));
2785}
2786
2787/// Determine whether a range fits a regular pattern of values.
2788/// This function accounts for the possibility of jumping over the End iterator.
2789template <typename ValType>
2790static bool
2792 unsigned CheckStride,
2794 ValType ExpectedIndex, unsigned ExpectedIndexStride) {
2795 auto &I = Begin;
2796
2797 while (I != End) {
2798 if (*I != -1 && *I != ExpectedIndex)
2799 return false;
2800 ExpectedIndex += ExpectedIndexStride;
2801
2802 // Incrementing past End is undefined behaviour so we must increment one
2803 // step at a time and check for End at each step.
2804 for (unsigned n = 0; n < CheckStride && I != End; ++n, ++I)
2805 ; // Empty loop body.
2806 }
2807 return true;
2808}
2809
2810// Determine whether VECTOR_SHUFFLE is a SPLATI.
2811//
2812// It is a SPLATI when the mask is:
2813// <x, x, x, ...>
2814// where x is any valid index.
2815//
2816// When undef's appear in the mask they are treated as if they were whatever
2817// value is necessary in order to fit the above form.
2819 SmallVector<int, 16> Indices,
2820 SelectionDAG &DAG) {
2821 assert((Indices.size() % 2) == 0);
2822
2823 int SplatIndex = -1;
2824 for (const auto &V : Indices) {
2825 if (V != -1) {
2826 SplatIndex = V;
2827 break;
2828 }
2829 }
2830
2831 return fitsRegularPattern<int>(Indices.begin(), 1, Indices.end(), SplatIndex,
2832 0);
2833}
2834
2835// Lower VECTOR_SHUFFLE into ILVEV (if possible).
2836//
2837// ILVEV interleaves the even elements from each vector.
2838//
2839// It is possible to lower into ILVEV when the mask consists of two of the
2840// following forms interleaved:
2841// <0, 2, 4, ...>
2842// <n, n+2, n+4, ...>
2843// where n is the number of elements in the vector.
2844// For example:
2845// <0, 0, 2, 2, 4, 4, ...>
2846// <0, n, 2, n+2, 4, n+4, ...>
2847//
2848// When undef's appear in the mask they are treated as if they were whatever
2849// value is necessary in order to fit the above forms.
2851 SmallVector<int, 16> Indices,
2852 SelectionDAG &DAG) {
2853 assert((Indices.size() % 2) == 0);
2854
2855 SDValue Wt;
2856 SDValue Ws;
2857 const auto &Begin = Indices.begin();
2858 const auto &End = Indices.end();
2859
2860 // Check even elements are taken from the even elements of one half or the
2861 // other and pick an operand accordingly.
2862 if (fitsRegularPattern<int>(Begin, 2, End, 0, 2))
2863 Wt = Op->getOperand(0);
2864 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size(), 2))
2865 Wt = Op->getOperand(1);
2866 else
2867 return SDValue();
2868
2869 // Check odd elements are taken from the even elements of one half or the
2870 // other and pick an operand accordingly.
2871 if (fitsRegularPattern<int>(Begin + 1, 2, End, 0, 2))
2872 Ws = Op->getOperand(0);
2873 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size(), 2))
2874 Ws = Op->getOperand(1);
2875 else
2876 return SDValue();
2877
2878 return DAG.getNode(MipsISD::ILVEV, SDLoc(Op), ResTy, Ws, Wt);
2879}
2880
2881// Lower VECTOR_SHUFFLE into ILVOD (if possible).
2882//
2883// ILVOD interleaves the odd elements from each vector.
2884//
2885// It is possible to lower into ILVOD when the mask consists of two of the
2886// following forms interleaved:
2887// <1, 3, 5, ...>
2888// <n+1, n+3, n+5, ...>
2889// where n is the number of elements in the vector.
2890// For example:
2891// <1, 1, 3, 3, 5, 5, ...>
2892// <1, n+1, 3, n+3, 5, n+5, ...>
2893//
2894// When undef's appear in the mask they are treated as if they were whatever
2895// value is necessary in order to fit the above forms.
2897 SmallVector<int, 16> Indices,
2898 SelectionDAG &DAG) {
2899 assert((Indices.size() % 2) == 0);
2900
2901 SDValue Wt;
2902 SDValue Ws;
2903 const auto &Begin = Indices.begin();
2904 const auto &End = Indices.end();
2905
2906 // Check even elements are taken from the odd elements of one half or the
2907 // other and pick an operand accordingly.
2908 if (fitsRegularPattern<int>(Begin, 2, End, 1, 2))
2909 Wt = Op->getOperand(0);
2910 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size() + 1, 2))
2911 Wt = Op->getOperand(1);
2912 else
2913 return SDValue();
2914
2915 // Check odd elements are taken from the odd elements of one half or the
2916 // other and pick an operand accordingly.
2917 if (fitsRegularPattern<int>(Begin + 1, 2, End, 1, 2))
2918 Ws = Op->getOperand(0);
2919 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size() + 1, 2))
2920 Ws = Op->getOperand(1);
2921 else
2922 return SDValue();
2923
2924 return DAG.getNode(MipsISD::ILVOD, SDLoc(Op), ResTy, Ws, Wt);
2925}
2926
2927// Lower VECTOR_SHUFFLE into ILVR (if possible).
2928//
2929// ILVR interleaves consecutive elements from the right (lowest-indexed) half of
2930// each vector.
2931//
2932// It is possible to lower into ILVR when the mask consists of two of the
2933// following forms interleaved:
2934// <0, 1, 2, ...>
2935// <n, n+1, n+2, ...>
2936// where n is the number of elements in the vector.
2937// For example:
2938// <0, 0, 1, 1, 2, 2, ...>
2939// <0, n, 1, n+1, 2, n+2, ...>
2940//
2941// When undef's appear in the mask they are treated as if they were whatever
2942// value is necessary in order to fit the above forms.
2944 SmallVector<int, 16> Indices,
2945 SelectionDAG &DAG) {
2946 assert((Indices.size() % 2) == 0);
2947
2948 SDValue Wt;
2949 SDValue Ws;
2950 const auto &Begin = Indices.begin();
2951 const auto &End = Indices.end();
2952
2953 // Check even elements are taken from the right (lowest-indexed) elements of
2954 // one half or the other and pick an operand accordingly.
2955 if (fitsRegularPattern<int>(Begin, 2, End, 0, 1))
2956 Wt = Op->getOperand(0);
2957 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size(), 1))
2958 Wt = Op->getOperand(1);
2959 else
2960 return SDValue();
2961
2962 // Check odd elements are taken from the right (lowest-indexed) elements of
2963 // one half or the other and pick an operand accordingly.
2964 if (fitsRegularPattern<int>(Begin + 1, 2, End, 0, 1))
2965 Ws = Op->getOperand(0);
2966 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size(), 1))
2967 Ws = Op->getOperand(1);
2968 else
2969 return SDValue();
2970
2971 return DAG.getNode(MipsISD::ILVR, SDLoc(Op), ResTy, Ws, Wt);
2972}
2973
2974// Lower VECTOR_SHUFFLE into ILVL (if possible).
2975//
2976// ILVL interleaves consecutive elements from the left (highest-indexed) half
2977// of each vector.
2978//
2979// It is possible to lower into ILVL when the mask consists of two of the
2980// following forms interleaved:
2981// <x, x+1, x+2, ...>
2982// <n+x, n+x+1, n+x+2, ...>
2983// where n is the number of elements in the vector and x is half n.
2984// For example:
2985// <x, x, x+1, x+1, x+2, x+2, ...>
2986// <x, n+x, x+1, n+x+1, x+2, n+x+2, ...>
2987//
2988// When undef's appear in the mask they are treated as if they were whatever
2989// value is necessary in order to fit the above forms.
2991 SmallVector<int, 16> Indices,
2992 SelectionDAG &DAG) {
2993 assert((Indices.size() % 2) == 0);
2994
2995 unsigned HalfSize = Indices.size() / 2;
2996 SDValue Wt;
2997 SDValue Ws;
2998 const auto &Begin = Indices.begin();
2999 const auto &End = Indices.end();
3000
3001 // Check even elements are taken from the left (highest-indexed) elements of
3002 // one half or the other and pick an operand accordingly.
3003 if (fitsRegularPattern<int>(Begin, 2, End, HalfSize, 1))
3004 Wt = Op->getOperand(0);
3005 else if (fitsRegularPattern<int>(Begin, 2, End, Indices.size() + HalfSize, 1))
3006 Wt = Op->getOperand(1);
3007 else
3008 return SDValue();
3009
3010 // Check odd elements are taken from the left (highest-indexed) elements of
3011 // one half or the other and pick an operand accordingly.
3012 if (fitsRegularPattern<int>(Begin + 1, 2, End, HalfSize, 1))
3013 Ws = Op->getOperand(0);
3014 else if (fitsRegularPattern<int>(Begin + 1, 2, End, Indices.size() + HalfSize,
3015 1))
3016 Ws = Op->getOperand(1);
3017 else
3018 return SDValue();
3019
3020 return DAG.getNode(MipsISD::ILVL, SDLoc(Op), ResTy, Ws, Wt);
3021}
3022
3023// Lower VECTOR_SHUFFLE into PCKEV (if possible).
3024//
3025// PCKEV copies the even elements of each vector into the result vector.
3026//
3027// It is possible to lower into PCKEV when the mask consists of two of the
3028// following forms concatenated:
3029// <0, 2, 4, ...>
3030// <n, n+2, n+4, ...>
3031// where n is the number of elements in the vector.
3032// For example:
3033// <0, 2, 4, ..., 0, 2, 4, ...>
3034// <0, 2, 4, ..., n, n+2, n+4, ...>
3035//
3036// When undef's appear in the mask they are treated as if they were whatever
3037// value is necessary in order to fit the above forms.
3039 SmallVector<int, 16> Indices,
3040 SelectionDAG &DAG) {
3041 assert((Indices.size() % 2) == 0);
3042
3043 SDValue Wt;
3044 SDValue Ws;
3045 const auto &Begin = Indices.begin();
3046 const auto &Mid = Indices.begin() + Indices.size() / 2;
3047 const auto &End = Indices.end();
3048
3049 if (fitsRegularPattern<int>(Begin, 1, Mid, 0, 2))
3050 Wt = Op->getOperand(0);
3051 else if (fitsRegularPattern<int>(Begin, 1, Mid, Indices.size(), 2))
3052 Wt = Op->getOperand(1);
3053 else
3054 return SDValue();
3055
3056 if (fitsRegularPattern<int>(Mid, 1, End, 0, 2))
3057 Ws = Op->getOperand(0);
3058 else if (fitsRegularPattern<int>(Mid, 1, End, Indices.size(), 2))
3059 Ws = Op->getOperand(1);
3060 else
3061 return SDValue();
3062
3063 return DAG.getNode(MipsISD::PCKEV, SDLoc(Op), ResTy, Ws, Wt);
3064}
3065
3066// Lower VECTOR_SHUFFLE into PCKOD (if possible).
3067//
3068// PCKOD copies the odd elements of each vector into the result vector.
3069//
3070// It is possible to lower into PCKOD when the mask consists of two of the
3071// following forms concatenated:
3072// <1, 3, 5, ...>
3073// <n+1, n+3, n+5, ...>
3074// where n is the number of elements in the vector.
3075// For example:
3076// <1, 3, 5, ..., 1, 3, 5, ...>
3077// <1, 3, 5, ..., n+1, n+3, n+5, ...>
3078//
3079// When undef's appear in the mask they are treated as if they were whatever
3080// value is necessary in order to fit the above forms.
3082 SmallVector<int, 16> Indices,
3083 SelectionDAG &DAG) {
3084 assert((Indices.size() % 2) == 0);
3085
3086 SDValue Wt;
3087 SDValue Ws;
3088 const auto &Begin = Indices.begin();
3089 const auto &Mid = Indices.begin() + Indices.size() / 2;
3090 const auto &End = Indices.end();
3091
3092 if (fitsRegularPattern<int>(Begin, 1, Mid, 1, 2))
3093 Wt = Op->getOperand(0);
3094 else if (fitsRegularPattern<int>(Begin, 1, Mid, Indices.size() + 1, 2))
3095 Wt = Op->getOperand(1);
3096 else
3097 return SDValue();
3098
3099 if (fitsRegularPattern<int>(Mid, 1, End, 1, 2))
3100 Ws = Op->getOperand(0);
3101 else if (fitsRegularPattern<int>(Mid, 1, End, Indices.size() + 1, 2))
3102 Ws = Op->getOperand(1);
3103 else
3104 return SDValue();
3105
3106 return DAG.getNode(MipsISD::PCKOD, SDLoc(Op), ResTy, Ws, Wt);
3107}
3108
3109// Lower VECTOR_SHUFFLE into VSHF.
3110//
3111// This mostly consists of converting the shuffle indices in Indices into a
3112// BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is
3113// also code to eliminate unused operands of the VECTOR_SHUFFLE. For example,
3114// if the type is v8i16 and all the indices are less than 8 then the second
3115// operand is unused and can be replaced with anything. We choose to replace it
3116// with the used operand since this reduces the number of instructions overall.
3117//
3118// NOTE: SPLATI shuffle masks may contain UNDEFs, since isSPLATI() treats
3119// UNDEFs as same as SPLATI index.
3120// For other instances we use the last valid index if UNDEF is
3121// encountered.
3123 const SmallVector<int, 16> &Indices,
3124 const bool isSPLATI,
3125 SelectionDAG &DAG) {
3127 SDValue Op0;
3128 SDValue Op1;
3129 EVT MaskVecTy = ResTy.changeVectorElementTypeToInteger();
3130 EVT MaskEltTy = MaskVecTy.getVectorElementType();
3131 bool Using1stVec = false;
3132 bool Using2ndVec = false;
3133 SDLoc DL(Op);
3134 int ResTyNumElts = ResTy.getVectorNumElements();
3135
3136 assert(Indices[0] >= 0 &&
3137 "shuffle mask starts with an UNDEF, which is not expected");
3138
3139 for (int i = 0; i < ResTyNumElts; ++i) {
3140 // Idx == -1 means UNDEF
3141 int Idx = Indices[i];
3142
3143 if (0 <= Idx && Idx < ResTyNumElts)
3144 Using1stVec = true;
3145 if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2)
3146 Using2ndVec = true;
3147 }
3148 int LastValidIndex = 0;
3149 for (size_t i = 0; i < Indices.size(); i++) {
3150 int Idx = Indices[i];
3151 if (Idx < 0) {
3152 // Continue using splati index or use the last valid index.
3153 Idx = isSPLATI ? Indices[0] : LastValidIndex;
3154 } else {
3155 LastValidIndex = Idx;
3156 }
3157 Ops.push_back(DAG.getTargetConstant(Idx, DL, MaskEltTy));
3158 }
3159
3160 SDValue MaskVec = DAG.getBuildVector(MaskVecTy, DL, Ops);
3161
3162 if (Using1stVec && Using2ndVec) {
3163 Op0 = Op->getOperand(0);
3164 Op1 = Op->getOperand(1);
3165 } else if (Using1stVec)
3166 Op0 = Op1 = Op->getOperand(0);
3167 else if (Using2ndVec)
3168 Op0 = Op1 = Op->getOperand(1);
3169 else
3170 llvm_unreachable("shuffle vector mask references neither vector operand?");
3171
3172 // VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion.
3173 // <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11>
3174 // VSHF concatenates the vectors in a bitwise fashion:
3175 // <0b00, 0b01> + <0b10, 0b11> ->
3176 // 0b0100 + 0b1110 -> 0b01001110
3177 // <0b10, 0b11, 0b00, 0b01>
3178 // We must therefore swap the operands to get the correct result.
3179 return DAG.getNode(MipsISD::VSHF, DL, ResTy, MaskVec, Op1, Op0);
3180}
3181
3182// Lower VECTOR_SHUFFLE into one of a number of instructions depending on the
3183// indices in the shuffle.
3184SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
3185 SelectionDAG &DAG) const {
3186 ShuffleVectorSDNode *Node = cast<ShuffleVectorSDNode>(Op);
3187 EVT ResTy = Op->getValueType(0);
3188
3189 if (!ResTy.is128BitVector())
3190 return SDValue();
3191
3192 int ResTyNumElts = ResTy.getVectorNumElements();
3193 SmallVector<int, 16> Indices;
3194
3195 for (int i = 0; i < ResTyNumElts; ++i)
3196 Indices.push_back(Node->getMaskElt(i));
3197
3198 // splati.[bhwd] is preferable to the others but is matched from
3199 // MipsISD::VSHF.
3200 if (isVECTOR_SHUFFLE_SPLATI(Op, ResTy, Indices, DAG))
3201 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, true, DAG);
3203 if ((Result = lowerVECTOR_SHUFFLE_ILVEV(Op, ResTy, Indices, DAG)))
3204 return Result;
3205 if ((Result = lowerVECTOR_SHUFFLE_ILVOD(Op, ResTy, Indices, DAG)))
3206 return Result;
3207 if ((Result = lowerVECTOR_SHUFFLE_ILVL(Op, ResTy, Indices, DAG)))
3208 return Result;
3209 if ((Result = lowerVECTOR_SHUFFLE_ILVR(Op, ResTy, Indices, DAG)))
3210 return Result;
3211 if ((Result = lowerVECTOR_SHUFFLE_PCKEV(Op, ResTy, Indices, DAG)))
3212 return Result;
3213 if ((Result = lowerVECTOR_SHUFFLE_PCKOD(Op, ResTy, Indices, DAG)))
3214 return Result;
3215 if ((Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG)))
3216 return Result;
3217 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, false, DAG);
3218}
3219
3221MipsSETargetLowering::emitBPOSGE32(MachineInstr &MI,
3222 MachineBasicBlock *BB) const {
3223 // $bb:
3224 // bposge32_pseudo $vr0
3225 // =>
3226 // $bb:
3227 // bposge32 $tbb
3228 // $fbb:
3229 // li $vr2, 0
3230 // b $sink
3231 // $tbb:
3232 // li $vr1, 1
3233 // $sink:
3234 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
3235
3236 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3237 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3238 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
3239 DebugLoc DL = MI.getDebugLoc();
3240 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3242 MachineFunction *F = BB->getParent();
3243 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
3244 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
3245 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
3246 F->insert(It, FBB);
3247 F->insert(It, TBB);
3248 F->insert(It, Sink);
3249
3250 // Transfer the remainder of BB and its successor edges to Sink.
3251 Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
3252 BB->end());
3253 Sink->transferSuccessorsAndUpdatePHIs(BB);
3254
3255 // Add successors.
3256 BB->addSuccessor(FBB);
3257 BB->addSuccessor(TBB);
3258 FBB->addSuccessor(Sink);
3259 TBB->addSuccessor(Sink);
3260
3261 // Insert the real bposge32 instruction to $BB.
3262 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
3263 // Insert the real bposge32c instruction to $BB.
3264 BuildMI(BB, DL, TII->get(Mips::BPOSGE32C_MMR3)).addMBB(TBB);
3265
3266 // Fill $FBB.
3267 Register VR2 = RegInfo.createVirtualRegister(RC);
3268 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
3269 .addReg(Mips::ZERO).addImm(0);
3270 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
3271
3272 // Fill $TBB.
3273 Register VR1 = RegInfo.createVirtualRegister(RC);
3274 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
3275 .addReg(Mips::ZERO).addImm(1);
3276
3277 // Insert phi function to $Sink.
3278 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
3279 MI.getOperand(0).getReg())
3280 .addReg(VR2)
3281 .addMBB(FBB)
3282 .addReg(VR1)
3283 .addMBB(TBB);
3284
3285 MI.eraseFromParent(); // The pseudo instruction is gone now.
3286 return Sink;
3287}
3288
3289MachineBasicBlock *MipsSETargetLowering::emitMSACBranchPseudo(
3290 MachineInstr &MI, MachineBasicBlock *BB, unsigned BranchOp) const {
3291 // $bb:
3292 // vany_nonzero $rd, $ws
3293 // =>
3294 // $bb:
3295 // bnz.b $ws, $tbb
3296 // b $fbb
3297 // $fbb:
3298 // li $rd1, 0
3299 // b $sink
3300 // $tbb:
3301 // li $rd2, 1
3302 // $sink:
3303 // $rd = phi($rd1, $fbb, $rd2, $tbb)
3304
3305 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3306 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3307 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
3308 DebugLoc DL = MI.getDebugLoc();
3309 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3311 MachineFunction *F = BB->getParent();
3312 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
3313 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
3314 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
3315 F->insert(It, FBB);
3316 F->insert(It, TBB);
3317 F->insert(It, Sink);
3318
3319 // Transfer the remainder of BB and its successor edges to Sink.
3320 Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
3321 BB->end());
3322 Sink->transferSuccessorsAndUpdatePHIs(BB);
3323
3324 // Add successors.
3325 BB->addSuccessor(FBB);
3326 BB->addSuccessor(TBB);
3327 FBB->addSuccessor(Sink);
3328 TBB->addSuccessor(Sink);
3329
3330 // Insert the real bnz.b instruction to $BB.
3331 BuildMI(BB, DL, TII->get(BranchOp))
3332 .addReg(MI.getOperand(1).getReg())
3333 .addMBB(TBB);
3334
3335 // Fill $FBB.
3336 Register RD1 = RegInfo.createVirtualRegister(RC);
3337 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
3338 .addReg(Mips::ZERO).addImm(0);
3339 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
3340
3341 // Fill $TBB.
3342 Register RD2 = RegInfo.createVirtualRegister(RC);
3343 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
3344 .addReg(Mips::ZERO).addImm(1);
3345
3346 // Insert phi function to $Sink.
3347 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
3348 MI.getOperand(0).getReg())
3349 .addReg(RD1)
3350 .addMBB(FBB)
3351 .addReg(RD2)
3352 .addMBB(TBB);
3353
3354 MI.eraseFromParent(); // The pseudo instruction is gone now.
3355 return Sink;
3356}
3357
3358// Emit the COPY_FW pseudo instruction.
3359//
3360// copy_fw_pseudo $fd, $ws, n
3361// =>
3362// copy_u_w $rt, $ws, $n
3363// mtc1 $rt, $fd
3364//
3365// When n is zero, the equivalent operation can be performed with (potentially)
3366// zero instructions due to register overlaps. This optimization is never valid
3367// for lane 1 because it would require FR=0 mode which isn't supported by MSA.
3369MipsSETargetLowering::emitCOPY_FW(MachineInstr &MI,
3370 MachineBasicBlock *BB) const {
3371 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3372 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3373 DebugLoc DL = MI.getDebugLoc();
3374 Register Fd = MI.getOperand(0).getReg();
3375 Register Ws = MI.getOperand(1).getReg();
3376 unsigned Lane = MI.getOperand(2).getImm();
3377
3378 if (Lane == 0) {
3379 unsigned Wt = Ws;
3380 if (!Subtarget.useOddSPReg()) {
3381 // We must copy to an even-numbered MSA register so that the
3382 // single-precision sub-register is also guaranteed to be even-numbered.
3383 Wt = RegInfo.createVirtualRegister(&Mips::MSA128WEvensRegClass);
3384
3385 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Wt).addReg(Ws);
3386 }
3387
3388 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, {}, Mips::sub_lo);
3389 } else {
3390 Register Wt = RegInfo.createVirtualRegister(
3391 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3392 : &Mips::MSA128WEvensRegClass);
3393
3394 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wt).addReg(Ws).addImm(Lane);
3395 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, {}, Mips::sub_lo);
3396 }
3397
3398 MI.eraseFromParent(); // The pseudo instruction is gone now.
3399 return BB;
3400}
3401
3402// Emit the COPY_FD pseudo instruction.
3403//
3404// copy_fd_pseudo $fd, $ws, n
3405// =>
3406// splati.d $wt, $ws, $n
3407// copy $fd, $wt:sub_64
3408//
3409// When n is zero, the equivalent operation can be performed with (potentially)
3410// zero instructions due to register overlaps. This optimization is always
3411// valid because FR=1 mode which is the only supported mode in MSA.
3413MipsSETargetLowering::emitCOPY_FD(MachineInstr &MI,
3414 MachineBasicBlock *BB) const {
3415 assert(Subtarget.isFP64bit());
3416
3417 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3418 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3419 Register Fd = MI.getOperand(0).getReg();
3420 Register Ws = MI.getOperand(1).getReg();
3421 unsigned Lane = MI.getOperand(2).getImm() * 2;
3422 DebugLoc DL = MI.getDebugLoc();
3423
3424 if (Lane == 0)
3425 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, {}, Mips::sub_64);
3426 else {
3427 Register Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3428
3429 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wt).addReg(Ws).addImm(1);
3430 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, {}, Mips::sub_64);
3431 }
3432
3433 MI.eraseFromParent(); // The pseudo instruction is gone now.
3434 return BB;
3435}
3436
3437// Emit the INSERT_FW pseudo instruction.
3438//
3439// insert_fw_pseudo $wd, $wd_in, $n, $fs
3440// =>
3441// subreg_to_reg $wt:sub_lo, $fs
3442// insve_w $wd[$n], $wd_in, $wt[0]
3444MipsSETargetLowering::emitINSERT_FW(MachineInstr &MI,
3445 MachineBasicBlock *BB) const {
3446 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3447 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3448 DebugLoc DL = MI.getDebugLoc();
3449 Register Wd = MI.getOperand(0).getReg();
3450 Register Wd_in = MI.getOperand(1).getReg();
3451 unsigned Lane = MI.getOperand(2).getImm();
3452 Register Fs = MI.getOperand(3).getReg();
3453 Register Wt = RegInfo.createVirtualRegister(
3454 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3455 : &Mips::MSA128WEvensRegClass);
3456
3457 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3458 .addReg(Fs)
3459 .addImm(Mips::sub_lo);
3460 BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_W), Wd)
3461 .addReg(Wd_in)
3462 .addImm(Lane)
3463 .addReg(Wt)
3464 .addImm(0);
3465
3466 MI.eraseFromParent(); // The pseudo instruction is gone now.
3467 return BB;
3468}
3469
3470// Emit the INSERT_FD pseudo instruction.
3471//
3472// insert_fd_pseudo $wd, $fs, n
3473// =>
3474// subreg_to_reg $wt:sub_64, $fs
3475// insve_d $wd[$n], $wd_in, $wt[0]
3477MipsSETargetLowering::emitINSERT_FD(MachineInstr &MI,
3478 MachineBasicBlock *BB) const {
3479 assert(Subtarget.isFP64bit());
3480
3481 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3482 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3483 DebugLoc DL = MI.getDebugLoc();
3484 Register Wd = MI.getOperand(0).getReg();
3485 Register Wd_in = MI.getOperand(1).getReg();
3486 unsigned Lane = MI.getOperand(2).getImm();
3487 Register Fs = MI.getOperand(3).getReg();
3488 Register Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3489
3490 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3491 .addReg(Fs)
3492 .addImm(Mips::sub_64);
3493 BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_D), Wd)
3494 .addReg(Wd_in)
3495 .addImm(Lane)
3496 .addReg(Wt)
3497 .addImm(0);
3498
3499 MI.eraseFromParent(); // The pseudo instruction is gone now.
3500 return BB;
3501}
3502
3503// Emit the INSERT_([BHWD]|F[WD])_VIDX pseudo instruction.
3504//
3505// For integer:
3506// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $rs)
3507// =>
3508// (SLL $lanetmp1, $lane, <log2size)
3509// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3510// (INSERT_[BHWD], $wdtmp2, $wdtmp1, 0, $rs)
3511// (NEG $lanetmp2, $lanetmp1)
3512// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2)
3513//
3514// For floating point:
3515// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $fs)
3516// =>
3517// (SUBREG_TO_REG $wt, $fs, <subreg>)
3518// (SLL $lanetmp1, $lane, <log2size)
3519// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3520// (INSVE_[WD], $wdtmp2, 0, $wdtmp1, 0)
3521// (NEG $lanetmp2, $lanetmp1)
3522// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2)
3523MachineBasicBlock *MipsSETargetLowering::emitINSERT_DF_VIDX(
3524 MachineInstr &MI, MachineBasicBlock *BB, unsigned EltSizeInBytes,
3525 bool IsFP) const {
3526 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3527 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3528 DebugLoc DL = MI.getDebugLoc();
3529 Register Wd = MI.getOperand(0).getReg();
3530 Register SrcVecReg = MI.getOperand(1).getReg();
3531 Register LaneReg = MI.getOperand(2).getReg();
3532 Register SrcValReg = MI.getOperand(3).getReg();
3533
3534 const TargetRegisterClass *VecRC = nullptr;
3535 // FIXME: This should be true for N32 too.
3536 const TargetRegisterClass *GPRRC =
3537 Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3538 unsigned SubRegIdx = Subtarget.isABI_N64() ? Mips::sub_32 : 0;
3539 unsigned ShiftOp = Subtarget.isABI_N64() ? Mips::DSLL : Mips::SLL;
3540 unsigned EltLog2Size;
3541 unsigned InsertOp = 0;
3542 unsigned InsveOp = 0;
3543 switch (EltSizeInBytes) {
3544 default:
3545 llvm_unreachable("Unexpected size");
3546 case 1:
3547 EltLog2Size = 0;
3548 InsertOp = Mips::INSERT_B;
3549 InsveOp = Mips::INSVE_B;
3550 VecRC = &Mips::MSA128BRegClass;
3551 break;
3552 case 2:
3553 EltLog2Size = 1;
3554 InsertOp = Mips::INSERT_H;
3555 InsveOp = Mips::INSVE_H;
3556 VecRC = &Mips::MSA128HRegClass;
3557 break;
3558 case 4:
3559 EltLog2Size = 2;
3560 InsertOp = Mips::INSERT_W;
3561 InsveOp = Mips::INSVE_W;
3562 VecRC = &Mips::MSA128WRegClass;
3563 break;
3564 case 8:
3565 EltLog2Size = 3;
3566 InsertOp = Mips::INSERT_D;
3567 InsveOp = Mips::INSVE_D;
3568 VecRC = &Mips::MSA128DRegClass;
3569 break;
3570 }
3571
3572 if (IsFP) {
3573 Register Wt = RegInfo.createVirtualRegister(VecRC);
3574 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3575 .addReg(SrcValReg)
3576 .addImm(EltSizeInBytes == 8 ? Mips::sub_64 : Mips::sub_lo);
3577 SrcValReg = Wt;
3578 }
3579
3580 // Convert the lane index into a byte index
3581 if (EltSizeInBytes != 1) {
3582 Register LaneTmp1 = RegInfo.createVirtualRegister(GPRRC);
3583 BuildMI(*BB, MI, DL, TII->get(ShiftOp), LaneTmp1)
3584 .addReg(LaneReg)
3585 .addImm(EltLog2Size);
3586 LaneReg = LaneTmp1;
3587 }
3588
3589 // Rotate bytes around so that the desired lane is element zero
3590 Register WdTmp1 = RegInfo.createVirtualRegister(VecRC);
3591 BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), WdTmp1)
3592 .addReg(SrcVecReg)
3593 .addReg(SrcVecReg)
3594 .addReg(LaneReg, {}, SubRegIdx);
3595
3596 Register WdTmp2 = RegInfo.createVirtualRegister(VecRC);
3597 if (IsFP) {
3598 // Use insve.df to insert to element zero
3599 BuildMI(*BB, MI, DL, TII->get(InsveOp), WdTmp2)
3600 .addReg(WdTmp1)
3601 .addImm(0)
3602 .addReg(SrcValReg)
3603 .addImm(0);
3604 } else {
3605 // Use insert.df to insert to element zero
3606 BuildMI(*BB, MI, DL, TII->get(InsertOp), WdTmp2)
3607 .addReg(WdTmp1)
3608 .addReg(SrcValReg)
3609 .addImm(0);
3610 }
3611
3612 // Rotate elements the rest of the way for a full rotation.
3613 // sld.df inteprets $rt modulo the number of columns so we only need to negate
3614 // the lane index to do this.
3615 Register LaneTmp2 = RegInfo.createVirtualRegister(GPRRC);
3616 BuildMI(*BB, MI, DL, TII->get(Subtarget.isABI_N64() ? Mips::DSUB : Mips::SUB),
3617 LaneTmp2)
3618 .addReg(Subtarget.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO)
3619 .addReg(LaneReg);
3620 BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), Wd)
3621 .addReg(WdTmp2)
3622 .addReg(WdTmp2)
3623 .addReg(LaneTmp2, {}, SubRegIdx);
3624
3625 MI.eraseFromParent(); // The pseudo instruction is gone now.
3626 return BB;
3627}
3628
3629// Emit the FILL_FW pseudo instruction.
3630//
3631// fill_fw_pseudo $wd, $fs
3632// =>
3633// implicit_def $wt1
3634// insert_subreg $wt2:subreg_lo, $wt1, $fs
3635// splati.w $wd, $wt2[0]
3637MipsSETargetLowering::emitFILL_FW(MachineInstr &MI,
3638 MachineBasicBlock *BB) const {
3639 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3640 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3641 DebugLoc DL = MI.getDebugLoc();
3642 Register Wd = MI.getOperand(0).getReg();
3643 Register Fs = MI.getOperand(1).getReg();
3644 Register Wt1 = RegInfo.createVirtualRegister(
3645 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3646 : &Mips::MSA128WEvensRegClass);
3647 Register Wt2 = RegInfo.createVirtualRegister(
3648 Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3649 : &Mips::MSA128WEvensRegClass);
3650
3651 BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1);
3652 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2)
3653 .addReg(Wt1)
3654 .addReg(Fs)
3655 .addImm(Mips::sub_lo);
3656 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wd).addReg(Wt2).addImm(0);
3657
3658 MI.eraseFromParent(); // The pseudo instruction is gone now.
3659 return BB;
3660}
3661
3662// Emit the FILL_FD pseudo instruction.
3663//
3664// fill_fd_pseudo $wd, $fs
3665// =>
3666// implicit_def $wt1
3667// insert_subreg $wt2:subreg_64, $wt1, $fs
3668// splati.d $wd, $wt2[0]
3670MipsSETargetLowering::emitFILL_FD(MachineInstr &MI,
3671 MachineBasicBlock *BB) const {
3672 assert(Subtarget.isFP64bit());
3673
3674 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3675 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3676 DebugLoc DL = MI.getDebugLoc();
3677 Register Wd = MI.getOperand(0).getReg();
3678 Register Fs = MI.getOperand(1).getReg();
3679 Register Wt1 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3680 Register Wt2 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
3681
3682 BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1);
3683 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2)
3684 .addReg(Wt1)
3685 .addReg(Fs)
3686 .addImm(Mips::sub_64);
3687 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wd).addReg(Wt2).addImm(0);
3688
3689 MI.eraseFromParent(); // The pseudo instruction is gone now.
3690 return BB;
3691}
3692
3693// Emit the FEXP2_W_1 pseudo instructions.
3694//
3695// fexp2_w_1_pseudo $wd, $wt
3696// =>
3697// ldi.w $ws, 1
3698// fexp2.w $wd, $ws, $wt
3700MipsSETargetLowering::emitFEXP2_W_1(MachineInstr &MI,
3701 MachineBasicBlock *BB) const {
3702 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3703 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3704 const TargetRegisterClass *RC = &Mips::MSA128WRegClass;
3705 Register Ws1 = RegInfo.createVirtualRegister(RC);
3706 Register Ws2 = RegInfo.createVirtualRegister(RC);
3707 DebugLoc DL = MI.getDebugLoc();
3708
3709 // Splat 1.0 into a vector
3710 BuildMI(*BB, MI, DL, TII->get(Mips::LDI_W), Ws1).addImm(1);
3711 BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_W), Ws2).addReg(Ws1);
3712
3713 // Emit 1.0 * fexp2(Wt)
3714 BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_W), MI.getOperand(0).getReg())
3715 .addReg(Ws2)
3716 .addReg(MI.getOperand(1).getReg());
3717
3718 MI.eraseFromParent(); // The pseudo instruction is gone now.
3719 return BB;
3720}
3721
3722// Emit the FEXP2_D_1 pseudo instructions.
3723//
3724// fexp2_d_1_pseudo $wd, $wt
3725// =>
3726// ldi.d $ws, 1
3727// fexp2.d $wd, $ws, $wt
3729MipsSETargetLowering::emitFEXP2_D_1(MachineInstr &MI,
3730 MachineBasicBlock *BB) const {
3731 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3732 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3733 const TargetRegisterClass *RC = &Mips::MSA128DRegClass;
3734 Register Ws1 = RegInfo.createVirtualRegister(RC);
3735 Register Ws2 = RegInfo.createVirtualRegister(RC);
3736 DebugLoc DL = MI.getDebugLoc();
3737
3738 // Splat 1.0 into a vector
3739 BuildMI(*BB, MI, DL, TII->get(Mips::LDI_D), Ws1).addImm(1);
3740 BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_D), Ws2).addReg(Ws1);
3741
3742 // Emit 1.0 * fexp2(Wt)
3743 BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_D), MI.getOperand(0).getReg())
3744 .addReg(Ws2)
3745 .addReg(MI.getOperand(1).getReg());
3746
3747 MI.eraseFromParent(); // The pseudo instruction is gone now.
3748 return BB;
3749}
static SDValue performSHLCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
If the operand is a bitwise AND with a constant RHS, and the shift has a constant RHS and is the only...
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
return SDValue()
static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue performSETCCCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:853
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool fitsRegularPattern(typename SmallVectorImpl< ValType >::const_iterator Begin, unsigned CheckStride, typename SmallVectorImpl< ValType >::const_iterator End, ValType ExpectedIndex, unsigned ExpectedIndexStride)
Determine whether a range fits a regular pattern of values.
static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
static SDValue truncateVecElts(SDNode *Node, SelectionDAG &DAG)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Promote Memory to Register
Definition Mem2Reg.cpp:110
static SDValue lowerMSABinaryBitImmIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc, SDValue Imm, bool BigEndian)
static SDValue lowerMSABitClearImm(SDValue Op, SelectionDAG &DAG)
static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, const TargetLowering::DAGCombinerInfo &DCI, const MipsSETargetLowering *TL, const MipsSubtarget &Subtarget)
static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc)
static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc)
static cl::opt< bool > NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), cl::desc("Expand double precision loads and " "stores to their single precision " "counterparts"))
static SDValue lowerVECTOR_SHUFFLE_ILVR(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue, bool BigEndian, SelectionDAG &DAG)
static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian)
static SDValue initAccumulator(SDValue In, const SDLoc &DL, SelectionDAG &DAG)
static bool isBitwiseInverse(SDValue N, SDValue OfNode)
static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, const MipsSubtarget &Subtarget)
static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
static bool isVectorAllOnes(SDValue N)
static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue performFP_TO_UINTCombine(SDNode *N, SelectionDAG &DAG)
static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC)
static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG)
static SDValue lowerMSABitClear(SDValue Op, SelectionDAG &DAG)
static SDValue lowerVECTOR_SHUFFLE_PCKEV(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT, EVT ShiftTy, SelectionDAG &DAG)
static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG, bool IsSigned=false)
static SDValue lowerVECTOR_SHUFFLE_ILVOD(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isConstantOrUndef(const SDValue Op)
static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy, const SmallVector< int, 16 > &Indices, const bool isSPLATI, SelectionDAG &DAG)
static SDValue lowerVECTOR_SHUFFLE_SHF(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static SDValue extractLOHI(SDValue Op, const SDLoc &DL, SelectionDAG &DAG)
static bool shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT, SelectionDAG &DAG, const MipsSubtarget &Subtarget)
static SDValue lowerVECTOR_SHUFFLE_ILVEV(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isVECTOR_SHUFFLE_SPLATI(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op)
static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, const MipsSubtarget &Subtarget)
static SDValue lowerVECTOR_SHUFFLE_ILVL(SDValue Op, EVT ResTy, SmallVector< int, 16 > Indices, SelectionDAG &DAG)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1563
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:968
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:372
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1511
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:330
unsigned logBase2() const
Definition APInt.h:1784
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:441
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:307
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:297
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:858
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
unsigned getInRegsParamsCount() const
uint64_t getZExtValue() const
const SDValue & getBasePtr() const
const Triple & getTargetTriple() const
Machine Value Type.
SimpleValueType SimpleTy
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Flags
Flags values. These may be or'd together.
Flags getFlags() const
Return the raw flags of the source value,.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Align getAlign() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
unsigned getIncomingArgSize() const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
void addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC)
Enable MSA support for the given floating-point type and Register class.
void addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC)
Enable MSA support for the given integer type and Register class.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
const TargetRegisterClass * getRepRegClassFor(MVT VT) const override
Return the 'representative' register class for the specified value type.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Determine if the target supports unaligned memory accesses.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
MipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
bool hasMips32r6() const
bool isLittle() const
bool hasDSPR2() const
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
Return the type to use for a scalar shift opcode, given the shifted amount type.
MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
This function fills Ops, which is the list of operands that will later be used when a function call n...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
const MipsSubtarget & Subtarget
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getNumOperands() const
Return the number of values used by this operation.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
LLVM_ABI void printrWithDepth(raw_ostream &O, const SelectionDAG *G=nullptr, unsigned depth=100) const
Print a SelectionDAG node and children up to depth "depth." The given SelectionDAG allows target-spec...
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const TargetSubtargetInfo & getSubtarget() const
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVMContext * getContext() const
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::const_iterator const_iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const SDValue & getBasePtr() const
const SDValue & getValue() const
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
Definition Triple.cpp:2445
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ 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:827
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:294
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:518
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition ISDOpcodes.h:220
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:888
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:254
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:438
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:852
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:804
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:233
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ STRICT_FP_TO_FP16
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:704
@ STRICT_FP16_TO_FP
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:769
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:649
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:576
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:858
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:819
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:727
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:813
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:934
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
Definition ISDOpcodes.h:179
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:739
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:205
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:304
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:427
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:565
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:864
@ BRCOND
BRCOND - Conditional branch.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:213
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:556
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
initializer< Ty > init(const Ty &Val)
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
const MipsTargetLowering * createMipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:197
@ Custom
The result value requires a custom uniformity check.
Definition Uniformity.h:31
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
#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
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition ValueTypes.h:230
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
This class contains a discriminated union of information about pointers in memory operands,...
These are IR-level optimization flags that may be propagated to SDNodes.
This structure is used to pass arguments to makeLibCall function.