summaryrefslogtreecommitdiff
path: root/lib/AsmParser
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-11-10 22:34:55 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-11-10 22:34:55 +0000
commitca668e19426e7188ab31d54b53bf33185b65eadd (patch)
treeca8098fa7f475387bdf351f75598f31acfc9c779 /lib/AsmParser
parentd31cbc45ab39e746ef8d85281ad8debab7ba893f (diff)
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
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp31
-rw-r--r--lib/AsmParser/LLParser.h3
-rw-r--r--lib/AsmParser/LLToken.h1
4 files changed, 25 insertions, 11 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 2dc1c0a1487..2ead37198b1 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -551,6 +551,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(nsw);
KEYWORD(exact);
KEYWORD(inbounds);
+ KEYWORD(inrange);
KEYWORD(align);
KEYWORD(addrspace);
KEYWORD(section);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 2b8d2f81011..d73818d2b86 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -3175,7 +3175,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
}
- if (ParseGlobalValueVector(Elts) ||
+ Optional<unsigned> InRangeOp;
+ if (ParseGlobalValueVector(
+ Elts, Opc == Instruction::GetElementPtr ? &InRangeOp : nullptr) ||
ParseToken(lltok::rparen, "expected ')' in constantexpr"))
return true;
@@ -3214,8 +3216,16 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (!GetElementPtrInst::getIndexedType(Ty, Indices))
return Error(ID.Loc, "invalid getelementptr indices");
- ID.ConstantVal =
- ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, InBounds);
+
+ if (InRangeOp) {
+ if (*InRangeOp == 0)
+ return Error(ID.Loc,
+ "inrange keyword may not appear on pointer operand");
+ --*InRangeOp;
+ }
+
+ ID.ConstantVal = ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices,
+ InBounds, InRangeOp);
} else if (Opc == Instruction::Select) {
if (Elts.size() != 3)
return Error(ID.Loc, "expected three operands to select");
@@ -3298,8 +3308,9 @@ bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
/// ParseGlobalValueVector
/// ::= /*empty*/
-/// ::= TypeAndValue (',' TypeAndValue)*
-bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) {
+/// ::= [inrange] TypeAndValue (',' [inrange] TypeAndValue)*
+bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
+ Optional<unsigned> *InRangeOp) {
// Empty list.
if (Lex.getKind() == lltok::rbrace ||
Lex.getKind() == lltok::rsquare ||
@@ -3307,14 +3318,14 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) {
Lex.getKind() == lltok::rparen)
return false;
- Constant *C;
- if (ParseGlobalTypeAndValue(C)) return true;
- Elts.push_back(C);
+ do {
+ if (InRangeOp && !*InRangeOp && EatIfPresent(lltok::kw_inrange))
+ *InRangeOp = Elts.size();
- while (EatIfPresent(lltok::comma)) {
+ Constant *C;
if (ParseGlobalTypeAndValue(C)) return true;
Elts.push_back(C);
- }
+ } while (EatIfPresent(lltok::comma));
return false;
}
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 479ff96bc8a..16d4e8b5baa 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -411,7 +411,8 @@ namespace llvm {
bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr);
bool ParseGlobalValue(Type *Ty, Constant *&V);
bool ParseGlobalTypeAndValue(Constant *&V);
- bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts);
+ bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
+ Optional<unsigned> *InRangeOp = nullptr);
bool parseOptionalComdat(StringRef GlobalName, Comdat *&C);
bool ParseMetadataAsValue(Value *&V, PerFunctionState &PFS);
bool ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 555aee3ef04..a1695258bbe 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -103,6 +103,7 @@ enum Kind {
kw_nsw,
kw_exact,
kw_inbounds,
+ kw_inrange,
kw_align,
kw_addrspace,
kw_section,