aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp243
1 files changed, 138 insertions, 105 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 7f451620a08e..5f0d1a76de79 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -150,7 +150,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
// If the alignment was parsed as an attribute, move to the alignment
// field.
if (MaybeAlign A = FnAttrs.getAlignment()) {
- Fn->setAlignment(A);
+ Fn->setAlignment(*A);
FnAttrs.removeAttribute(Attribute::Alignment);
}
@@ -974,14 +974,6 @@ static void maybeSetDSOLocal(bool DSOLocal, GlobalValue &GV) {
GV.setDSOLocal(true);
}
-static std::string typeComparisonErrorMessage(StringRef Message, Type *Ty1,
- Type *Ty2) {
- std::string ErrString;
- raw_string_ostream ErrOS(ErrString);
- ErrOS << Message << " (" << *Ty1 << " vs " << *Ty2 << ")";
- return ErrOS.str();
-}
-
/// parseAliasOrIFunc:
/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
/// OptionalVisibility OptionalDLLStorageClass
@@ -1053,20 +1045,6 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, LocTy NameLoc,
return error(AliaseeLoc, "An alias or ifunc must have pointer type");
unsigned AddrSpace = PTy->getAddressSpace();
- if (IsAlias) {
- if (!PTy->isOpaqueOrPointeeTypeMatches(Ty))
- return error(
- ExplicitTypeLoc,
- typeComparisonErrorMessage(
- "explicit pointee type doesn't match operand's pointee type", Ty,
- PTy->getNonOpaquePointerElementType()));
- } else {
- if (!PTy->isOpaque() &&
- !PTy->getNonOpaquePointerElementType()->isFunctionTy())
- return error(ExplicitTypeLoc,
- "explicit pointee type should be a function type");
- }
-
GlobalValue *GVal = nullptr;
// See if the alias was forward referenced, if so, prepare to replace the
@@ -1141,9 +1119,9 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, LocTy NameLoc,
// Insert into the module, we know its name won't collide now.
if (IsAlias)
- M->getAliasList().push_back(GA.release());
+ M->insertAlias(GA.release());
else
- M->getIFuncList().push_back(GI.release());
+ M->insertIFunc(GI.release());
assert(GV->getName() == Name && "Should not be a name conflict!");
return false;
@@ -1279,7 +1257,7 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
GV->setUnnamedAddr(UnnamedAddr);
if (GVal) {
- if (GVal->getType() != Ty->getPointerTo(AddrSpace))
+ if (GVal->getAddressSpace() != AddrSpace)
return error(
TyLoc,
"forward reference and definition of global have different types");
@@ -1306,7 +1284,8 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
MaybeAlign Alignment;
if (parseOptionalAlignment(Alignment))
return true;
- GV->setAlignment(Alignment);
+ if (Alignment)
+ GV->setAlignment(*Alignment);
} else if (Lex.getKind() == lltok::MetadataVar) {
if (parseGlobalObjectMetadataAttachment(*GV))
return true;
@@ -1468,6 +1447,15 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
B.addMemoryAttr(*ME);
return false;
}
+ case Attribute::NoFPClass: {
+ if (FPClassTest NoFPClass =
+ static_cast<FPClassTest>(parseNoFPClassAttr())) {
+ B.addNoFPClassAttr(NoFPClass);
+ return false;
+ }
+
+ return true;
+ }
default:
B.addAttribute(Attr);
Lex.Lex();
@@ -1573,22 +1561,12 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
//===----------------------------------------------------------------------===//
static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy) {
- // For opaque pointers, the used global type does not matter. We will later
- // RAUW it with a global/function of the correct type.
- if (PTy->isOpaque())
- return new GlobalVariable(*M, Type::getInt8Ty(M->getContext()), false,
- GlobalValue::ExternalWeakLinkage, nullptr, "",
- nullptr, GlobalVariable::NotThreadLocal,
- PTy->getAddressSpace());
-
- Type *ElemTy = PTy->getNonOpaquePointerElementType();
- if (auto *FT = dyn_cast<FunctionType>(ElemTy))
- return Function::Create(FT, GlobalValue::ExternalWeakLinkage,
- PTy->getAddressSpace(), "", M);
- else
- return new GlobalVariable(
- *M, ElemTy, false, GlobalValue::ExternalWeakLinkage, nullptr, "",
- nullptr, GlobalVariable::NotThreadLocal, PTy->getAddressSpace());
+ // The used global type does not matter. We will later RAUW it with a
+ // global/function of the correct type.
+ return new GlobalVariable(*M, Type::getInt8Ty(M->getContext()), false,
+ GlobalValue::ExternalWeakLinkage, nullptr, "",
+ nullptr, GlobalVariable::NotThreadLocal,
+ PTy->getAddressSpace());
}
Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
@@ -2017,6 +1995,8 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'amdgpu_gs'
/// ::= 'amdgpu_ps'
/// ::= 'amdgpu_cs'
+/// ::= 'amdgpu_cs_chain'
+/// ::= 'amdgpu_cs_chain_preserve'
/// ::= 'amdgpu_kernel'
/// ::= 'tailcc'
/// ::= 'cc' UINT
@@ -2064,8 +2044,12 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
case lltok::kw_swiftcc: CC = CallingConv::Swift; break;
case lltok::kw_swifttailcc: CC = CallingConv::SwiftTail; break;
case lltok::kw_x86_intrcc: CC = CallingConv::X86_INTR; break;
- case lltok::kw_hhvmcc: CC = CallingConv::HHVM; break;
- case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break;
+ case lltok::kw_hhvmcc:
+ CC = CallingConv::DUMMY_HHVM;
+ break;
+ case lltok::kw_hhvm_ccc:
+ CC = CallingConv::DUMMY_HHVM_C;
+ break;
case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break;
case lltok::kw_amdgpu_vs: CC = CallingConv::AMDGPU_VS; break;
case lltok::kw_amdgpu_gfx: CC = CallingConv::AMDGPU_Gfx; break;
@@ -2075,6 +2059,12 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
case lltok::kw_amdgpu_gs: CC = CallingConv::AMDGPU_GS; break;
case lltok::kw_amdgpu_ps: CC = CallingConv::AMDGPU_PS; break;
case lltok::kw_amdgpu_cs: CC = CallingConv::AMDGPU_CS; break;
+ case lltok::kw_amdgpu_cs_chain:
+ CC = CallingConv::AMDGPU_CS_Chain;
+ break;
+ case lltok::kw_amdgpu_cs_chain_preserve:
+ CC = CallingConv::AMDGPU_CS_ChainPreserve;
+ break;
case lltok::kw_amdgpu_kernel: CC = CallingConv::AMDGPU_KERNEL; break;
case lltok::kw_tailcc: CC = CallingConv::Tail; break;
case lltok::kw_cc: {
@@ -2257,9 +2247,9 @@ bool LLParser::parseAllocKind(AllocFnKind &Kind) {
static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
switch (Tok) {
case lltok::kw_argmem:
- return MemoryEffects::ArgMem;
+ return IRMemLocation::ArgMem;
case lltok::kw_inaccessiblemem:
- return MemoryEffects::InaccessibleMem;
+ return IRMemLocation::InaccessibleMem;
default:
return std::nullopt;
}
@@ -2296,7 +2286,7 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
bool SeenLoc = false;
do {
- std::optional<MemoryEffects::Location> Loc = keywordToLoc(Lex.getKind());
+ std::optional<IRMemLocation> Loc = keywordToLoc(Lex.getKind());
if (Loc) {
Lex.Lex();
if (!EatIfPresent(lltok::colon)) {
@@ -2335,6 +2325,86 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
return std::nullopt;
}
+static unsigned keywordToFPClassTest(lltok::Kind Tok) {
+ switch (Tok) {
+ case lltok::kw_all:
+ return fcAllFlags;
+ case lltok::kw_nan:
+ return fcNan;
+ case lltok::kw_snan:
+ return fcSNan;
+ case lltok::kw_qnan:
+ return fcQNan;
+ case lltok::kw_inf:
+ return fcInf;
+ case lltok::kw_ninf:
+ return fcNegInf;
+ case lltok::kw_pinf:
+ return fcPosInf;
+ case lltok::kw_norm:
+ return fcNormal;
+ case lltok::kw_nnorm:
+ return fcNegNormal;
+ case lltok::kw_pnorm:
+ return fcPosNormal;
+ case lltok::kw_sub:
+ return fcSubnormal;
+ case lltok::kw_nsub:
+ return fcNegSubnormal;
+ case lltok::kw_psub:
+ return fcPosSubnormal;
+ case lltok::kw_zero:
+ return fcZero;
+ case lltok::kw_nzero:
+ return fcNegZero;
+ case lltok::kw_pzero:
+ return fcPosZero;
+ default:
+ return 0;
+ }
+}
+
+unsigned LLParser::parseNoFPClassAttr() {
+ unsigned Mask = fcNone;
+
+ Lex.Lex();
+ if (!EatIfPresent(lltok::lparen)) {
+ tokError("expected '('");
+ return 0;
+ }
+
+ do {
+ uint64_t Value = 0;
+ unsigned TestMask = keywordToFPClassTest(Lex.getKind());
+ if (TestMask != 0) {
+ Mask |= TestMask;
+ // TODO: Disallow overlapping masks to avoid copy paste errors
+ } else if (Mask == 0 && Lex.getKind() == lltok::APSInt &&
+ !parseUInt64(Value)) {
+ if (Value == 0 || (Value & ~static_cast<unsigned>(fcAllFlags)) != 0) {
+ error(Lex.getLoc(), "invalid mask value for 'nofpclass'");
+ return 0;
+ }
+
+ if (!EatIfPresent(lltok::rparen)) {
+ error(Lex.getLoc(), "expected ')'");
+ return 0;
+ }
+
+ return Value;
+ } else {
+ error(Lex.getLoc(), "expected nofpclass test mask");
+ return 0;
+ }
+
+ Lex.Lex();
+ if (EatIfPresent(lltok::rparen))
+ return Mask;
+ } while (1);
+
+ llvm_unreachable("unterminated nofpclass attribute");
+}
+
/// parseOptionalCommaAlign
/// ::=
/// ::= ',' align 4
@@ -2573,7 +2643,7 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
// Handle "ptr" opaque pointer type.
//
// Type ::= ptr ('addrspace' '(' uint32 ')')?
- if (Result->isOpaquePointerTy()) {
+ if (Result->isPointerTy()) {
unsigned AddrSpace;
if (parseOptionalAddrSpace(AddrSpace))
return true;
@@ -3236,6 +3306,12 @@ Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty,
} else {
FwdVal = new Argument(Ty, Name);
}
+ if (FwdVal->getName() != Name) {
+ P.error(Loc, "name is too long which can result in name collisions, "
+ "consider making the name shorter or "
+ "increasing -non-global-value-max-name-size");
+ return nullptr;
+ }
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -3782,6 +3858,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
return error(ID.Loc, "frem constexprs are no longer supported");
case lltok::kw_fneg:
return error(ID.Loc, "fneg constexprs are no longer supported");
+ case lltok::kw_select:
+ return error(ID.Loc, "select constexprs are no longer supported");
case lltok::kw_icmp:
case lltok::kw_fcmp: {
unsigned PredVal, Opc = Lex.getUIntVal();
@@ -3911,8 +3989,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
case lltok::kw_getelementptr:
case lltok::kw_shufflevector:
case lltok::kw_insertelement:
- case lltok::kw_extractelement:
- case lltok::kw_select: {
+ case lltok::kw_extractelement: {
unsigned Opc = Lex.getUIntVal();
SmallVector<Constant*, 16> Elts;
bool InBounds = false;
@@ -3925,7 +4002,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
if (parseToken(lltok::lparen, "expected '(' in constantexpr"))
return true;
- LocTy ExplicitTypeLoc = Lex.getLoc();
if (Opc == Instruction::GetElementPtr) {
if (parseType(Ty) ||
parseToken(lltok::comma, "expected comma after getelementptr's type"))
@@ -3944,15 +4020,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
return error(ID.Loc, "base of getelementptr must be a pointer");
Type *BaseType = Elts[0]->getType();
- auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
- if (!BasePointerType->isOpaqueOrPointeeTypeMatches(Ty)) {
- return error(
- ExplicitTypeLoc,
- typeComparisonErrorMessage(
- "explicit pointee type doesn't match operand's pointee type",
- Ty, BasePointerType->getNonOpaquePointerElementType()));
- }
-
unsigned GEPWidth =
BaseType->isVectorTy()
? cast<FixedVectorType>(BaseType)->getNumElements()
@@ -3991,13 +4058,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
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");
- if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1],
- Elts[2]))
- return error(ID.Loc, Reason);
- ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]);
} else if (Opc == Instruction::ShuffleVector) {
if (Elts.size() != 3)
return error(ID.Loc, "expected three operands to shufflevector");
@@ -5993,10 +6053,6 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
auto FRVI = ForwardRefVals.find(FunctionName);
if (FRVI != ForwardRefVals.end()) {
FwdFn = FRVI->second.first;
- if (!FwdFn->getType()->isOpaque() &&
- !FwdFn->getType()->getNonOpaquePointerElementType()->isFunctionTy())
- return error(FRVI->second.second, "invalid forward reference to "
- "function as global value!");
if (FwdFn->getType() != PFT)
return error(FRVI->second.second,
"invalid forward reference to "
@@ -6047,7 +6103,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
Fn->setCallingConv(CC);
Fn->setAttributes(PAL);
Fn->setUnnamedAddr(UnnamedAddr);
- Fn->setAlignment(MaybeAlign(Alignment));
+ if (Alignment)
+ Fn->setAlignment(*Alignment);
Fn->setSection(Section);
Fn->setPartition(Partition);
Fn->setComdat(C);
@@ -7576,13 +7633,6 @@ int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Ordering == AtomicOrdering::AcquireRelease)
return error(Loc, "atomic load cannot use Release ordering");
- if (!cast<PointerType>(Val->getType())->isOpaqueOrPointeeTypeMatches(Ty)) {
- return error(
- ExplicitTypeLoc,
- typeComparisonErrorMessage(
- "explicit pointee type doesn't match operand's pointee type", Ty,
- Val->getType()->getNonOpaquePointerElementType()));
- }
SmallPtrSet<Type *, 4> Visited;
if (!Alignment && !Ty->isSized(&Visited))
return error(ExplicitTypeLoc, "loading unsized types is not allowed");
@@ -7627,9 +7677,6 @@ int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
return error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
return error(Loc, "store operand must be a first class value");
- if (!cast<PointerType>(Ptr->getType())
- ->isOpaqueOrPointeeTypeMatches(Val->getType()))
- return error(Loc, "stored value and pointer type do not match");
if (isAtomic && !Alignment)
return error(Loc, "atomic store must have explicit non-zero alignment");
if (Ordering == AtomicOrdering::Acquire ||
@@ -7681,12 +7728,6 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
return tokError("invalid cmpxchg failure ordering");
if (!Ptr->getType()->isPointerTy())
return error(PtrLoc, "cmpxchg operand must be a pointer");
- if (!cast<PointerType>(Ptr->getType())
- ->isOpaqueOrPointeeTypeMatches(Cmp->getType()))
- return error(CmpLoc, "compare value and pointer type do not match");
- if (!cast<PointerType>(Ptr->getType())
- ->isOpaqueOrPointeeTypeMatches(New->getType()))
- return error(NewLoc, "new value and pointer type do not match");
if (Cmp->getType() != New->getType())
return error(NewLoc, "compare value and new value type do not match");
if (!New->getType()->isFirstClassType())
@@ -7772,9 +7813,6 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
return tokError("atomicrmw cannot be unordered");
if (!Ptr->getType()->isPointerTy())
return error(PtrLoc, "atomicrmw operand must be a pointer");
- if (!cast<PointerType>(Ptr->getType())
- ->isOpaqueOrPointeeTypeMatches(Val->getType()))
- return error(ValLoc, "atomicrmw value and pointer type do not match");
if (Operation == AtomicRMWInst::Xchg) {
if (!Val->getType()->isIntegerTy() &&
@@ -7843,7 +7881,6 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
bool InBounds = EatIfPresent(lltok::kw_inbounds);
Type *Ty = nullptr;
- LocTy ExplicitTypeLoc = Lex.getLoc();
if (parseType(Ty) ||
parseToken(lltok::comma, "expected comma after getelementptr's type") ||
parseTypeAndValue(Ptr, Loc, PFS))
@@ -7854,14 +7891,6 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
if (!BasePointerType)
return error(Loc, "base of getelementptr must be a pointer");
- if (!BasePointerType->isOpaqueOrPointeeTypeMatches(Ty)) {
- return error(
- ExplicitTypeLoc,
- typeComparisonErrorMessage(
- "explicit pointee type doesn't match operand's pointee type", Ty,
- BasePointerType->getNonOpaquePointerElementType()));
- }
-
SmallVector<Value*, 16> Indices;
bool AteExtraComma = false;
// GEP returns a vector of pointers if at least one of parameters is a vector.
@@ -7895,6 +7924,11 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
if (!Indices.empty() && !Ty->isSized(&Visited))
return error(Loc, "base element of getelementptr must be sized");
+ auto *STy = dyn_cast<StructType>(Ty);
+ if (STy && STy->containsScalableVectorType())
+ return error(Loc, "getelementptr cannot target structure that contains "
+ "scalable vector type");
+
if (!GetElementPtrInst::getIndexedType(Ty, Indices))
return error(Loc, "invalid getelementptr indices");
Inst = GetElementPtrInst::Create(Ty, Ptr, Indices);
@@ -9884,7 +9918,7 @@ bool LLParser::parseMemProfs(std::vector<MIBInfo> &MIBs) {
}
/// AllocType
-/// := ('none'|'notcold'|'cold'|'notcoldandcold')
+/// := ('none'|'notcold'|'cold'|'hot')
bool LLParser::parseAllocType(uint8_t &AllocType) {
switch (Lex.getKind()) {
case lltok::kw_none:
@@ -9896,9 +9930,8 @@ bool LLParser::parseAllocType(uint8_t &AllocType) {
case lltok::kw_cold:
AllocType = (uint8_t)AllocationType::Cold;
break;
- case lltok::kw_notcoldandcold:
- AllocType =
- (uint8_t)AllocationType::NotCold | (uint8_t)AllocationType::Cold;
+ case lltok::kw_hot:
+ AllocType = (uint8_t)AllocationType::Hot;
break;
default:
return error(Lex.getLoc(), "invalid alloc type");