diff options
| author | Nikita Popov <npopov@redhat.com> | 2024-05-27 16:05:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-27 16:05:17 +0200 |
| commit | 8cdecd4d3aedea7bc5f27d1f69da216100cb2815 (patch) | |
| tree | fb5b5a1d15766c4187abfabc4a6248c18bf7f1a3 /llvm/lib/AsmParser | |
| parent | 49b760ff2c7da60f4308708f56688ca99874605f (diff) | |
[IR] Add getelementptr nusw and nuw flags (#90824)
This implements the `nusw` and `nuw` flags for `getelementptr` as
proposed at
https://discourse.llvm.org/t/rfc-add-nusw-and-nuw-flags-for-getelementptr/78672.
The three possible flags are encapsulated in the new `GEPNoWrapFlags`
class. Currently this class has a ctor from bool, interpreted as the
InBounds flag. This ctor should be removed in the future, as code gets
migrated to handle all flags.
There are a few places annotated with `TODO(gep_nowrap)`, where I've had
to touch code but opted to not infer or precisely preserve the new
flags, so as to keep this as NFC as possible and make sure any changes
of that kind get test coverage when they are made.
Diffstat (limited to 'llvm/lib/AsmParser')
| -rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 36 |
2 files changed, 29 insertions, 8 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 8ded07ffd8bd..20a1bd295771 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -566,6 +566,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(fast); KEYWORD(nuw); KEYWORD(nsw); + KEYWORD(nusw); KEYWORD(exact); KEYWORD(disjoint); KEYWORD(inbounds); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 2902bd9fe17c..5d2056d20856 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4216,7 +4216,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { case lltok::kw_extractelement: { unsigned Opc = Lex.getUIntVal(); SmallVector<Constant*, 16> Elts; - bool InBounds = false; + GEPNoWrapFlags NW; bool HasInRange = false; APSInt InRangeStart; APSInt InRangeEnd; @@ -4224,7 +4224,17 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { Lex.Lex(); if (Opc == Instruction::GetElementPtr) { - InBounds = EatIfPresent(lltok::kw_inbounds); + while (true) { + if (EatIfPresent(lltok::kw_inbounds)) + NW |= GEPNoWrapFlags::inBounds(); + else if (EatIfPresent(lltok::kw_nusw)) + NW |= GEPNoWrapFlags::noUnsignedSignedWrap(); + else if (EatIfPresent(lltok::kw_nuw)) + NW |= GEPNoWrapFlags::noUnsignedWrap(); + else + break; + } + if (EatIfPresent(lltok::kw_inrange)) { if (parseToken(lltok::lparen, "expected '('")) return true; @@ -4303,8 +4313,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return error(ID.Loc, "invalid getelementptr indices"); - ID.ConstantVal = ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, - InBounds, InRange); + ID.ConstantVal = + ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, NW, InRange); } else if (Opc == Instruction::ShuffleVector) { if (Elts.size() != 3) return error(ID.Loc, "expected three operands to shufflevector"); @@ -8339,8 +8349,18 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Value *Ptr = nullptr; Value *Val = nullptr; LocTy Loc, EltLoc; + GEPNoWrapFlags NW; - bool InBounds = EatIfPresent(lltok::kw_inbounds); + while (true) { + if (EatIfPresent(lltok::kw_inbounds)) + NW |= GEPNoWrapFlags::inBounds(); + else if (EatIfPresent(lltok::kw_nusw)) + NW |= GEPNoWrapFlags::noUnsignedSignedWrap(); + else if (EatIfPresent(lltok::kw_nuw)) + NW |= GEPNoWrapFlags::noUnsignedWrap(); + else + break; + } Type *Ty = nullptr; if (parseType(Ty) || @@ -8393,9 +8413,9 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return error(Loc, "invalid getelementptr indices"); - Inst = GetElementPtrInst::Create(Ty, Ptr, Indices); - if (InBounds) - cast<GetElementPtrInst>(Inst)->setIsInBounds(true); + GetElementPtrInst *GEP = GetElementPtrInst::Create(Ty, Ptr, Indices); + Inst = GEP; + GEP->setNoWrapFlags(NW); return AteExtraComma ? InstExtraComma : InstNormal; } |
