Bitcode: Fix reading and writing of ConstantDataVectors of halfs

In r254991 I allowed ConstantDataVectors to contain elements of
HalfTy, but I missed updating the bitcode reader and writer to handle
this, so now we crash if we try to emit bitcode on programs that have
constant vectors of half.

This fixes the issue and adds test coverage for reading and writing
constant sequences in bitcode.

llvm-svn: 256982
This commit is contained in:
Justin Bogner 2016-01-06 22:31:32 +00:00
parent 58a636ac06
commit a43eacbf9e
3 changed files with 47 additions and 23 deletions

View File

@ -2654,8 +2654,6 @@ std::error_code BitcodeReader::parseConstants() {
return error("Invalid record");
Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
unsigned Size = Record.size();
if (EltTy->isIntegerTy(8)) {
SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
if (isa<VectorType>(CurTy))
@ -2680,21 +2678,24 @@ std::error_code BitcodeReader::parseConstants() {
V = ConstantDataVector::get(Context, Elts);
else
V = ConstantDataArray::get(Context, Elts);
} else if (EltTy->isHalfTy()) {
SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end());
if (isa<VectorType>(CurTy))
V = ConstantDataVector::getFP(Context, Elts);
else
V = ConstantDataArray::getFP(Context, Elts);
} else if (EltTy->isFloatTy()) {
SmallVector<float, 16> Elts(Size);
std::transform(Record.begin(), Record.end(), Elts.begin(), BitsToFloat);
SmallVector<uint32_t, 16> Elts(Record.begin(), Record.end());
if (isa<VectorType>(CurTy))
V = ConstantDataVector::get(Context, Elts);
V = ConstantDataVector::getFP(Context, Elts);
else
V = ConstantDataArray::get(Context, Elts);
V = ConstantDataArray::getFP(Context, Elts);
} else if (EltTy->isDoubleTy()) {
SmallVector<double, 16> Elts(Size);
std::transform(Record.begin(), Record.end(), Elts.begin(),
BitsToDouble);
SmallVector<uint64_t, 16> Elts(Record.begin(), Record.end());
if (isa<VectorType>(CurTy))
V = ConstantDataVector::get(Context, Elts);
V = ConstantDataVector::getFP(Context, Elts);
else
V = ConstantDataArray::get(Context, Elts);
V = ConstantDataArray::getFP(Context, Elts);
} else {
return error("Invalid type for value");
}

View File

@ -1630,19 +1630,10 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
if (isa<IntegerType>(EltTy)) {
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
Record.push_back(CDS->getElementAsInteger(i));
} else if (EltTy->isFloatTy()) {
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
union { float F; uint32_t I; };
F = CDS->getElementAsFloat(i);
Record.push_back(I);
}
} else {
assert(EltTy->isDoubleTy() && "Unknown ConstantData element type");
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
union { double F; uint64_t I; };
F = CDS->getElementAsDouble(i);
Record.push_back(I);
}
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
Record.push_back(
CDS->getElementAsAPFloat(i).bitcastToAPInt().getLimitedValue());
}
} else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
isa<ConstantVector>(C)) {

View File

@ -0,0 +1,32 @@
; Round trip constant sequences through bitcode
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; CHECK: @array.i8 = constant [3 x i8] c"\00\01\00"
@array.i8 = constant [3 x i8] [i8 -0, i8 1, i8 0]
; CHECK: @array.i16 = constant [3 x i16] [i16 0, i16 1, i16 0]
@array.i16 = constant [3 x i16] [i16 -0, i16 1, i16 0]
; CHECK: @array.i32 = constant [3 x i32] [i32 0, i32 1, i32 0]
@array.i32 = constant [3 x i32] [i32 -0, i32 1, i32 0]
; CHECK: @array.i64 = constant [3 x i64] [i64 0, i64 1, i64 0]
@array.i64 = constant [3 x i64] [i64 -0, i64 1, i64 0]
; CHECK: @array.f16 = constant [3 x half] [half 0xH8000, half 0xH3C00, half 0xH0000]
@array.f16 = constant [3 x half] [half -0.0, half 1.0, half 0.0]
; CHECK: @array.f32 = constant [3 x float] [float -0.000000e+00, float 1.000000e+00, float 0.000000e+00]
@array.f32 = constant [3 x float] [float -0.0, float 1.0, float 0.0]
; CHECK: @array.f64 = constant [3 x double] [double -0.000000e+00, double 1.000000e+00, double 0.000000e+00]
@array.f64 = constant [3 x double] [double -0.0, double 1.0, double 0.0]
; CHECK: @vector.i8 = constant <3 x i8> <i8 0, i8 1, i8 0>
@vector.i8 = constant <3 x i8> <i8 -0, i8 1, i8 0>
; CHECK: @vector.i16 = constant <3 x i16> <i16 0, i16 1, i16 0>
@vector.i16 = constant <3 x i16> <i16 -0, i16 1, i16 0>
; CHECK: @vector.i32 = constant <3 x i32> <i32 0, i32 1, i32 0>
@vector.i32 = constant <3 x i32> <i32 -0, i32 1, i32 0>
; CHECK: @vector.i64 = constant <3 x i64> <i64 0, i64 1, i64 0>
@vector.i64 = constant <3 x i64> <i64 -0, i64 1, i64 0>
; CHECK: @vector.f16 = constant <3 x half> <half 0xH8000, half 0xH3C00, half 0xH0000>
@vector.f16 = constant <3 x half> <half -0.0, half 1.0, half 0.0>
; CHECK: @vector.f32 = constant <3 x float> <float -0.000000e+00, float 1.000000e+00, float 0.000000e+00>
@vector.f32 = constant <3 x float> <float -0.0, float 1.0, float 0.0>
; CHECK: @vector.f64 = constant <3 x double> <double -0.000000e+00, double 1.000000e+00, double 0.000000e+00>
@vector.f64 = constant <3 x double> <double -0.0, double 1.0, double 0.0>