diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 17 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 6 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 3 |
6 files changed, 30 insertions, 2 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index e047002c13..c9b2821243 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -504,6 +504,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(nuw); KEYWORD(nsw); KEYWORD(exact); + KEYWORD(inbounds); KEYWORD(align); KEYWORD(addrspace); KEYWORD(section); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index f9db40915a..adcd79f40a 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -457,7 +457,7 @@ bool LLParser::ParseStandaloneMetadata() { /// Aliasee /// ::= TypeAndValue /// ::= 'bitcast' '(' TypeAndValue 'to' Type ')' -/// ::= 'getelementptr' '(' ... ')' +/// ::= 'getelementptr' 'inbounds'? '(' ... ')' /// /// Everything through visibility has already been parsed. /// @@ -2039,7 +2039,11 @@ bool LLParser::ParseValID(ValID &ID) { case lltok::kw_select: { unsigned Opc = Lex.getUIntVal(); SmallVector<Constant*, 16> Elts; + bool InBounds = false; Lex.Lex(); + if (Opc == Instruction::GetElementPtr) + if (EatIfPresent(lltok::kw_inbounds)) + InBounds = true; if (ParseToken(lltok::lparen, "expected '(' in constantexpr") || ParseGlobalValueVector(Elts) || ParseToken(lltok::rparen, "expected ')' in constantexpr")) @@ -2055,6 +2059,8 @@ bool LLParser::ParseValID(ValID &ID) { return Error(ID.Loc, "invalid indices for getelementptr"); ID.ConstantVal = Context.getConstantExprGetElementPtr(Elts[0], Elts.data() + 1, Elts.size() - 1); + if (InBounds) + cast<GEPOperator>(ID.ConstantVal)->setIsInBounds(true); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); @@ -3368,9 +3374,14 @@ bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) { } /// ParseGetElementPtr -/// ::= 'getelementptr' TypeAndValue (',' TypeAndValue)* +/// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Value *Ptr, *Val; LocTy Loc, EltLoc; + bool InBounds = false; + + if (EatIfPresent(lltok::kw_inbounds)) + InBounds = true; + if (ParseTypeAndValue(Ptr, Loc, PFS)) return true; if (!isa<PointerType>(Ptr->getType())) @@ -3388,6 +3399,8 @@ bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.begin(), Indices.end())) return Error(Loc, "invalid getelementptr indices"); Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end()); + if (InBounds) + cast<GEPOperator>(Inst)->setIsInBounds(true); return false; } diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index c8cdff6bf6..75cc1db8ad 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -54,6 +54,7 @@ namespace lltok { kw_nuw, kw_nsw, kw_exact, + kw_inbounds, kw_align, kw_addrspace, kw_section, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 687cae9ecf..e1cc1a3afb 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -997,6 +997,7 @@ bool BitcodeReader::ParseConstants() { } break; } + 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 CE_GEP record"); SmallVector<Constant*, 16> Elts; @@ -1007,6 +1008,8 @@ bool BitcodeReader::ParseConstants() { } V = Context.getConstantExprGetElementPtr(Elts[0], &Elts[1], Elts.size()-1); + if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP) + cast<GEPOperator>(V)->setIsInBounds(true); break; } case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#] @@ -1556,6 +1559,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy); break; } + case bitc::FUNC_CODE_INST_INBOUNDS_GEP: case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands] unsigned OpNum = 0; Value *BasePtr; @@ -1571,6 +1575,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end()); + if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP) + cast<GEPOperator>(I)->setIsInBounds(true); break; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index b312420490..fd09edec94 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -706,6 +706,8 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, break; case Instruction::GetElementPtr: Code = bitc::CST_CODE_CE_GEP; + if (cast<GEPOperator>(C)->isInBounds()) + Code = bitc::CST_CODE_CE_INBOUNDS_GEP; 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))); @@ -829,6 +831,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::GetElementPtr: Code = bitc::FUNC_CODE_INST_GEP; + if (cast<GEPOperator>(&I)->isInBounds()) + Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP; for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) PushValueAndType(I.getOperand(i), InstID, Vals, VE); break; diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 11d238eba2..8242d8155b 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -854,6 +854,9 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) { if (Div->isExact()) Out << " exact"; + } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { + if (GEP->isInBounds()) + Out << " inbounds"; } } |