@@ -687,15 +687,26 @@ llvm::Value *irgen::getFixedTypeEnumTagSinglePayload(
687
687
688
688
llvm::Value *caseIndexFromValue = zero;
689
689
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
+ }
699
710
}
700
711
701
712
auto *result1 = Builder.CreateAdd (
@@ -867,11 +878,25 @@ void irgen::storeFixedTypeEnumTagSinglePayload(
867
878
payloadIndex->addIncoming (payloadIndex0, payloadLT4BB);
868
879
869
880
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
+ }
875
900
}
876
901
// Write to the extra tag bytes, if any.
877
902
emitSetTag (IGF, extraTagBitsAddr, extraTagIndex, numExtraTagBytes);
0 commit comments