diff --git a/llvm/include/llvm/Support/LowLevelTypeImpl.h b/llvm/include/llvm/Support/LowLevelTypeImpl.h --- a/llvm/include/llvm/Support/LowLevelTypeImpl.h +++ b/llvm/include/llvm/Support/LowLevelTypeImpl.h @@ -43,7 +43,13 @@ static LLT scalar(unsigned SizeInBits) { assert(SizeInBits > 0 && "invalid scalar size"); return LLT{/*isPointer=*/false, /*isVector=*/false, - ElementCount::getFixed(0), SizeInBits, + ElementCount::getFixed(0), SizeInBits, /*AddressSpace=*/0}; + } + + /// Get a low-level opaque type, defined as a scalar of zero size + static LLT opaque() { + return LLT{/*isPointer=*/false, /*isVector=*/false, + ElementCount::getFixed(0), 0, /*AddressSpace=*/0}; } @@ -66,7 +72,9 @@ static LLT vector(ElementCount EC, LLT ScalarTy) { assert(!EC.isScalar() && "invalid number of vector elements"); assert(!ScalarTy.isVector() && "invalid vector element type"); - return LLT{ScalarTy.isPointer(), /*isVector=*/true, EC, + return LLT{ScalarTy.isPointer(), + /*isVector=*/true, + EC, ScalarTy.getSizeInBits().getFixedSize(), ScalarTy.isPointer() ? ScalarTy.getAddressSpace() : 0}; } @@ -116,12 +124,18 @@ bool isValid() const { return RawData != 0; } - bool isScalar() const { return isValid() && !IsPointer && !IsVector; } + bool isScalar() const { + return isValid() && !IsPointer && !IsVector && getScalarSizeInBits() != 0; + } bool isPointer() const { return isValid() && IsPointer && !IsVector; } bool isVector() const { return isValid() && IsVector; } + bool isOpaque() const { + return isValid() && !IsPointer && !IsVector && getScalarSizeInBits() == 0; + } + /// Returns the number of elements in a vector LLT. Must only be called on /// vector types. uint16_t getNumElements() const { @@ -286,7 +300,7 @@ static const constexpr BitFieldInfo PointerAddressSpaceFieldInfo{ 24, PointerSizeFieldInfo[0] + PointerSizeFieldInfo[1]}; static_assert((PointerAddressSpaceFieldInfo[0] + - PointerAddressSpaceFieldInfo[1]) <= 62, + PointerAddressSpaceFieldInfo[1]) <= 61, "Insufficient bits to encode all data"); /// * Vector-of-non-pointer (isPointer == 0 && isVector == 1): /// NumElements: 16; @@ -297,7 +311,7 @@ 32, VectorElementsFieldInfo[0] + VectorElementsFieldInfo[1]}; static const constexpr BitFieldInfo VectorScalableFieldInfo{ 1, VectorSizeFieldInfo[0] + VectorSizeFieldInfo[1]}; - static_assert((VectorSizeFieldInfo[0] + VectorSizeFieldInfo[1]) <= 62, + static_assert((VectorSizeFieldInfo[0] + VectorSizeFieldInfo[1]) <= 61, "Insufficient bits to encode all data"); /// * Vector-of-pointer (isPointer == 1 && isVector == 1): /// NumElements: 16; @@ -314,12 +328,12 @@ 1, PointerVectorAddressSpaceFieldInfo[0] + PointerVectorAddressSpaceFieldInfo[1]}; static_assert((PointerVectorAddressSpaceFieldInfo[0] + - PointerVectorAddressSpaceFieldInfo[1]) <= 62, + PointerVectorAddressSpaceFieldInfo[1]) <= 61, "Insufficient bits to encode all data"); uint64_t IsPointer : 1; uint64_t IsVector : 1; - uint64_t RawData : 62; + uint64_t RawData : 61; static uint64_t getMask(const BitFieldInfo FieldInfo) { const int FieldSizeInBits = FieldInfo[0]; @@ -342,6 +356,7 @@ "Not enough bits in LLT to represent size"); this->IsPointer = IsPointer; this->IsVector = IsVector; + if (!IsVector) { if (!IsPointer) RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo); diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp --- a/llvm/lib/CodeGen/MachineOperand.cpp +++ b/llvm/lib/CodeGen/MachineOperand.cpp @@ -1048,9 +1048,12 @@ const MDNode *Ranges, SyncScope::ID SSID, AtomicOrdering Ordering, AtomicOrdering FailureOrdering) - : MachineMemOperand(ptrinfo, f, - s == ~UINT64_C(0) ? LLT() : LLT::scalar(8 * s), a, - AAInfo, Ranges, SSID, Ordering, FailureOrdering) {} + : MachineMemOperand( + ptrinfo, f, + s == ~UINT64_C(0) + ? LLT() + : (s == UINT64_C(0) ? LLT::opaque() : LLT::scalar(8 * s)), + a, AAInfo, Ranges, SSID, Ordering, FailureOrdering) {} /// Profile - Gather unique data for the object. /// diff --git a/llvm/lib/Support/LowLevelType.cpp b/llvm/lib/Support/LowLevelType.cpp --- a/llvm/lib/Support/LowLevelType.cpp +++ b/llvm/lib/Support/LowLevelType.cpp @@ -23,9 +23,12 @@ } else if (VT.isValid()) { // Aggregates are no different from real scalars as far as GlobalISel is // concerned. - assert(VT.getSizeInBits().isNonZero() && "invalid zero-sized type"); - init(/*IsPointer=*/false, /*IsVector=*/false, ElementCount::getFixed(0), - VT.getSizeInBits(), /*AddressSpace=*/0); + if (VT.getSizeInBits().isNonZero()) + init(/*IsPointer=*/false, /*IsVector=*/false, ElementCount::getFixed(0), + VT.getSizeInBits(), /*AddressSpace=*/0); + else + init(/*IsPointer=*/false, /*IsVector=*/false, ElementCount::getFixed(0), + VT.getSizeInBits(), /*AddressSpace=*/0); } else { IsPointer = false; IsVector = false; @@ -39,6 +42,8 @@ OS << getElementCount() << " x " << getElementType() << ">"; } else if (isPointer()) OS << "p" << getAddressSpace(); + else if (isOpaque()) + OS << ""; else if (isValid()) { assert(isScalar() && "unexpected type"); OS << "s" << getScalarSizeInBits();