Patch provide by Tom Roeder!
authorJoe Abbey <jabbey@arxan.com>
Thu, 12 Sep 2013 22:02:31 +0000 (22:02 +0000)
committerJoe Abbey <jabbey@arxan.com>
Thu, 12 Sep 2013 22:02:31 +0000 (22:02 +0000)
Reviewed by Joe Abbey and Tobias Grosser

Here is a patch that fixes decoding of CE_SELECT in BitcodeReader,
along with a simple test case. The problem in the current code is that
it generates but doesn't accept bitcode that uses vectors for the
first element of a select in this context.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190634 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bitcode/Reader/BitcodeReader.cpp
test/Bitcode/select.ll [new file with mode: 0644]

index 3ac6e038fda865c406889f019d791d375e2fab39..ca432fd5903518bd6c5153dbf8db4badc1d8f46e 100644 (file)
@@ -1387,14 +1387,23 @@ bool BitcodeReader::ParseConstants() {
                                            bitc::CST_CODE_CE_INBOUNDS_GEP);
       break;
     }
-    case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
+    case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
       if (Record.size() < 3) return Error("Invalid CE_SELECT record");
-      V = ConstantExpr::getSelect(
-                          ValueList.getConstantFwdRef(Record[0],
-                                                      Type::getInt1Ty(Context)),
-                          ValueList.getConstantFwdRef(Record[1],CurTy),
-                          ValueList.getConstantFwdRef(Record[2],CurTy));
+
+      Type *SelectorTy = Type::getInt1Ty(Context);
+
+      // If CurTy is a vector of length n, then Record[0] must be a <n x i1>
+      // vector. Otherwise, it must be a single bit.
+      if (VectorType *VTy = dyn_cast<VectorType>(CurTy))
+        SelectorTy = VectorType::get(Type::getInt1Ty(Context),
+                                     VTy->getNumElements());
+
+      V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0],
+                                                              SelectorTy),
+                                  ValueList.getConstantFwdRef(Record[1],CurTy),
+                                  ValueList.getConstantFwdRef(Record[2],CurTy));
       break;
+    }
     case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval]
       if (Record.size() < 3) return Error("Invalid CE_EXTRACTELT record");
       VectorType *OpTy =
diff --git a/test/Bitcode/select.ll b/test/Bitcode/select.ll
new file mode 100644 (file)
index 0000000..71e669a
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+define <2 x i32> @main() {
+  ret <2 x i32> select (<2 x i1> <i1 false, i1 undef>, <2 x i32> zeroinitializer, <2 x i32> <i32 0, i32 undef>)
+}
+
+; CHECK: define <2 x i32> @main() {
+; CHECK:   ret <2 x i32> select (<2 x i1> <i1 false, i1 undef>, <2 x i32> zeroinitializer, <2 x i32> <i32 0, i32 undef>)
+; CHECK: }