Bitcode: Fix reading and writing of ConstantDataVectors of halfs
authorJustin Bogner <mail@justinbogner.com>
Wed, 6 Jan 2016 22:31:32 +0000 (22:31 +0000)
committerJustin Bogner <mail@justinbogner.com>
Wed, 6 Jan 2016 22:31:32 +0000 (22:31 +0000)
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
lib/Bitcode/Writer/BitcodeWriter.cpp
test/Bitcode/constant-sequence.ll [new file with mode: 0644]

index c7606fd488a0a7446ecb87e383aa5f7da37a5ed7..2ad4b32e3157516dc497b594734d81aa1a81085a 100644 (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");
       }
index a1f87863757bb777b2e516f4e33a3b5292e83dcf..a899a0cc3ee450c22dc99dc7a513953f81360de5 100644 (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)) {
diff --git a/test/Bitcode/constant-sequence.ll b/test/Bitcode/constant-sequence.ll
new file mode 100644 (file)
index 0000000..51e3b00
--- /dev/null
@@ -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>