From 4b0bd158058240d73a4848891746e0d5954bbeb3 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256982 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 23 ++++++++++---------- lib/Bitcode/Writer/BitcodeWriter.cpp | 15 +++---------- test/Bitcode/constant-sequence.ll | 32 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 test/Bitcode/constant-sequence.ll diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index c7606fd488a..2ad4b32e315 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/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/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index a1f87863757..a899a0cc3ee 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/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/test/Bitcode/constant-sequence.ll b/test/Bitcode/constant-sequence.ll new file mode 100644 index 00000000000..51e3b0051e0 --- /dev/null +++ b/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> -- 2.34.1