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 @@ -47,6 +47,13 @@ /*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}; + } + /// Get a low-level pointer in the given address space. static LLT pointer(unsigned AddressSpace, unsigned SizeInBits) { assert(SizeInBits > 0 && "invalid pointer size"); @@ -116,12 +123,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 { 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();