10b57cec5SDimitry Andric //===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the set of low-level target independent types which various
100b57cec5SDimitry Andric // values in the code generator are.  This allows the target specific behavior
110b57cec5SDimitry Andric // of instructions to be described to target independent passes.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_VALUETYPES_H
160b57cec5SDimitry Andric #define LLVM_CODEGEN_VALUETYPES_H
170b57cec5SDimitry Andric 
1806c3fb27SDimitry Andric #include "llvm/CodeGen/MachineValueType.h"
190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
200b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
21480093f4SDimitry Andric #include "llvm/Support/TypeSize.h"
220b57cec5SDimitry Andric #include <cassert>
230b57cec5SDimitry Andric #include <cstdint>
240b57cec5SDimitry Andric #include <string>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace llvm {
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric   class LLVMContext;
290b57cec5SDimitry Andric   class Type;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric   /// Extended Value Type. Capable of holding value types which are not native
320b57cec5SDimitry Andric   /// for any processor (such as the i12345 type), as well as the types an MVT
330b57cec5SDimitry Andric   /// can represent.
340b57cec5SDimitry Andric   struct EVT {
350b57cec5SDimitry Andric   private:
360b57cec5SDimitry Andric     MVT V = MVT::INVALID_SIMPLE_VALUE_TYPE;
370b57cec5SDimitry Andric     Type *LLVMTy = nullptr;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   public:
400b57cec5SDimitry Andric     constexpr EVT() = default;
EVTEVT410b57cec5SDimitry Andric     constexpr EVT(MVT::SimpleValueType SVT) : V(SVT) {}
EVTEVT420b57cec5SDimitry Andric     constexpr EVT(MVT S) : V(S) {}
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric     bool operator==(EVT VT) const {
450b57cec5SDimitry Andric       return !(*this != VT);
460b57cec5SDimitry Andric     }
470b57cec5SDimitry Andric     bool operator!=(EVT VT) const {
480b57cec5SDimitry Andric       if (V.SimpleTy != VT.V.SimpleTy)
490b57cec5SDimitry Andric         return true;
500b57cec5SDimitry Andric       if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
510b57cec5SDimitry Andric         return LLVMTy != VT.LLVMTy;
520b57cec5SDimitry Andric       return false;
530b57cec5SDimitry Andric     }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric     /// Returns the EVT that represents a floating-point type with the given
560b57cec5SDimitry Andric     /// number of bits. There are two floating-point types with 128 bits - this
570b57cec5SDimitry Andric     /// returns f128 rather than ppcf128.
getFloatingPointVTEVT580b57cec5SDimitry Andric     static EVT getFloatingPointVT(unsigned BitWidth) {
590b57cec5SDimitry Andric       return MVT::getFloatingPointVT(BitWidth);
600b57cec5SDimitry Andric     }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric     /// Returns the EVT that represents an integer with the given number of
630b57cec5SDimitry Andric     /// bits.
getIntegerVTEVT640b57cec5SDimitry Andric     static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
650b57cec5SDimitry Andric       MVT M = MVT::getIntegerVT(BitWidth);
660b57cec5SDimitry Andric       if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
670b57cec5SDimitry Andric         return M;
680b57cec5SDimitry Andric       return getExtendedIntegerVT(Context, BitWidth);
690b57cec5SDimitry Andric     }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric     /// Returns the EVT that represents a vector NumElements in length, where
720b57cec5SDimitry Andric     /// each element is of type VT.
730b57cec5SDimitry Andric     static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements,
740b57cec5SDimitry Andric                            bool IsScalable = false) {
750b57cec5SDimitry Andric       MVT M = MVT::getVectorVT(VT.V, NumElements, IsScalable);
760b57cec5SDimitry Andric       if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
770b57cec5SDimitry Andric         return M;
785ffd83dbSDimitry Andric       return getExtendedVectorVT(Context, VT, NumElements, IsScalable);
790b57cec5SDimitry Andric     }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric     /// Returns the EVT that represents a vector EC.Min elements in length,
820b57cec5SDimitry Andric     /// where each element is of type VT.
getVectorVTEVT838bcb0991SDimitry Andric     static EVT getVectorVT(LLVMContext &Context, EVT VT, ElementCount EC) {
840b57cec5SDimitry Andric       MVT M = MVT::getVectorVT(VT.V, EC);
850b57cec5SDimitry Andric       if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
860b57cec5SDimitry Andric         return M;
875ffd83dbSDimitry Andric       return getExtendedVectorVT(Context, VT, EC);
880b57cec5SDimitry Andric     }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric     /// Return a vector with the same number of elements as this vector, but
910b57cec5SDimitry Andric     /// with the element type converted to an integer type with the same
920b57cec5SDimitry Andric     /// bitwidth.
changeVectorElementTypeToIntegerEVT930b57cec5SDimitry Andric     EVT changeVectorElementTypeToInteger() const {
94e8d8bef9SDimitry Andric       if (isSimple())
95e8d8bef9SDimitry Andric         return getSimpleVT().changeVectorElementTypeToInteger();
960b57cec5SDimitry Andric       return changeExtendedVectorElementTypeToInteger();
975ffd83dbSDimitry Andric     }
985ffd83dbSDimitry Andric 
995ffd83dbSDimitry Andric     /// Return a VT for a vector type whose attributes match ourselves
1005ffd83dbSDimitry Andric     /// with the exception of the element type that is chosen by the caller.
changeVectorElementTypeEVT1015ffd83dbSDimitry Andric     EVT changeVectorElementType(EVT EltVT) const {
102fe6060f1SDimitry Andric       if (isSimple()) {
103fe6060f1SDimitry Andric         assert(EltVT.isSimple() &&
104fe6060f1SDimitry Andric                "Can't change simple vector VT to have extended element VT");
105e8d8bef9SDimitry Andric         return getSimpleVT().changeVectorElementType(EltVT.getSimpleVT());
106fe6060f1SDimitry Andric       }
1075ffd83dbSDimitry Andric       return changeExtendedVectorElementType(EltVT);
1080b57cec5SDimitry Andric     }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric     /// Return the type converted to an equivalently sized integer or vector
1110b57cec5SDimitry Andric     /// with integer element type. Similar to changeVectorElementTypeToInteger,
1120b57cec5SDimitry Andric     /// but also handles scalars.
changeTypeToIntegerEVT11306c3fb27SDimitry Andric     EVT changeTypeToInteger() const {
1140b57cec5SDimitry Andric       if (isVector())
1150b57cec5SDimitry Andric         return changeVectorElementTypeToInteger();
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric       if (isSimple())
118e8d8bef9SDimitry Andric         return getSimpleVT().changeTypeToInteger();
1190b57cec5SDimitry Andric       return changeExtendedTypeToInteger();
1200b57cec5SDimitry Andric     }
1210b57cec5SDimitry Andric 
122fe6060f1SDimitry Andric     /// Test if the given EVT has zero size, this will fail if called on a
123fe6060f1SDimitry Andric     /// scalable type
isZeroSizedEVT124fe6060f1SDimitry Andric     bool isZeroSized() const {
12506c3fb27SDimitry Andric       return getSizeInBits().isZero();
126fe6060f1SDimitry Andric     }
127fe6060f1SDimitry Andric 
1280b57cec5SDimitry Andric     /// Test if the given EVT is simple (as opposed to being extended).
isSimpleEVT1290b57cec5SDimitry Andric     bool isSimple() const {
1300b57cec5SDimitry Andric       return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE;
1310b57cec5SDimitry Andric     }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric     /// Test if the given EVT is extended (as opposed to being simple).
isExtendedEVT1340b57cec5SDimitry Andric     bool isExtended() const {
1350b57cec5SDimitry Andric       return !isSimple();
1360b57cec5SDimitry Andric     }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric     /// Return true if this is a FP or a vector FP type.
isFloatingPointEVT1390b57cec5SDimitry Andric     bool isFloatingPoint() const {
1400b57cec5SDimitry Andric       return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
1410b57cec5SDimitry Andric     }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric     /// Return true if this is an integer or a vector integer type.
isIntegerEVT1440b57cec5SDimitry Andric     bool isInteger() const {
1450b57cec5SDimitry Andric       return isSimple() ? V.isInteger() : isExtendedInteger();
1460b57cec5SDimitry Andric     }
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric     /// Return true if this is an integer, but not a vector.
isScalarIntegerEVT1490b57cec5SDimitry Andric     bool isScalarInteger() const {
1500b57cec5SDimitry Andric       return isSimple() ? V.isScalarInteger() : isExtendedScalarInteger();
1510b57cec5SDimitry Andric     }
1520b57cec5SDimitry Andric 
15306c3fb27SDimitry Andric     /// Return true if this is a vector type where the runtime
15406c3fb27SDimitry Andric     /// length is machine dependent
isScalableTargetExtVTEVT15506c3fb27SDimitry Andric     bool isScalableTargetExtVT() const {
15606c3fb27SDimitry Andric       return isSimple() && V.isScalableTargetExtVT();
15706c3fb27SDimitry Andric     }
15806c3fb27SDimitry Andric 
1590b57cec5SDimitry Andric     /// Return true if this is a vector value type.
isVectorEVT1600b57cec5SDimitry Andric     bool isVector() const {
1610b57cec5SDimitry Andric       return isSimple() ? V.isVector() : isExtendedVector();
1620b57cec5SDimitry Andric     }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric     /// Return true if this is a vector type where the runtime
1650b57cec5SDimitry Andric     /// length is machine dependent
isScalableVectorEVT1660b57cec5SDimitry Andric     bool isScalableVector() const {
1675ffd83dbSDimitry Andric       return isSimple() ? V.isScalableVector() : isExtendedScalableVector();
1685ffd83dbSDimitry Andric     }
1695ffd83dbSDimitry Andric 
isFixedLengthVectorEVT1705ffd83dbSDimitry Andric     bool isFixedLengthVector() const {
1715ffd83dbSDimitry Andric       return isSimple() ? V.isFixedLengthVector()
1725ffd83dbSDimitry Andric                         : isExtendedFixedLengthVector();
1730b57cec5SDimitry Andric     }
1740b57cec5SDimitry Andric 
17506c3fb27SDimitry Andric     /// Return true if the type is a scalable type.
isScalableVTEVT17606c3fb27SDimitry Andric     bool isScalableVT() const {
17706c3fb27SDimitry Andric       return isScalableVector() || isScalableTargetExtVT();
17806c3fb27SDimitry Andric     }
17906c3fb27SDimitry Andric 
1800b57cec5SDimitry Andric     /// Return true if this is a 16-bit vector type.
is16BitVectorEVT1810b57cec5SDimitry Andric     bool is16BitVector() const {
1820b57cec5SDimitry Andric       return isSimple() ? V.is16BitVector() : isExtended16BitVector();
1830b57cec5SDimitry Andric     }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric     /// Return true if this is a 32-bit vector type.
is32BitVectorEVT1860b57cec5SDimitry Andric     bool is32BitVector() const {
1870b57cec5SDimitry Andric       return isSimple() ? V.is32BitVector() : isExtended32BitVector();
1880b57cec5SDimitry Andric     }
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric     /// Return true if this is a 64-bit vector type.
is64BitVectorEVT1910b57cec5SDimitry Andric     bool is64BitVector() const {
1920b57cec5SDimitry Andric       return isSimple() ? V.is64BitVector() : isExtended64BitVector();
1930b57cec5SDimitry Andric     }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric     /// Return true if this is a 128-bit vector type.
is128BitVectorEVT1960b57cec5SDimitry Andric     bool is128BitVector() const {
1970b57cec5SDimitry Andric       return isSimple() ? V.is128BitVector() : isExtended128BitVector();
1980b57cec5SDimitry Andric     }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric     /// Return true if this is a 256-bit vector type.
is256BitVectorEVT2010b57cec5SDimitry Andric     bool is256BitVector() const {
2020b57cec5SDimitry Andric       return isSimple() ? V.is256BitVector() : isExtended256BitVector();
2030b57cec5SDimitry Andric     }
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric     /// Return true if this is a 512-bit vector type.
is512BitVectorEVT2060b57cec5SDimitry Andric     bool is512BitVector() const {
2070b57cec5SDimitry Andric       return isSimple() ? V.is512BitVector() : isExtended512BitVector();
2080b57cec5SDimitry Andric     }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric     /// Return true if this is a 1024-bit vector type.
is1024BitVectorEVT2110b57cec5SDimitry Andric     bool is1024BitVector() const {
2120b57cec5SDimitry Andric       return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
2130b57cec5SDimitry Andric     }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric     /// Return true if this is a 2048-bit vector type.
is2048BitVectorEVT2160b57cec5SDimitry Andric     bool is2048BitVector() const {
2170b57cec5SDimitry Andric       return isSimple() ? V.is2048BitVector() : isExtended2048BitVector();
2180b57cec5SDimitry Andric     }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric     /// Return true if this is an overloaded type for TableGen.
isOverloadedEVT2210b57cec5SDimitry Andric     bool isOverloaded() const {
2220b57cec5SDimitry Andric       return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
2230b57cec5SDimitry Andric     }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric     /// Return true if the bit size is a multiple of 8.
isByteSizedEVT226fe6060f1SDimitry Andric     bool isByteSized() const {
227fe6060f1SDimitry Andric       return !isZeroSized() && getSizeInBits().isKnownMultipleOf(8);
228fe6060f1SDimitry Andric     }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric     /// Return true if the size is a power-of-two number of bytes.
isRoundEVT2310b57cec5SDimitry Andric     bool isRound() const {
232480093f4SDimitry Andric       if (isScalableVector())
233480093f4SDimitry Andric         return false;
2340b57cec5SDimitry Andric       unsigned BitSize = getSizeInBits();
2350b57cec5SDimitry Andric       return BitSize >= 8 && !(BitSize & (BitSize - 1));
2360b57cec5SDimitry Andric     }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric     /// Return true if this has the same number of bits as VT.
bitsEqEVT2390b57cec5SDimitry Andric     bool bitsEq(EVT VT) const {
2400b57cec5SDimitry Andric       if (EVT::operator==(VT)) return true;
2410b57cec5SDimitry Andric       return getSizeInBits() == VT.getSizeInBits();
2420b57cec5SDimitry Andric     }
2430b57cec5SDimitry Andric 
244e8d8bef9SDimitry Andric     /// Return true if we know at compile time this has more bits than VT.
knownBitsGTEVT245e8d8bef9SDimitry Andric     bool knownBitsGT(EVT VT) const {
246e8d8bef9SDimitry Andric       return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
247e8d8bef9SDimitry Andric     }
248e8d8bef9SDimitry Andric 
249e8d8bef9SDimitry Andric     /// Return true if we know at compile time this has more than or the same
250e8d8bef9SDimitry Andric     /// bits as VT.
knownBitsGEEVT251e8d8bef9SDimitry Andric     bool knownBitsGE(EVT VT) const {
252e8d8bef9SDimitry Andric       return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
253e8d8bef9SDimitry Andric     }
254e8d8bef9SDimitry Andric 
255e8d8bef9SDimitry Andric     /// Return true if we know at compile time this has fewer bits than VT.
knownBitsLTEVT256e8d8bef9SDimitry Andric     bool knownBitsLT(EVT VT) const {
257e8d8bef9SDimitry Andric       return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
258e8d8bef9SDimitry Andric     }
259e8d8bef9SDimitry Andric 
260e8d8bef9SDimitry Andric     /// Return true if we know at compile time this has fewer than or the same
261e8d8bef9SDimitry Andric     /// bits as VT.
knownBitsLEEVT262e8d8bef9SDimitry Andric     bool knownBitsLE(EVT VT) const {
263e8d8bef9SDimitry Andric       return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
264e8d8bef9SDimitry Andric     }
265e8d8bef9SDimitry Andric 
2660b57cec5SDimitry Andric     /// Return true if this has more bits than VT.
bitsGTEVT2670b57cec5SDimitry Andric     bool bitsGT(EVT VT) const {
2680b57cec5SDimitry Andric       if (EVT::operator==(VT)) return false;
269e8d8bef9SDimitry Andric       assert(isScalableVector() == VT.isScalableVector() &&
270e8d8bef9SDimitry Andric              "Comparison between scalable and fixed types");
271e8d8bef9SDimitry Andric       return knownBitsGT(VT);
2720b57cec5SDimitry Andric     }
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric     /// Return true if this has no less bits than VT.
bitsGEEVT2750b57cec5SDimitry Andric     bool bitsGE(EVT VT) const {
2760b57cec5SDimitry Andric       if (EVT::operator==(VT)) return true;
277e8d8bef9SDimitry Andric       assert(isScalableVector() == VT.isScalableVector() &&
278e8d8bef9SDimitry Andric              "Comparison between scalable and fixed types");
279e8d8bef9SDimitry Andric       return knownBitsGE(VT);
2800b57cec5SDimitry Andric     }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric     /// Return true if this has less bits than VT.
bitsLTEVT2830b57cec5SDimitry Andric     bool bitsLT(EVT VT) const {
2840b57cec5SDimitry Andric       if (EVT::operator==(VT)) return false;
285e8d8bef9SDimitry Andric       assert(isScalableVector() == VT.isScalableVector() &&
286e8d8bef9SDimitry Andric              "Comparison between scalable and fixed types");
287e8d8bef9SDimitry Andric       return knownBitsLT(VT);
2880b57cec5SDimitry Andric     }
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric     /// Return true if this has no more bits than VT.
bitsLEEVT2910b57cec5SDimitry Andric     bool bitsLE(EVT VT) const {
2920b57cec5SDimitry Andric       if (EVT::operator==(VT)) return true;
293e8d8bef9SDimitry Andric       assert(isScalableVector() == VT.isScalableVector() &&
294e8d8bef9SDimitry Andric              "Comparison between scalable and fixed types");
295e8d8bef9SDimitry Andric       return knownBitsLE(VT);
2960b57cec5SDimitry Andric     }
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric     /// Return the SimpleValueType held in the specified simple EVT.
getSimpleVTEVT2990b57cec5SDimitry Andric     MVT getSimpleVT() const {
3000b57cec5SDimitry Andric       assert(isSimple() && "Expected a SimpleValueType!");
3010b57cec5SDimitry Andric       return V;
3020b57cec5SDimitry Andric     }
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric     /// If this is a vector type, return the element type, otherwise return
3050b57cec5SDimitry Andric     /// this.
getScalarTypeEVT3060b57cec5SDimitry Andric     EVT getScalarType() const {
3070b57cec5SDimitry Andric       return isVector() ? getVectorElementType() : *this;
3080b57cec5SDimitry Andric     }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric     /// Given a vector type, return the type of each element.
getVectorElementTypeEVT3110b57cec5SDimitry Andric     EVT getVectorElementType() const {
3120b57cec5SDimitry Andric       assert(isVector() && "Invalid vector type!");
3130b57cec5SDimitry Andric       if (isSimple())
3140b57cec5SDimitry Andric         return V.getVectorElementType();
3150b57cec5SDimitry Andric       return getExtendedVectorElementType();
3160b57cec5SDimitry Andric     }
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric     /// Given a vector type, return the number of elements it contains.
getVectorNumElementsEVT3190b57cec5SDimitry Andric     unsigned getVectorNumElements() const {
3200b57cec5SDimitry Andric       assert(isVector() && "Invalid vector type!");
321fe6060f1SDimitry Andric 
3225ffd83dbSDimitry Andric       if (isScalableVector())
323fe6060f1SDimitry Andric         llvm::reportInvalidSizeRequest(
324fe6060f1SDimitry Andric             "Possible incorrect use of EVT::getVectorNumElements() for "
3255ffd83dbSDimitry Andric             "scalable vector. Scalable flag may be dropped, use "
326fe6060f1SDimitry Andric             "EVT::getVectorElementCount() instead");
327fe6060f1SDimitry Andric 
328fe6060f1SDimitry Andric       return isSimple() ? V.getVectorNumElements()
329fe6060f1SDimitry Andric                         : getExtendedVectorNumElements();
3300b57cec5SDimitry Andric     }
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric     // Given a (possibly scalable) vector type, return the ElementCount
getVectorElementCountEVT3338bcb0991SDimitry Andric     ElementCount getVectorElementCount() const {
3340b57cec5SDimitry Andric       assert((isVector()) && "Invalid vector type!");
3350b57cec5SDimitry Andric       if (isSimple())
3360b57cec5SDimitry Andric         return V.getVectorElementCount();
3370b57cec5SDimitry Andric 
3385ffd83dbSDimitry Andric       return getExtendedVectorElementCount();
3395ffd83dbSDimitry Andric     }
3405ffd83dbSDimitry Andric 
3415ffd83dbSDimitry Andric     /// Given a vector type, return the minimum number of elements it contains.
getVectorMinNumElementsEVT3425ffd83dbSDimitry Andric     unsigned getVectorMinNumElements() const {
343e8d8bef9SDimitry Andric       return getVectorElementCount().getKnownMinValue();
3440b57cec5SDimitry Andric     }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric     /// Return the size of the specified value type in bits.
347480093f4SDimitry Andric     ///
348480093f4SDimitry Andric     /// If the value type is a scalable vector type, the scalable property will
349480093f4SDimitry Andric     /// be set and the runtime size will be a positive integer multiple of the
350480093f4SDimitry Andric     /// base size.
getSizeInBitsEVT351480093f4SDimitry Andric     TypeSize getSizeInBits() const {
3520b57cec5SDimitry Andric       if (isSimple())
3530b57cec5SDimitry Andric         return V.getSizeInBits();
3540b57cec5SDimitry Andric       return getExtendedSizeInBits();
3550b57cec5SDimitry Andric     }
3560b57cec5SDimitry Andric 
357e8d8bef9SDimitry Andric     /// Return the size of the specified fixed width value type in bits. The
358e8d8bef9SDimitry Andric     /// function will assert if the type is scalable.
getFixedSizeInBitsEVT359e8d8bef9SDimitry Andric     uint64_t getFixedSizeInBits() const {
360bdd1243dSDimitry Andric       return getSizeInBits().getFixedValue();
361e8d8bef9SDimitry Andric     }
362e8d8bef9SDimitry Andric 
getScalarSizeInBitsEVT363e8d8bef9SDimitry Andric     uint64_t getScalarSizeInBits() const {
364bdd1243dSDimitry Andric       return getScalarType().getSizeInBits().getFixedValue();
3650b57cec5SDimitry Andric     }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric     /// Return the number of bytes overwritten by a store of the specified value
3680b57cec5SDimitry Andric     /// type.
369480093f4SDimitry Andric     ///
370480093f4SDimitry Andric     /// If the value type is a scalable vector type, the scalable property will
371480093f4SDimitry Andric     /// be set and the runtime size will be a positive integer multiple of the
372480093f4SDimitry Andric     /// base size.
getStoreSizeEVT373480093f4SDimitry Andric     TypeSize getStoreSize() const {
374480093f4SDimitry Andric       TypeSize BaseSize = getSizeInBits();
375bdd1243dSDimitry Andric       return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
3760b57cec5SDimitry Andric     }
3770b57cec5SDimitry Andric 
37881ad6265SDimitry Andric     // Return the number of bytes overwritten by a store of this value type or
37981ad6265SDimitry Andric     // this value type's element type in the case of a vector.
getScalarStoreSizeEVT38081ad6265SDimitry Andric     uint64_t getScalarStoreSize() const {
381bdd1243dSDimitry Andric       return getScalarType().getStoreSize().getFixedValue();
38281ad6265SDimitry Andric     }
38381ad6265SDimitry Andric 
3840b57cec5SDimitry Andric     /// Return the number of bits overwritten by a store of the specified value
3850b57cec5SDimitry Andric     /// type.
386480093f4SDimitry Andric     ///
387480093f4SDimitry Andric     /// If the value type is a scalable vector type, the scalable property will
388480093f4SDimitry Andric     /// be set and the runtime size will be a positive integer multiple of the
389480093f4SDimitry Andric     /// base size.
getStoreSizeInBitsEVT390480093f4SDimitry Andric     TypeSize getStoreSizeInBits() const {
3910b57cec5SDimitry Andric       return getStoreSize() * 8;
3920b57cec5SDimitry Andric     }
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric     /// Rounds the bit-width of the given integer EVT up to the nearest power of
3950b57cec5SDimitry Andric     /// two (and at least to eight), and returns the integer EVT with that
3960b57cec5SDimitry Andric     /// number of bits.
getRoundIntegerTypeEVT3970b57cec5SDimitry Andric     EVT getRoundIntegerType(LLVMContext &Context) const {
3980b57cec5SDimitry Andric       assert(isInteger() && !isVector() && "Invalid integer type!");
3990b57cec5SDimitry Andric       unsigned BitWidth = getSizeInBits();
4000b57cec5SDimitry Andric       if (BitWidth <= 8)
4010b57cec5SDimitry Andric         return EVT(MVT::i8);
402bdd1243dSDimitry Andric       return getIntegerVT(Context, llvm::bit_ceil(BitWidth));
4030b57cec5SDimitry Andric     }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric     /// Finds the smallest simple value type that is greater than or equal to
4060b57cec5SDimitry Andric     /// half the width of this EVT. If no simple value type can be found, an
4070b57cec5SDimitry Andric     /// extended integer value type of half the size (rounded up) is returned.
getHalfSizedIntegerVTEVT4080b57cec5SDimitry Andric     EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
4090b57cec5SDimitry Andric       assert(isInteger() && !isVector() && "Invalid integer type!");
4100b57cec5SDimitry Andric       unsigned EVTSize = getSizeInBits();
4110b57cec5SDimitry Andric       for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
4120b57cec5SDimitry Andric           IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
4130b57cec5SDimitry Andric         EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
4140b57cec5SDimitry Andric         if (HalfVT.getSizeInBits() * 2 >= EVTSize)
4150b57cec5SDimitry Andric           return HalfVT;
4160b57cec5SDimitry Andric       }
4170b57cec5SDimitry Andric       return getIntegerVT(Context, (EVTSize + 1) / 2);
4180b57cec5SDimitry Andric     }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric     /// Return a VT for an integer vector type with the size of the
4210b57cec5SDimitry Andric     /// elements doubled. The typed returned may be an extended type.
widenIntegerVectorElementTypeEVT4220b57cec5SDimitry Andric     EVT widenIntegerVectorElementType(LLVMContext &Context) const {
4230b57cec5SDimitry Andric       EVT EltVT = getVectorElementType();
4240b57cec5SDimitry Andric       EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
4250b57cec5SDimitry Andric       return EVT::getVectorVT(Context, EltVT, getVectorElementCount());
4260b57cec5SDimitry Andric     }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric     // Return a VT for a vector type with the same element type but
4290b57cec5SDimitry Andric     // half the number of elements. The type returned may be an
4300b57cec5SDimitry Andric     // extended type.
getHalfNumVectorElementsVTEVT4310b57cec5SDimitry Andric     EVT getHalfNumVectorElementsVT(LLVMContext &Context) const {
4320b57cec5SDimitry Andric       EVT EltVT = getVectorElementType();
4330b57cec5SDimitry Andric       auto EltCnt = getVectorElementCount();
434e8d8bef9SDimitry Andric       assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
435e8d8bef9SDimitry Andric       return EVT::getVectorVT(Context, EltVT, EltCnt.divideCoefficientBy(2));
436e8d8bef9SDimitry Andric     }
437e8d8bef9SDimitry Andric 
438e8d8bef9SDimitry Andric     // Return a VT for a vector type with the same element type but
439e8d8bef9SDimitry Andric     // double the number of elements. The type returned may be an
440e8d8bef9SDimitry Andric     // extended type.
getDoubleNumVectorElementsVTEVT441e8d8bef9SDimitry Andric     EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const {
442e8d8bef9SDimitry Andric       EVT EltVT = getVectorElementType();
443e8d8bef9SDimitry Andric       auto EltCnt = getVectorElementCount();
444e8d8bef9SDimitry Andric       return EVT::getVectorVT(Context, EltVT, EltCnt * 2);
4450b57cec5SDimitry Andric     }
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric     /// Returns true if the given vector is a power of 2.
isPow2VectorTypeEVT4480b57cec5SDimitry Andric     bool isPow2VectorType() const {
4495ffd83dbSDimitry Andric       unsigned NElts = getVectorMinNumElements();
4500b57cec5SDimitry Andric       return !(NElts & (NElts - 1));
4510b57cec5SDimitry Andric     }
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric     /// Widens the length of the given vector EVT up to the nearest power of 2
4540b57cec5SDimitry Andric     /// and returns that type.
getPow2VectorTypeEVT4550b57cec5SDimitry Andric     EVT getPow2VectorType(LLVMContext &Context) const {
4560b57cec5SDimitry Andric       if (!isPow2VectorType()) {
4575ffd83dbSDimitry Andric         ElementCount NElts = getVectorElementCount();
458e8d8bef9SDimitry Andric         unsigned NewMinCount = 1 << Log2_32_Ceil(NElts.getKnownMinValue());
459e8d8bef9SDimitry Andric         NElts = ElementCount::get(NewMinCount, NElts.isScalable());
4605ffd83dbSDimitry Andric         return EVT::getVectorVT(Context, getVectorElementType(), NElts);
4610b57cec5SDimitry Andric       }
4620b57cec5SDimitry Andric       else {
4630b57cec5SDimitry Andric         return *this;
4640b57cec5SDimitry Andric       }
4650b57cec5SDimitry Andric     }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric     /// This function returns value type as a string, e.g. "i32".
4680b57cec5SDimitry Andric     std::string getEVTString() const;
4690b57cec5SDimitry Andric 
47006c3fb27SDimitry Andric     /// Support for debugging, callable in GDB: VT.dump()
47106c3fb27SDimitry Andric     void dump() const;
47206c3fb27SDimitry Andric 
47306c3fb27SDimitry Andric     /// Implement operator<<.
printEVT47406c3fb27SDimitry Andric     void print(raw_ostream &OS) const {
47506c3fb27SDimitry Andric       OS << getEVTString();
47606c3fb27SDimitry Andric     }
47706c3fb27SDimitry Andric 
4780b57cec5SDimitry Andric     /// This method returns an LLVM type corresponding to the specified EVT.
4790b57cec5SDimitry Andric     /// For integer types, this returns an unsigned type. Note that this will
4800b57cec5SDimitry Andric     /// abort for types that cannot be represented.
4810b57cec5SDimitry Andric     Type *getTypeForEVT(LLVMContext &Context) const;
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric     /// Return the value type corresponding to the specified type.
4840b57cec5SDimitry Andric     /// This returns all pointers as iPTR.  If HandleUnknown is true, unknown
4850b57cec5SDimitry Andric     /// types are returned as Other, otherwise they are invalid.
4860b57cec5SDimitry Andric     static EVT getEVT(Type *Ty, bool HandleUnknown = false);
4870b57cec5SDimitry Andric 
getRawBitsEVT4880b57cec5SDimitry Andric     intptr_t getRawBits() const {
4890b57cec5SDimitry Andric       if (isSimple())
4900b57cec5SDimitry Andric         return V.SimpleTy;
4910b57cec5SDimitry Andric       else
4920b57cec5SDimitry Andric         return (intptr_t)(LLVMTy);
4930b57cec5SDimitry Andric     }
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric     /// A meaningless but well-behaved order, useful for constructing
4960b57cec5SDimitry Andric     /// containers.
4970b57cec5SDimitry Andric     struct compareRawBits {
operatorEVT::compareRawBits4980b57cec5SDimitry Andric       bool operator()(EVT L, EVT R) const {
4990b57cec5SDimitry Andric         if (L.V.SimpleTy == R.V.SimpleTy)
5000b57cec5SDimitry Andric           return L.LLVMTy < R.LLVMTy;
5010b57cec5SDimitry Andric         else
5020b57cec5SDimitry Andric           return L.V.SimpleTy < R.V.SimpleTy;
5030b57cec5SDimitry Andric       }
5040b57cec5SDimitry Andric     };
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric   private:
5070b57cec5SDimitry Andric     // Methods for handling the Extended-type case in functions above.
5080b57cec5SDimitry Andric     // These are all out-of-line to prevent users of this header file
5090b57cec5SDimitry Andric     // from having a dependency on Type.h.
5100b57cec5SDimitry Andric     EVT changeExtendedTypeToInteger() const;
5115ffd83dbSDimitry Andric     EVT changeExtendedVectorElementType(EVT EltVT) const;
5120b57cec5SDimitry Andric     EVT changeExtendedVectorElementTypeToInteger() const;
5130b57cec5SDimitry Andric     static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
5145ffd83dbSDimitry Andric     static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements,
5155ffd83dbSDimitry Andric                                    bool IsScalable);
5165ffd83dbSDimitry Andric     static EVT getExtendedVectorVT(LLVMContext &Context, EVT VT,
5175ffd83dbSDimitry Andric                                    ElementCount EC);
5180b57cec5SDimitry Andric     bool isExtendedFloatingPoint() const LLVM_READONLY;
5190b57cec5SDimitry Andric     bool isExtendedInteger() const LLVM_READONLY;
5200b57cec5SDimitry Andric     bool isExtendedScalarInteger() const LLVM_READONLY;
5210b57cec5SDimitry Andric     bool isExtendedVector() const LLVM_READONLY;
5220b57cec5SDimitry Andric     bool isExtended16BitVector() const LLVM_READONLY;
5230b57cec5SDimitry Andric     bool isExtended32BitVector() const LLVM_READONLY;
5240b57cec5SDimitry Andric     bool isExtended64BitVector() const LLVM_READONLY;
5250b57cec5SDimitry Andric     bool isExtended128BitVector() const LLVM_READONLY;
5260b57cec5SDimitry Andric     bool isExtended256BitVector() const LLVM_READONLY;
5270b57cec5SDimitry Andric     bool isExtended512BitVector() const LLVM_READONLY;
5280b57cec5SDimitry Andric     bool isExtended1024BitVector() const LLVM_READONLY;
5290b57cec5SDimitry Andric     bool isExtended2048BitVector() const LLVM_READONLY;
5305ffd83dbSDimitry Andric     bool isExtendedFixedLengthVector() const LLVM_READONLY;
5315ffd83dbSDimitry Andric     bool isExtendedScalableVector() const LLVM_READONLY;
5320b57cec5SDimitry Andric     EVT getExtendedVectorElementType() const;
5330b57cec5SDimitry Andric     unsigned getExtendedVectorNumElements() const LLVM_READONLY;
5345ffd83dbSDimitry Andric     ElementCount getExtendedVectorElementCount() const LLVM_READONLY;
535480093f4SDimitry Andric     TypeSize getExtendedSizeInBits() const LLVM_READONLY;
5360b57cec5SDimitry Andric   };
5370b57cec5SDimitry Andric 
53806c3fb27SDimitry Andric   inline raw_ostream &operator<<(raw_ostream &OS, const EVT &V) {
53906c3fb27SDimitry Andric     V.print(OS);
54006c3fb27SDimitry Andric     return OS;
54106c3fb27SDimitry Andric   }
5420b57cec5SDimitry Andric } // end namespace llvm
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric #endif // LLVM_CODEGEN_VALUETYPES_H
545