diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1113,6 +1113,13 @@ /// Determine whether the GEP has the inbounds flag. bool isInBounds() const; + /// Set the inrange index of this GEP instruction. + /// See LangRef.html for the meaning of inrange on a getelementptr. + void setInRangeIndex(unsigned InRangeIndex); + + /// Determine whether the GEP has an inrange index. + Optional getInRangeIndex() const; + /// Accumulate the constant address offset of this GEP if possible. /// /// This routine accepts an APInt into which it will accumulate the constant diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h --- a/llvm/include/llvm/IR/Operator.h +++ b/llvm/include/llvm/IR/Operator.h @@ -469,6 +469,12 @@ (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); } + void setInRangeIndex(unsigned InRangeIndex) { + assert(InRangeIndex < 63 && "unsupported"); + assert(!getInRangeIndex() && "trying to set multiple inrange indices"); + SubclassOptionalData |= InRangeIndex << 1; + } + public: /// Test whether this is an inbounds GEP, as defined by LangRef.html. bool isInBounds() const { diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -7643,7 +7643,7 @@ } /// parseGetElementPtr -/// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* +/// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' 'inrange'? TypeAndValue)* int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Value *Ptr = nullptr; Value *Val = nullptr; @@ -7675,11 +7675,14 @@ ? cast(BaseType)->getElementCount() : ElementCount::getFixed(0); + Optional InRangeIndex; while (EatIfPresent(lltok::comma)) { if (Lex.getKind() == lltok::MetadataVar) { AteExtraComma = true; break; } + if (EatIfPresent(lltok::kw_inrange) && !InRangeIndex) + InRangeIndex = Indices.size(); if (parseTypeAndValue(Val, EltLoc, PFS)) return true; if (!Val->getType()->isIntOrIntVectorTy()) @@ -7705,6 +7708,8 @@ Inst = GetElementPtrInst::Create(Ty, Ptr, Indices); if (InBounds) cast(Inst)->setIsInBounds(true); + if (InRangeIndex && *InRangeIndex < 63) + cast(Inst)->setInRangeIndex(*InRangeIndex); return AteExtraComma ? InstExtraComma : InstNormal; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1787,6 +1787,14 @@ return cast(this)->isInBounds(); } +void GetElementPtrInst::setInRangeIndex(unsigned InRangeIndex) { + cast(this)->setInRangeIndex(InRangeIndex); +} + +Optional GetElementPtrInst::getInRangeIndex() const { + return cast(this)->getInRangeIndex(); +} + bool GetElementPtrInst::accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { // Delegate to the generic GEPOperator implementation.