IR: Introduce inrange attribute on getelementptr indices.
If the inrange keyword is present before any index, loading from or storing to any pointer derived from the getelementptr has undefined behavior if the load or store would access memory outside of the bounds of the element selected by the index marked as inrange. This can be used, e.g. for alias analysis or to split globals at element boundaries where beneficial. As previously proposed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-July/102472.html Differential Revision: https://reviews.llvm.org/D22793 llvm-svn: 286514
This commit is contained in:
@@ -3268,12 +3268,25 @@ Error BitcodeReader::parseConstants() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_CE_INBOUNDS_GEP:
|
||||
case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands]
|
||||
case bitc::CST_CODE_CE_INBOUNDS_GEP: // [ty, n x operands]
|
||||
case bitc::CST_CODE_CE_GEP: // [ty, n x operands]
|
||||
case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX: { // [ty, flags, n x
|
||||
// operands]
|
||||
unsigned OpNum = 0;
|
||||
Type *PointeeType = nullptr;
|
||||
if (Record.size() % 2)
|
||||
if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX ||
|
||||
Record.size() % 2)
|
||||
PointeeType = getTypeByID(Record[OpNum++]);
|
||||
|
||||
bool InBounds = false;
|
||||
Optional<unsigned> InRangeIndex;
|
||||
if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX) {
|
||||
uint64_t Op = Record[OpNum++];
|
||||
InBounds = Op & 1;
|
||||
InRangeIndex = Op >> 1;
|
||||
} else if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
|
||||
InBounds = true;
|
||||
|
||||
SmallVector<Constant*, 16> Elts;
|
||||
while (OpNum != Record.size()) {
|
||||
Type *ElTy = getTypeByID(Record[OpNum++]);
|
||||
@@ -3294,8 +3307,7 @@ Error BitcodeReader::parseConstants() {
|
||||
|
||||
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
|
||||
V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
|
||||
BitCode ==
|
||||
bitc::CST_CODE_CE_INBOUNDS_GEP);
|
||||
InBounds, InRangeIndex);
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#]
|
||||
|
||||
Reference in New Issue
Block a user