summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2015-03-13 21:03:36 +0000
committerDavid Blaikie <dblaikie@gmail.com>2015-03-13 21:03:36 +0000
commitb9263570a59371126d3492f68853029a3f801fce (patch)
tree6f39477633795becc291be6ff616e552cbc67b65
parent4a5c8c602c68e727a0d560d68d6bf9463b2d3cc2 (diff)
downloadbcm5719-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
-rw-r--r--llvm/include/llvm/IR/Operator.h5
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp16
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp7
3 files changed, 21 insertions, 7 deletions
diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h
index 46935ce3e96..c87f89c6157 100644
--- a/llvm/include/llvm/IR/Operator.h
+++ b/llvm/include/llvm/IR/Operator.h
@@ -400,6 +400,11 @@ public:
return getPointerOperand()->getType();
}
+ Type *getSourceElementType() const {
+ return cast<SequentialType>(getPointerOperandType()->getScalarType())
+ ->getElementType();
+ }
+
/// Method to return the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
return getPointerOperandType()->getPointerAddressSpace();
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)));
OpenPOWER on IntegriCloud