@@ -687,15 +687,26 @@ llvm::Value *irgen::getFixedTypeEnumTagSinglePayload(
687687
688688 llvm::Value *caseIndexFromValue = zero;
689689 if (fixedSize > Size (0 )) {
690- // Read up to one pointer-sized 'chunk' of the payload.
691- // The size of the chunk does not have to be a power of 2.
692- auto *caseIndexType = llvm::IntegerType::get (Ctx,
693- fixedSize.getValueInBits ());
694- auto *caseIndexAddr = Builder.CreateBitCast (valueAddr,
695- caseIndexType->getPointerTo ());
696- caseIndexFromValue = Builder.CreateZExtOrTrunc (
697- Builder.CreateLoad (Address (caseIndexAddr, Alignment (1 ))),
698- IGM.Int32Ty );
690+ // llvm only supports integer types upto a certain size (i.e selection dag
691+ // will crash).
692+ if (fixedSize.getValueInBits () <= llvm::IntegerType::MAX_INT_BITS / 4 ) {
693+ // Read up to one pointer-sized 'chunk' of the payload.
694+ // The size of the chunk does not have to be a power of 2.
695+ auto *caseIndexType =
696+ llvm::IntegerType::get (Ctx, fixedSize.getValueInBits ());
697+ auto *caseIndexAddr =
698+ Builder.CreateBitCast (valueAddr, caseIndexType->getPointerTo ());
699+ caseIndexFromValue = Builder.CreateZExtOrTrunc (
700+ Builder.CreateLoad (Address (caseIndexAddr, Alignment (1 ))),
701+ IGM.Int32Ty );
702+ } else {
703+ auto *caseIndexType = llvm::IntegerType::get (Ctx, 32 );
704+ auto *caseIndexAddr =
705+ Builder.CreateBitCast (valueAddr, caseIndexType->getPointerTo ());
706+ caseIndexFromValue = Builder.CreateZExtOrTrunc (
707+ Builder.CreateLoad (Address (caseIndexAddr, Alignment (1 ))),
708+ IGM.Int32Ty );
709+ }
699710 }
700711
701712 auto *result1 = Builder.CreateAdd (
@@ -867,11 +878,25 @@ void irgen::storeFixedTypeEnumTagSinglePayload(
867878 payloadIndex->addIncoming (payloadIndex0, payloadLT4BB);
868879
869880 if (fixedSize > Size (0 )) {
870- // Write the value to the payload as a zero extended integer.
871- auto *intType = Builder.getIntNTy (fixedSize.getValueInBits ());
872- Builder.CreateStore (
873- Builder.CreateZExtOrTrunc (payloadIndex, intType),
874- Builder.CreateBitCast (valueAddr, intType->getPointerTo ()));
881+ if (fixedSize.getValueInBits () <= llvm::IntegerType::MAX_INT_BITS / 4 ) {
882+ // Write the value to the payload as a zero extended integer.
883+ auto *intType = Builder.getIntNTy (fixedSize.getValueInBits ());
884+ Builder.CreateStore (
885+ Builder.CreateZExtOrTrunc (payloadIndex, intType),
886+ Builder.CreateBitCast (valueAddr, intType->getPointerTo ()));
887+ } else {
888+ // Write the value to the payload as a zero extended integer.
889+ Size limit = IGM.getPointerSize ();
890+ auto *intType = Builder.getIntNTy (limit.getValueInBits ());
891+ Builder.CreateStore (
892+ Builder.CreateZExtOrTrunc (payloadIndex, intType),
893+ Builder.CreateBitCast (valueAddr, intType->getPointerTo ()));
894+ // Zero the remainder of the payload.
895+ auto zeroAddr = Builder.CreateConstByteArrayGEP (valueAddr, limit);
896+ auto zeroSize = Builder.CreateSub (
897+ size, llvm::ConstantInt::get (size->getType (), limit.getValue ()));
898+ Builder.CreateMemSet (zeroAddr, Builder.getInt8 (0 ), zeroSize);
899+ }
875900 }
876901 // Write to the extra tag bytes, if any.
877902 emitSetTag (IGF, extraTagBitsAddr, extraTagIndex, numExtraTagBytes);
0 commit comments