Issue converting unsized to sized types

I’ve added a new (fundamental) data type. However, while compiling, the following error occurs. I made the necessary changes to MachineValueType.h and ValueTypes.td to specify the size to be 16 bits but it doesn’t seem to have done so.

Here is a list of all the file changes I’ve made to add the data type:

  • Type.cpp & Type.h

  • Core.cpp & Core.h

  • LLVMContextImpl.cpp & LLVMContextImpl.h

  • AsmWriter.cpp

  • LLLexer.cpp

  • BitcodeReader.cpp & BitcodeWriter.cpp

  • LLVMBitCodes.h

  • MachineValueType.h

  • ValueTypes.td &ValueTypes.cpp

Cannot allocate unsized type
  %ao = alloca 188529083116, align 2
loading unsized types is not allowed
  %1 = load 188529083116, ptr %ao, align 2, !dbg !11

Look at source of the error, when figure out why it was triggered. Usually you can find something you forgot to implement directly.

For your error:

Check(AI.getAllocatedType()->isSized(&Visited),
        "Cannot allocate unsized type", &AI);

Where isSized is

/// Return true if it makes sense to take the size of this type. To get the
  /// actual size for a particular target, it is reasonable to use the
  /// DataLayout subsystem to do this.
  bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const {
    // If it's a primitive, it is always sized.
    if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
        getTypeID() == PointerTyID || getTypeID() == X86_MMXTyID ||
        getTypeID() == X86_AMXTyID)
      return true;
    // If it is not something that can have a size (e.g. a function or label),
    // it doesn't have a size.
    if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
        !isVectorTy() && getTypeID() != TargetExtTyID)
      return false;
    // Otherwise we have to try harder to decide.
    return isSizedDerivedType(Visited);
  }

Figure out whether you need to modify it to support your type (or if you type lack appropriate type id), or if you need to handle it in isSizedDerivedType.

1 Like

I’ve made the necessary change in isSized to take my datatype(AOType) as well.

bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const {
    // If it's a primitive, it is always sized.
    if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
        getTypeID() == PointerTyID || getTypeID() == X86_MMXTyID ||
        getTypeID() == X86_AMXTyID || getTypeID() == AOTyID)
      return true;

I ensured that my type has the type id added in the necessary files, but the issue persists.

enum TypeID {
    // PrimitiveTypes
    HalfTyID = 0,  ///< 16-bit floating point type
    BFloatTyID,    ///< 16-bit floating point type (7-bit significand)
    FloatTyID,     ///< 32-bit floating point type
    DoubleTyID,    ///< 64-bit floating point type
    X86_FP80TyID,  ///< 80-bit floating point type (X87)
    FP128TyID,     ///< 128-bit floating point type (112-bit significand)
    PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
    VoidTyID,      ///< type with no size
    LabelTyID,     ///< Labels
    MetadataTyID,  ///< Metadata
    X86_MMXTyID,   ///< MMX vectors (64 bits, X86 specific)
    X86_AMXTyID,   ///< AMX vectors (8192 bits, X86 specific)
    TokenTyID,     ///< Tokens
    AOTyID,         ///< 16-bit AO type

As well as specifying that it is a Primitive type as well as its size.

Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
  switch (IDNumber) {
  case VoidTyID      : return getVoidTy(C);
  case HalfTyID      : return getHalfTy(C);
  case BFloatTyID    : return getBFloatTy(C);
  case FloatTyID     : return getFloatTy(C);
  case DoubleTyID    : return getDoubleTy(C);
  case X86_FP80TyID  : return getX86_FP80Ty(C);
  case FP128TyID     : return getFP128Ty(C);
  case PPC_FP128TyID : return getPPC_FP128Ty(C);
  case LabelTyID     : return getLabelTy(C);
  case MetadataTyID  : return getMetadataTy(C);
  case X86_MMXTyID   : return getX86_MMXTy(C);
  case X86_AMXTyID   : return getX86_AMXTy(C);
  case TokenTyID     : return getTokenTy(C);
  case AOTyID        : return getAOTy(C);
  default:
    return nullptr;
  }
}
TypeSize Type::getPrimitiveSizeInBits() const {
  switch (getTypeID()) {
  case Type::HalfTyID: return TypeSize::Fixed(16);
  case Type::BFloatTyID: return TypeSize::Fixed(16);
  case Type::FloatTyID: return TypeSize::Fixed(32);
  case Type::DoubleTyID: return TypeSize::Fixed(64);
  case Type::X86_FP80TyID: return TypeSize::Fixed(80);
  case Type::FP128TyID: return TypeSize::Fixed(128);
  case Type::PPC_FP128TyID: return TypeSize::Fixed(128);
  case Type::X86_MMXTyID: return TypeSize::Fixed(64);
  case Type::X86_AMXTyID: return TypeSize::Fixed(8192);
  case Type::AOTyID: return TypeSize::Fixed(16);
  case Type::IntegerTyID:
    return TypeSize::Fixed(cast<IntegerType>(this)->getBitWidth());

I followed the following tutorial and added a couple of other dependencies as listed in my previous post, but I still don’t see what I’m missing as the issue persists.

Does YourType->isSized() return true? Perhaps you don’t create it properly/with the right type id (i.e. check thet getTypeID() ineed returns your AOTyID).

I’m sorry, I’m new to llvm, how can we test that?

Like with any other app - debugger and/or print statements (dbgs() << …) would work.

I’ve used asserts to check what isSized and gettypeid are returning but they don’t seem to return anything hence, I don’t think the AOTyID is a part of the type enum for some reason

What do you mean by " don’t seem to return anything hence"? They can’t not return anything. isSized MUST return either true or false (unless it triggers some assert and crashes) and getTypeID MUST return the type id. It might be the wrong type id (i.e. not AOTyID in your case), but then you’d now the problem (at which point I’d look into how you create your types).

I tried to get the type id that is used for isSized by using getTypeString() like so in LLParser.cpp, but it doesn’t seem to be returning the type id that isSized is trying to check for.

SmallPtrSet<Type *, 4> Visited;
  if (!Alignment && !Ty->isSized(&Visited))
    return error(TyLoc, "Cannot allocate unsized type " + getTypeString(Ty));
static std::string getTypeString(Type *T) {
  std::string Result;
  raw_string_ostream Tmp(Result);
  Tmp << *T;
  return Tmp.str();
}

If by ignored you mean that it prints nothing (just "Cannot allocate unsized type "), then it’s not a big surprise - you probably didn’t implement the string conversion for your type. I don’t see how this relates to the type id though.
Just add dbgs() << "isSized: " << yourType->isSized(&Visited) << ", typeId: " << yourType->getTypeID() << '\n'; somewhere where it is appropriate (i.e. you have an instance of yourType) and check if the output makes sense.

Yup, fixed it. It was an issue with the typeID not being linked to the machine value type so had to add dependencies for it. Thanks for the help!