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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286514 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Peter Collingbourne
2016-11-10 22:34:55 +00:00
parent d31cbc45ab
commit ca668e1942
18 changed files with 218 additions and 64 deletions

View File

@@ -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#]