From a43eacbf9ec8027b18ffef1b768f8303e4ffc7cf Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Wed, 6 Jan 2016 22:31:32 +0000 Subject: [PATCH] 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 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 23 ++++++++-------- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 15 +++-------- llvm/test/Bitcode/constant-sequence.ll | 32 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 llvm/test/Bitcode/constant-sequence.ll diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index c7606fd488a0..2ad4b32e3157 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2654,8 +2654,6 @@ std::error_code BitcodeReader::parseConstants() { return error("Invalid record"); Type *EltTy = cast(CurTy)->getElementType(); - unsigned Size = Record.size(); - if (EltTy->isIntegerTy(8)) { SmallVector Elts(Record.begin(), Record.end()); if (isa(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 Elts(Record.begin(), Record.end()); + if (isa(CurTy)) + V = ConstantDataVector::getFP(Context, Elts); + else + V = ConstantDataArray::getFP(Context, Elts); } else if (EltTy->isFloatTy()) { - SmallVector Elts(Size); - std::transform(Record.begin(), Record.end(), Elts.begin(), BitsToFloat); + SmallVector Elts(Record.begin(), Record.end()); if (isa(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 Elts(Size); - std::transform(Record.begin(), Record.end(), Elts.begin(), - BitsToDouble); + SmallVector Elts(Record.begin(), Record.end()); if (isa(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"); } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index a1f87863757b..a899a0cc3ee4 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1630,19 +1630,10 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, if (isa(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(C) || isa(C) || isa(C)) { diff --git a/llvm/test/Bitcode/constant-sequence.ll b/llvm/test/Bitcode/constant-sequence.ll new file mode 100644 index 000000000000..51e3b0051e05 --- /dev/null +++ b/llvm/test/Bitcode/constant-sequence.ll @@ -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> +@vector.i8 = constant <3 x i8> +; CHECK: @vector.i16 = constant <3 x i16> +@vector.i16 = constant <3 x i16> +; CHECK: @vector.i32 = constant <3 x i32> +@vector.i32 = constant <3 x i32> +; CHECK: @vector.i64 = constant <3 x i64> +@vector.i64 = constant <3 x i64> +; CHECK: @vector.f16 = constant <3 x half> +@vector.f16 = constant <3 x half> +; CHECK: @vector.f32 = constant <3 x float> +@vector.f32 = constant <3 x float> +; CHECK: @vector.f64 = constant <3 x double> +@vector.f64 = constant <3 x double>