Skip to content

Commit d896232

Browse files
committed
Avoid assertion failure when serialising constant integer values.
We used a loop to get the individual bytes of a constant value and serialise them. This would crash if we ask for 8-bits from the value, but there are fewer than 8 bits to fetch. E.g. for a i1, you can never fetch a whole byte's worth of bits. This change ensures we fetch the right number of bits (i.e. fewer than 8 if there are fewer than 8 left).
1 parent 7c45e9d commit d896232

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

llvm/lib/YkIR/YkIRWriter.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,10 +768,26 @@ class YkIRWriter {
768768

769769
void serialiseConstantInt(ConstantInt *CI) {
770770
OutStreamer.emitSizeT(typeIndex(CI->getType()));
771-
OutStreamer.emitSizeT(CI->getBitWidth() / 8);
772-
for (size_t I = 0; I < CI->getBitWidth(); I += 8) {
773-
uint64_t Byte = CI->getValue().extractBitsAsZExtValue(8, I);
771+
unsigned BitWidth = CI->getBitWidth();
772+
773+
// Figure out how many bytes it'd take to store that many bits.
774+
unsigned ByteWidth = BitWidth / 8;
775+
if (BitWidth % 8 != 0) {
776+
ByteWidth++;
777+
}
778+
OutStreamer.emitSizeT(ByteWidth);
779+
780+
unsigned BitsRemain = BitWidth;
781+
while (BitsRemain > 0) {
782+
// We have to be careful not to ask extractBitsAsZExtValue() for more
783+
// bits than there are left, or an internal assertion will fail.
784+
unsigned NumBitsThisIter = std::min({BitsRemain, unsigned(8)});
785+
uint64_t Byte = CI->getValue().extractBitsAsZExtValue(
786+
NumBitsThisIter, BitWidth - BitsRemain);
787+
// This could be optimised by writing larger chunks thank a byte, but
788+
// beware endianess!
774789
OutStreamer.emitInt8(Byte);
790+
BitsRemain -= NumBitsThisIter;
775791
}
776792
}
777793

0 commit comments

Comments
 (0)