diff options
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 243 |
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"); |