diff options
author | David Blaikie <dblaikie@gmail.com> | 2015-03-13 21:03:36 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2015-03-13 21:03:36 +0000 |
commit | b9263570a59371126d3492f68853029a3f801fce (patch) | |
tree | 6f39477633795becc291be6ff616e552cbc67b65 /llvm/lib/Bitcode | |
parent | 4a5c8c602c68e727a0d560d68d6bf9463b2d3cc2 (diff) | |
download | bcm5719-llvm-b9263570a59371126d3492f68853029a3f801fce.tar.gz bcm5719-llvm-b9263570a59371126d3492f68853029a3f801fce.zip |
[opaque pointer type] Bitcode support for explicit type parameter on the gep operator
This happened to be fairly easy to support backwards compatibility based
on the number of operands (old format had an even number, new format has
one more operand so an odd number).
test/Bitcode/old-aliases.ll already appears to test old gep operators
(if I remove the backwards compatibility in the BitcodeReader, this and
another test fail) so I'm not adding extra test coverage here.
llvm-svn: 232216
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 7 |
2 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 33b02f912f0..9a0ec19e6f3 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1955,19 +1955,25 @@ std::error_code BitcodeReader::ParseConstants() { } case bitc::CST_CODE_CE_INBOUNDS_GEP: case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands] - if (Record.size() & 1) - return Error("Invalid record"); + unsigned OpNum = 0; + Type *PointeeType = nullptr; + if (Record.size() % 2) + PointeeType = getTypeByID(Record[OpNum++]); SmallVector<Constant*, 16> Elts; - for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - Type *ElTy = getTypeByID(Record[i]); + while (OpNum != Record.size()) { + Type *ElTy = getTypeByID(Record[OpNum++]); if (!ElTy) return Error("Invalid record"); - Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy)); + Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } + ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); V = ConstantExpr::getGetElementPtr(Elts[0], Indices, BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP); + if (PointeeType && + PointeeType != cast<GEPOperator>(V)->getSourceElementType()) + return Error("Invalid record"); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index ecb6f7c130a..d2417acc689 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1522,15 +1522,18 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, Record.push_back(Flags); } break; - case Instruction::GetElementPtr: + case Instruction::GetElementPtr: { Code = bitc::CST_CODE_CE_GEP; - if (cast<GEPOperator>(C)->isInBounds()) + const auto *GO = cast<GEPOperator>(C); + if (GO->isInBounds()) Code = bitc::CST_CODE_CE_INBOUNDS_GEP; + Record.push_back(VE.getTypeID(GO->getSourceElementType())); for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { Record.push_back(VE.getTypeID(C->getOperand(i)->getType())); Record.push_back(VE.getValueID(C->getOperand(i))); } break; + } case Instruction::Select: Code = bitc::CST_CODE_CE_SELECT; Record.push_back(VE.getValueID(C->getOperand(0))); |