File indexing completed on 2026-05-10 08:43:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_CODEGEN_MACHINEVALUETYPE_H
0017 #define LLVM_CODEGEN_MACHINEVALUETYPE_H
0018
0019 #include "llvm/ADT/Sequence.h"
0020 #include "llvm/Support/ErrorHandling.h"
0021 #include "llvm/Support/MathExtras.h"
0022 #include "llvm/Support/TypeSize.h"
0023 #include <cassert>
0024 #include <cstdint>
0025
0026 namespace llvm {
0027
0028 class Type;
0029 struct fltSemantics;
0030 class raw_ostream;
0031
0032
0033
0034
0035 class MVT {
0036 public:
0037 enum SimpleValueType : uint16_t {
0038
0039
0040 INVALID_SIMPLE_VALUE_TYPE = 0,
0041
0042 #define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0043 Ty = n,
0044 #define GET_VT_RANGES
0045 #include "llvm/CodeGen/GenVT.inc"
0046 #undef GET_VT_ATTR
0047 #undef GET_VT_RANGES
0048
0049 VALUETYPE_SIZE = LAST_VALUETYPE + 1,
0050 };
0051
0052 static_assert(FIRST_VALUETYPE > 0);
0053 static_assert(LAST_VALUETYPE < token);
0054
0055 SimpleValueType SimpleTy = INVALID_SIMPLE_VALUE_TYPE;
0056
0057 constexpr MVT() = default;
0058 constexpr MVT(SimpleValueType SVT) : SimpleTy(SVT) {}
0059
0060 bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; }
0061 bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; }
0062 bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; }
0063 bool operator!=(const MVT& S) const { return SimpleTy != S.SimpleTy; }
0064 bool operator>=(const MVT& S) const { return SimpleTy >= S.SimpleTy; }
0065 bool operator<=(const MVT& S) const { return SimpleTy <= S.SimpleTy; }
0066
0067
0068 void dump() const;
0069
0070
0071 void print(raw_ostream &OS) const;
0072
0073
0074 bool isValid() const {
0075 return (SimpleTy >= MVT::FIRST_VALUETYPE &&
0076 SimpleTy <= MVT::LAST_VALUETYPE);
0077 }
0078
0079
0080 bool isFloatingPoint() const {
0081 return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE &&
0082 SimpleTy <= MVT::LAST_FP_VALUETYPE) ||
0083 (SimpleTy >= MVT::FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE &&
0084 SimpleTy <= MVT::LAST_FP_FIXEDLEN_VECTOR_VALUETYPE) ||
0085 (SimpleTy >= MVT::FIRST_FP_SCALABLE_VECTOR_VALUETYPE &&
0086 SimpleTy <= MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE));
0087 }
0088
0089
0090 bool isInteger() const {
0091 return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
0092 SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
0093 (SimpleTy >= MVT::FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE &&
0094 SimpleTy <= MVT::LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE) ||
0095 (SimpleTy >= MVT::FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE &&
0096 SimpleTy <= MVT::LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE));
0097 }
0098
0099
0100 bool isScalarInteger() const {
0101 return (SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
0102 SimpleTy <= MVT::LAST_INTEGER_VALUETYPE);
0103 }
0104
0105
0106 bool isVector() const {
0107 return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
0108 SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
0109 }
0110
0111
0112
0113 bool isScalableVector() const {
0114 return (SimpleTy >= MVT::FIRST_SCALABLE_VECTOR_VALUETYPE &&
0115 SimpleTy <= MVT::LAST_SCALABLE_VECTOR_VALUETYPE);
0116 }
0117
0118
0119
0120 bool isRISCVVectorTuple() const {
0121 return (SimpleTy >= MVT::FIRST_RISCV_VECTOR_TUPLE_VALUETYPE &&
0122 SimpleTy <= MVT::LAST_RISCV_VECTOR_TUPLE_VALUETYPE);
0123 }
0124
0125
0126 bool isScalableTargetExtVT() const {
0127 return SimpleTy == MVT::aarch64svcount || isRISCVVectorTuple();
0128 }
0129
0130
0131 bool isScalableVT() const {
0132 return isScalableVector() || isScalableTargetExtVT();
0133 }
0134
0135 bool isFixedLengthVector() const {
0136 return (SimpleTy >= MVT::FIRST_FIXEDLEN_VECTOR_VALUETYPE &&
0137 SimpleTy <= MVT::LAST_FIXEDLEN_VECTOR_VALUETYPE);
0138 }
0139
0140
0141 bool is16BitVector() const {
0142 return (isFixedLengthVector() && getFixedSizeInBits() == 16);
0143 }
0144
0145
0146 bool is32BitVector() const {
0147 return (isFixedLengthVector() && getFixedSizeInBits() == 32);
0148 }
0149
0150
0151 bool is64BitVector() const {
0152 return (isFixedLengthVector() && getFixedSizeInBits() == 64);
0153 }
0154
0155
0156 bool is128BitVector() const {
0157 return (isFixedLengthVector() && getFixedSizeInBits() == 128);
0158 }
0159
0160
0161 bool is256BitVector() const {
0162 return (isFixedLengthVector() && getFixedSizeInBits() == 256);
0163 }
0164
0165
0166 bool is512BitVector() const {
0167 return (isFixedLengthVector() && getFixedSizeInBits() == 512);
0168 }
0169
0170
0171 bool is1024BitVector() const {
0172 return (isFixedLengthVector() && getFixedSizeInBits() == 1024);
0173 }
0174
0175
0176 bool is2048BitVector() const {
0177 return (isFixedLengthVector() && getFixedSizeInBits() == 2048);
0178 }
0179
0180
0181 bool isOverloaded() const {
0182 switch (SimpleTy) {
0183 #define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0184 case Ty: \
0185 return Any;
0186 #include "llvm/CodeGen/GenVT.inc"
0187 #undef GET_VT_ATTR
0188 default:
0189 return false;
0190 }
0191 }
0192
0193
0194
0195
0196 MVT changeVectorElementTypeToInteger() const {
0197 MVT EltTy = getVectorElementType();
0198 MVT IntTy = MVT::getIntegerVT(EltTy.getSizeInBits());
0199 MVT VecTy = MVT::getVectorVT(IntTy, getVectorElementCount());
0200 assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
0201 "Simple vector VT not representable by simple integer vector VT!");
0202 return VecTy;
0203 }
0204
0205
0206
0207 MVT changeVectorElementType(MVT EltVT) const {
0208 MVT VecTy = MVT::getVectorVT(EltVT, getVectorElementCount());
0209 assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
0210 "Simple vector VT not representable by simple integer vector VT!");
0211 return VecTy;
0212 }
0213
0214
0215
0216
0217 MVT changeTypeToInteger() {
0218 if (isVector())
0219 return changeVectorElementTypeToInteger();
0220 return MVT::getIntegerVT(getSizeInBits());
0221 }
0222
0223
0224
0225 MVT getHalfNumVectorElementsVT() const {
0226 MVT EltVT = getVectorElementType();
0227 auto EltCnt = getVectorElementCount();
0228 assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
0229 return getVectorVT(EltVT, EltCnt.divideCoefficientBy(2));
0230 }
0231
0232
0233
0234 MVT getDoubleNumVectorElementsVT() const {
0235 MVT EltVT = getVectorElementType();
0236 auto EltCnt = getVectorElementCount();
0237 return MVT::getVectorVT(EltVT, EltCnt * 2);
0238 }
0239
0240
0241 bool isPow2VectorType() const {
0242 unsigned NElts = getVectorMinNumElements();
0243 return !(NElts & (NElts - 1));
0244 }
0245
0246
0247
0248 MVT getPow2VectorType() const {
0249 if (isPow2VectorType())
0250 return *this;
0251
0252 ElementCount NElts = getVectorElementCount();
0253 unsigned NewMinCount = 1 << Log2_32_Ceil(NElts.getKnownMinValue());
0254 NElts = ElementCount::get(NewMinCount, NElts.isScalable());
0255 return MVT::getVectorVT(getVectorElementType(), NElts);
0256 }
0257
0258
0259 MVT getScalarType() const {
0260 return isVector() ? getVectorElementType() : *this;
0261 }
0262
0263 MVT getVectorElementType() const {
0264 assert(SimpleTy >= FIRST_VALUETYPE && SimpleTy <= LAST_VALUETYPE);
0265 static constexpr SimpleValueType EltTyTable[] = {
0266 #define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0267 EltTy,
0268 #include "llvm/CodeGen/GenVT.inc"
0269 #undef GET_VT_ATTR
0270 };
0271 SimpleValueType VT = EltTyTable[SimpleTy - FIRST_VALUETYPE];
0272 assert(VT != INVALID_SIMPLE_VALUE_TYPE && "Not a vector MVT!");
0273 return VT;
0274 }
0275
0276
0277 unsigned getVectorMinNumElements() const {
0278 assert(SimpleTy >= FIRST_VALUETYPE && SimpleTy <= LAST_VALUETYPE);
0279 static constexpr uint16_t NElemTable[] = {
0280 #define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0281 NElem,
0282 #include "llvm/CodeGen/GenVT.inc"
0283 #undef GET_VT_ATTR
0284 };
0285 unsigned NElem = NElemTable[SimpleTy - FIRST_VALUETYPE];
0286 assert(NElem != 0 && "Not a vector MVT!");
0287 return NElem;
0288 }
0289
0290 ElementCount getVectorElementCount() const {
0291 return ElementCount::get(getVectorMinNumElements(), isScalableVector());
0292 }
0293
0294 unsigned getVectorNumElements() const {
0295 if (isScalableVector())
0296 llvm::reportInvalidSizeRequest(
0297 "Possible incorrect use of MVT::getVectorNumElements() for "
0298 "scalable vector. Scalable flag may be dropped, use "
0299 "MVT::getVectorElementCount() instead");
0300 return getVectorMinNumElements();
0301 }
0302
0303
0304
0305
0306
0307
0308 TypeSize getSizeInBits() const {
0309 static constexpr TypeSize SizeTable[] = {
0310 #define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0311 TypeSize(Sz, Sc || Tup || Ty == aarch64svcount
0312 ),
0313 #include "llvm/CodeGen/GenVT.inc"
0314 #undef GET_VT_ATTR
0315 };
0316
0317 switch (SimpleTy) {
0318 case INVALID_SIMPLE_VALUE_TYPE:
0319 llvm_unreachable("getSizeInBits called on extended MVT.");
0320 case Other:
0321 llvm_unreachable("Value type is non-standard value, Other.");
0322 case iPTR:
0323 llvm_unreachable("Value type size is target-dependent. Ask TLI.");
0324 case pAny:
0325 case iAny:
0326 case fAny:
0327 case vAny:
0328 case Any:
0329 llvm_unreachable("Value type is overloaded.");
0330 case token:
0331 llvm_unreachable("Token type is a sentinel that cannot be used "
0332 "in codegen and has no size");
0333 case Metadata:
0334 llvm_unreachable("Value type is metadata.");
0335 default:
0336 assert(SimpleTy < VALUETYPE_SIZE && "Unexpected value type!");
0337 return SizeTable[SimpleTy - FIRST_VALUETYPE];
0338 }
0339 }
0340
0341
0342
0343 uint64_t getFixedSizeInBits() const {
0344 return getSizeInBits().getFixedValue();
0345 }
0346
0347 uint64_t getScalarSizeInBits() const {
0348 return getScalarType().getSizeInBits().getFixedValue();
0349 }
0350
0351
0352
0353
0354
0355
0356
0357 TypeSize getStoreSize() const {
0358 TypeSize BaseSize = getSizeInBits();
0359 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
0360 }
0361
0362
0363
0364 uint64_t getScalarStoreSize() const {
0365 return getScalarType().getStoreSize().getFixedValue();
0366 }
0367
0368
0369
0370
0371
0372
0373
0374 TypeSize getStoreSizeInBits() const {
0375 return getStoreSize() * 8;
0376 }
0377
0378
0379
0380 bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(8); }
0381
0382
0383 bool knownBitsGT(MVT VT) const {
0384 return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
0385 }
0386
0387
0388
0389 bool knownBitsGE(MVT VT) const {
0390 return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
0391 }
0392
0393
0394 bool knownBitsLT(MVT VT) const {
0395 return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
0396 }
0397
0398
0399
0400 bool knownBitsLE(MVT VT) const {
0401 return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
0402 }
0403
0404
0405 bool bitsGT(MVT VT) const {
0406 assert(isScalableVector() == VT.isScalableVector() &&
0407 "Comparison between scalable and fixed types");
0408 return knownBitsGT(VT);
0409 }
0410
0411
0412 bool bitsGE(MVT VT) const {
0413 assert(isScalableVector() == VT.isScalableVector() &&
0414 "Comparison between scalable and fixed types");
0415 return knownBitsGE(VT);
0416 }
0417
0418
0419 bool bitsLT(MVT VT) const {
0420 assert(isScalableVector() == VT.isScalableVector() &&
0421 "Comparison between scalable and fixed types");
0422 return knownBitsLT(VT);
0423 }
0424
0425
0426 bool bitsLE(MVT VT) const {
0427 assert(isScalableVector() == VT.isScalableVector() &&
0428 "Comparison between scalable and fixed types");
0429 return knownBitsLE(VT);
0430 }
0431
0432 static MVT getFloatingPointVT(unsigned BitWidth) {
0433 #define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0434 if (FP == 3 && sz == BitWidth) \
0435 return Ty;
0436 #include "llvm/CodeGen/GenVT.inc"
0437 #undef GET_VT_ATTR
0438
0439 llvm_unreachable("Bad bit width!");
0440 }
0441
0442 static MVT getIntegerVT(unsigned BitWidth) {
0443 #define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0444 if (Int == 3 && sz == BitWidth) \
0445 return Ty;
0446 #include "llvm/CodeGen/GenVT.inc"
0447 #undef GET_VT_ATTR
0448
0449 return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
0450 }
0451
0452 static MVT getVectorVT(MVT VT, unsigned NumElements) {
0453 #define GET_VT_VECATTR(Ty, Sc, Tup, nElem, ElTy) \
0454 if (!Sc && !Tup && VT.SimpleTy == ElTy && NumElements == nElem) \
0455 return Ty;
0456 #include "llvm/CodeGen/GenVT.inc"
0457 #undef GET_VT_VECATTR
0458
0459 return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
0460 }
0461
0462 static MVT getScalableVectorVT(MVT VT, unsigned NumElements) {
0463 #define GET_VT_VECATTR(Ty, Sc, Tup, nElem, ElTy) \
0464 if (Sc && VT.SimpleTy == ElTy && NumElements == nElem) \
0465 return Ty;
0466 #include "llvm/CodeGen/GenVT.inc"
0467 #undef GET_VT_VECATTR
0468
0469 return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
0470 }
0471
0472 static MVT getRISCVVectorTupleVT(unsigned Sz, unsigned NFields) {
0473 #define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, nElem, EltTy) \
0474 if (Tup && sz == Sz && NF == NFields) \
0475 return Ty;
0476 #include "llvm/CodeGen/GenVT.inc"
0477 #undef GET_VT_ATTR
0478
0479 llvm_unreachable("Invalid RISCV vector tuple type");
0480 }
0481
0482
0483 unsigned getRISCVVectorTupleNumFields() const {
0484 assert(isRISCVVectorTuple() && SimpleTy >= FIRST_VALUETYPE &&
0485 SimpleTy <= LAST_VALUETYPE);
0486 static constexpr uint8_t NFTable[] = {
0487 #define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \
0488 NF,
0489 #include "llvm/CodeGen/GenVT.inc"
0490 #undef GET_VT_ATTR
0491 };
0492 return NFTable[SimpleTy - FIRST_VALUETYPE];
0493 }
0494
0495 static MVT getVectorVT(MVT VT, unsigned NumElements, bool IsScalable) {
0496 if (IsScalable)
0497 return getScalableVectorVT(VT, NumElements);
0498 return getVectorVT(VT, NumElements);
0499 }
0500
0501 static MVT getVectorVT(MVT VT, ElementCount EC) {
0502 if (EC.isScalable())
0503 return getScalableVectorVT(VT, EC.getKnownMinValue());
0504 return getVectorVT(VT, EC.getKnownMinValue());
0505 }
0506
0507
0508
0509
0510
0511
0512 static MVT getVT(Type *Ty, bool HandleUnknown = false);
0513
0514
0515
0516 const fltSemantics &getFltSemantics() const;
0517
0518 public:
0519
0520
0521 static auto all_valuetypes() {
0522 return enum_seq_inclusive(MVT::FIRST_VALUETYPE, MVT::LAST_VALUETYPE,
0523 force_iteration_on_noniterable_enum);
0524 }
0525
0526 static auto integer_valuetypes() {
0527 return enum_seq_inclusive(MVT::FIRST_INTEGER_VALUETYPE,
0528 MVT::LAST_INTEGER_VALUETYPE,
0529 force_iteration_on_noniterable_enum);
0530 }
0531
0532 static auto fp_valuetypes() {
0533 return enum_seq_inclusive(MVT::FIRST_FP_VALUETYPE, MVT::LAST_FP_VALUETYPE,
0534 force_iteration_on_noniterable_enum);
0535 }
0536
0537 static auto vector_valuetypes() {
0538 return enum_seq_inclusive(MVT::FIRST_VECTOR_VALUETYPE,
0539 MVT::LAST_VECTOR_VALUETYPE,
0540 force_iteration_on_noniterable_enum);
0541 }
0542
0543 static auto fixedlen_vector_valuetypes() {
0544 return enum_seq_inclusive(MVT::FIRST_FIXEDLEN_VECTOR_VALUETYPE,
0545 MVT::LAST_FIXEDLEN_VECTOR_VALUETYPE,
0546 force_iteration_on_noniterable_enum);
0547 }
0548
0549 static auto scalable_vector_valuetypes() {
0550 return enum_seq_inclusive(MVT::FIRST_SCALABLE_VECTOR_VALUETYPE,
0551 MVT::LAST_SCALABLE_VECTOR_VALUETYPE,
0552 force_iteration_on_noniterable_enum);
0553 }
0554
0555 static auto integer_fixedlen_vector_valuetypes() {
0556 return enum_seq_inclusive(MVT::FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE,
0557 MVT::LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE,
0558 force_iteration_on_noniterable_enum);
0559 }
0560
0561 static auto fp_fixedlen_vector_valuetypes() {
0562 return enum_seq_inclusive(MVT::FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE,
0563 MVT::LAST_FP_FIXEDLEN_VECTOR_VALUETYPE,
0564 force_iteration_on_noniterable_enum);
0565 }
0566
0567 static auto integer_scalable_vector_valuetypes() {
0568 return enum_seq_inclusive(MVT::FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE,
0569 MVT::LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE,
0570 force_iteration_on_noniterable_enum);
0571 }
0572
0573 static auto fp_scalable_vector_valuetypes() {
0574 return enum_seq_inclusive(MVT::FIRST_FP_SCALABLE_VECTOR_VALUETYPE,
0575 MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE,
0576 force_iteration_on_noniterable_enum);
0577 }
0578
0579 };
0580
0581 inline raw_ostream &operator<<(raw_ostream &OS, const MVT &VT) {
0582 VT.print(OS);
0583 return OS;
0584 }
0585
0586 }
0587
0588 #endif