diff options
Diffstat (limited to 'clang/lib')
32 files changed, 441 insertions, 123 deletions
diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp index 9ea104c..fd12bc4 100644 --- a/clang/lib/AST/ASTConcept.cpp +++ b/clang/lib/AST/ASTConcept.cpp @@ -86,7 +86,7 @@ void ConstraintSatisfaction::Profile(llvm::FoldingSetNodeID &ID, ID.AddPointer(ConstraintOwner); ID.AddInteger(TemplateArgs.size()); for (auto &Arg : TemplateArgs) - C.getCanonicalTemplateArgument(Arg).Profile(ID, C); + Arg.Profile(ID, C); } ConceptReference * diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 6b98927..f15b3c1 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -6432,6 +6432,13 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) { return this->emitNoRet(SourceInfo{}); } +static uint32_t getBitWidth(const Expr *E) { + assert(E->refersToBitField()); + const auto *ME = cast<MemberExpr>(E); + const auto *FD = cast<FieldDecl>(ME->getMemberDecl()); + return FD->getBitWidthValue(); +} + template <class Emitter> bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { const Expr *SubExpr = E->getSubExpr(); @@ -6460,10 +6467,15 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return DiscardResult ? this->emitPopPtr(E) : true; } - if (T == PT_Float) { + if (T == PT_Float) return DiscardResult ? this->emitIncfPop(getFPOptions(E), E) : this->emitIncf(getFPOptions(E), E); - } + + if (SubExpr->refersToBitField()) + return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E) + : this->emitIncBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E); return DiscardResult ? this->emitIncPop(*T, E->canOverflow(), E) : this->emitInc(*T, E->canOverflow(), E); @@ -6484,9 +6496,15 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return DiscardResult ? this->emitPopPtr(E) : true; } - if (T == PT_Float) { + if (T == PT_Float) return DiscardResult ? this->emitDecfPop(getFPOptions(E), E) : this->emitDecf(getFPOptions(E), E); + + if (SubExpr->refersToBitField()) { + return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E) + : this->emitDecBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E); } return DiscardResult ? this->emitDecPop(*T, E->canOverflow(), E) @@ -6515,6 +6533,11 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { if (DiscardResult) { if (T == PT_Float) return this->emitIncfPop(getFPOptions(E), E); + if (SubExpr->refersToBitField()) + return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E) + : this->emitIncBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E); return this->emitIncPop(*T, E->canOverflow(), E); } @@ -6530,6 +6553,11 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return false; if (!this->emitStoreFloat(E)) return false; + } else if (SubExpr->refersToBitField()) { + assert(isIntegralType(*T)); + if (!this->emitPreIncBitfield(*T, E->canOverflow(), getBitWidth(SubExpr), + E)) + return false; } else { assert(isIntegralType(*T)); if (!this->emitPreInc(*T, E->canOverflow(), E)) @@ -6560,6 +6588,11 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { if (DiscardResult) { if (T == PT_Float) return this->emitDecfPop(getFPOptions(E), E); + if (SubExpr->refersToBitField()) + return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E) + : this->emitDecBitfield(*T, E->canOverflow(), + getBitWidth(SubExpr), E); return this->emitDecPop(*T, E->canOverflow(), E); } @@ -6575,6 +6608,11 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return false; if (!this->emitStoreFloat(E)) return false; + } else if (SubExpr->refersToBitField()) { + assert(isIntegralType(*T)); + if (!this->emitPreDecBitfield(*T, E->canOverflow(), getBitWidth(SubExpr), + E)) + return false; } else { assert(isIntegralType(*T)); if (!this->emitPreDec(*T, E->canOverflow(), E)) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index d8529da..89f6fbe 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -702,7 +702,7 @@ enum class IncDecOp { template <typename T, IncDecOp Op, PushVal DoPush> bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - bool CanOverflow) { + bool CanOverflow, UnsignedOrNone BitWidth = std::nullopt) { assert(!Ptr.isDummy()); if (!S.inConstantContext()) { @@ -725,12 +725,18 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, if constexpr (Op == IncDecOp::Inc) { if (!T::increment(Value, &Result) || !CanOverflow) { - Ptr.deref<T>() = Result; + if (BitWidth) + Ptr.deref<T>() = Result.truncate(*BitWidth); + else + Ptr.deref<T>() = Result; return true; } } else { if (!T::decrement(Value, &Result) || !CanOverflow) { - Ptr.deref<T>() = Result; + if (BitWidth) + Ptr.deref<T>() = Result.truncate(*BitWidth); + else + Ptr.deref<T>() = Result; return true; } } @@ -774,6 +780,17 @@ bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow) { CanOverflow); } +template <PrimType Name, class T = typename PrimConv<Name>::T> +bool IncBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, + unsigned BitWidth) { + const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckLoad(S, OpPC, Ptr, AK_Increment)) + return false; + + return IncDecHelper<T, IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr, CanOverflow, + BitWidth); +} + /// 1) Pops a pointer from the stack /// 2) Load the value from the pointer /// 3) Writes the value increased by one back to the pointer @@ -787,6 +804,17 @@ bool IncPop(InterpState &S, CodePtr OpPC, bool CanOverflow) { } template <PrimType Name, class T = typename PrimConv<Name>::T> +bool IncPopBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckLoad(S, OpPC, Ptr, AK_Increment)) + return false; + + return IncDecHelper<T, IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, CanOverflow, + BitWidth); +} + +template <PrimType Name, class T = typename PrimConv<Name>::T> bool PreInc(InterpState &S, CodePtr OpPC, bool CanOverflow) { const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckLoad(S, OpPC, Ptr, AK_Increment)) @@ -795,6 +823,17 @@ bool PreInc(InterpState &S, CodePtr OpPC, bool CanOverflow) { return IncDecHelper<T, IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, CanOverflow); } +template <PrimType Name, class T = typename PrimConv<Name>::T> +bool PreIncBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.peek<Pointer>(); + if (!CheckLoad(S, OpPC, Ptr, AK_Increment)) + return false; + + return IncDecHelper<T, IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, CanOverflow, + BitWidth); +} + /// 1) Pops a pointer from the stack /// 2) Load the value from the pointer /// 3) Writes the value decreased by one back to the pointer @@ -808,6 +847,16 @@ bool Dec(InterpState &S, CodePtr OpPC, bool CanOverflow) { return IncDecHelper<T, IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr, CanOverflow); } +template <PrimType Name, class T = typename PrimConv<Name>::T> +bool DecBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) + return false; + + return IncDecHelper<T, IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr, CanOverflow, + BitWidth); +} /// 1) Pops a pointer from the stack /// 2) Load the value from the pointer @@ -822,6 +871,17 @@ bool DecPop(InterpState &S, CodePtr OpPC, bool CanOverflow) { } template <PrimType Name, class T = typename PrimConv<Name>::T> +bool DecPopBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) + return false; + + return IncDecHelper<T, IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, CanOverflow, + BitWidth); +} + +template <PrimType Name, class T = typename PrimConv<Name>::T> bool PreDec(InterpState &S, CodePtr OpPC, bool CanOverflow) { const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) @@ -829,6 +889,16 @@ bool PreDec(InterpState &S, CodePtr OpPC, bool CanOverflow) { return IncDecHelper<T, IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, CanOverflow); } +template <PrimType Name, class T = typename PrimConv<Name>::T> +bool PreDecBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, + uint32_t BitWidth) { + const Pointer &Ptr = S.Stk.peek<Pointer>(); + if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) + return false; + return IncDecHelper<T, IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, CanOverflow, + BitWidth); +} + template <IncDecOp Op, PushVal DoPush> bool IncDecFloatHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, uint32_t FPOI) { diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 532c444..406feb5 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -612,12 +612,25 @@ class OverflowOpcode : Opcode { let HasGroup = 1; } +class OverflowBitfieldOpcode : Opcode { + let Types = [AluTypeClass]; + let Args = [ArgBool, ArgUint32]; + let HasGroup = 1; +} + def Inc : OverflowOpcode; +def IncBitfield : OverflowBitfieldOpcode; def IncPop : OverflowOpcode; +def IncPopBitfield : OverflowBitfieldOpcode; def PreInc : OverflowOpcode; +def PreIncBitfield : OverflowBitfieldOpcode; + def Dec : OverflowOpcode; +def DecBitfield : OverflowBitfieldOpcode; def DecPop : OverflowOpcode; +def DecPopBitfield : OverflowBitfieldOpcode; def PreDec : OverflowOpcode; +def PreDecBitfield : OverflowBitfieldOpcode; // Float increment and decrement. def Incf: FloatOpcode; diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp index 07e3de8..2b56c1e 100644 --- a/clang/lib/AST/StmtOpenACC.cpp +++ b/clang/lib/AST/StmtOpenACC.cpp @@ -12,7 +12,9 @@ #include "clang/AST/StmtOpenACC.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" + using namespace clang; OpenACCComputeConstruct * @@ -322,6 +324,38 @@ OpenACCAtomicConstruct *OpenACCAtomicConstruct::Create( return Inst; } +const OpenACCAtomicConstruct::StmtInfo +OpenACCAtomicConstruct::getAssociatedStmtInfo() const { + // This ends up being a vastly simplified version of SemaOpenACCAtomic, since + // it doesn't have to worry about erroring out, but we should do a lot of + // asserts to ensure we don't get off into the weeds. + assert(getAssociatedStmt() && "invalid associated stmt?"); + + switch (AtomicKind) { + case OpenACCAtomicKind::None: + case OpenACCAtomicKind::Write: + case OpenACCAtomicKind::Update: + case OpenACCAtomicKind::Capture: + assert(false && "Only 'read' has been implemented here"); + return {}; + case OpenACCAtomicKind::Read: { + // Read only supports the format 'v = x'; where both sides are a scalar + // expression. This can come in 2 forms; BinaryOperator or + // CXXOperatorCallExpr (rarely). + const Expr *AssignExpr = cast<const Expr>(getAssociatedStmt()); + if (const auto *BO = dyn_cast<BinaryOperator>(AssignExpr)) { + assert(BO->getOpcode() == BO_Assign); + return {BO->getLHS()->IgnoreImpCasts(), BO->getRHS()->IgnoreImpCasts()}; + } + + const auto *OO = cast<CXXOperatorCallExpr>(AssignExpr); + assert(OO->getOperator() == OO_Equal); + + return {OO->getArg(0)->IgnoreImpCasts(), OO->getArg(1)->IgnoreImpCasts()}; + } + } +} + OpenACCCacheConstruct *OpenACCCacheConstruct::CreateEmpty(const ASTContext &C, unsigned NumVars) { void *Mem = diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 2da7789..c18b2ea 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2147,9 +2147,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, } case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break; case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break; - case attr::DeviceKernel: - OS << T->getAttr()->getSpelling(); - break; case attr::IntelOclBicc: OS << "inteloclbicc"; break; diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index 33c2958..f5c8396 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -200,7 +200,7 @@ public: // a host function. if (HostTarget) return HostTarget->checkCallingConvention(CC); - return CCCR_Warning; + return CC == CC_DeviceKernel ? CCCR_OK : CCCR_Warning; } bool hasBitIntType() const override { return true; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 19ed656..800262a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -1011,9 +1011,9 @@ public: } mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) { - cgm.errorNYI(die->getBeginLoc(), - "ConstExprEmitter::VisitCXXDefaultInitExpr"); - return {}; + // No need for a DefaultInitExprScope: we don't handle 'this' in a + // constant expression. + return Visit(die->getExpr(), t); } mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) { @@ -1028,9 +1028,7 @@ public: mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *e, QualType t) { - cgm.errorNYI(e->getBeginLoc(), - "ConstExprEmitter::VisitImplicitValueInitExpr"); - return {}; + return cgm.getBuilder().getZeroInitAttr(cgm.convertType(t)); } mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) { diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp index ce4ae7e..385f89c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp @@ -553,12 +553,15 @@ public: } void VisitIfClause(const OpenACCIfClause &clause) { - if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp, - mlir::acc::KernelsOp, mlir::acc::InitOp, - mlir::acc::ShutdownOp, mlir::acc::SetOp, - mlir::acc::DataOp, mlir::acc::WaitOp, - mlir::acc::HostDataOp, mlir::acc::EnterDataOp, - mlir::acc::ExitDataOp, mlir::acc::UpdateOp>) { + if constexpr (isOneOfTypes< + OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp, + mlir::acc::KernelsOp, mlir::acc::InitOp, + mlir::acc::ShutdownOp, mlir::acc::SetOp, + mlir::acc::DataOp, mlir::acc::WaitOp, + mlir::acc::HostDataOp, mlir::acc::EnterDataOp, + mlir::acc::ExitDataOp, mlir::acc::UpdateOp, + mlir::acc::AtomicReadOp, mlir::acc::AtomicWriteOp, + mlir::acc::AtomicUpdateOp, mlir::acc::AtomicCaptureOp>) { operation.getIfCondMutable().append( createCondition(clause.getConditionExpr())); } else if constexpr (isCombinedType<OpTy>) { @@ -1144,6 +1147,10 @@ EXPL_SPEC(mlir::acc::HostDataOp) EXPL_SPEC(mlir::acc::EnterDataOp) EXPL_SPEC(mlir::acc::ExitDataOp) EXPL_SPEC(mlir::acc::UpdateOp) +EXPL_SPEC(mlir::acc::AtomicReadOp) +EXPL_SPEC(mlir::acc::AtomicWriteOp) +EXPL_SPEC(mlir::acc::AtomicCaptureOp) +EXPL_SPEC(mlir::acc::AtomicUpdateOp) #undef EXPL_SPEC template <typename ComputeOp, typename LoopOp> diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp index e89393c..02bb46d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp @@ -306,6 +306,29 @@ CIRGenFunction::emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s) { mlir::LogicalResult CIRGenFunction::emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s) { - cgm.errorNYI(s.getSourceRange(), "OpenACC Atomic Construct"); - return mlir::failure(); + // For now, we are only support 'read', so diagnose. We can switch on the kind + // later once we start implementing the other 3 forms. + if (s.getAtomicKind() != OpenACCAtomicKind::Read) { + cgm.errorNYI(s.getSourceRange(), "OpenACC Atomic Construct"); + return mlir::failure(); + } + + // While Atomic is an 'associated statement' construct, it 'steals' the + // expression it is associated with rather than emitting it inside of it. So + // it has custom emit logic. + mlir::Location start = getLoc(s.getSourceRange().getBegin()); + OpenACCAtomicConstruct::StmtInfo inf = s.getAssociatedStmtInfo(); + // Atomic 'read' only permits 'v = x', where v and x are both scalar L values. + // The getAssociatedStmtInfo strips off implicit casts, which includes + // implicit conversions and L-to-R-Value conversions, so we can just emit it + // as an L value. The Flang implementation has no problem with different + // types, so it appears that the dialect can handle the conversions. + mlir::Value v = emitLValue(inf.V).getPointer(); + mlir::Value x = emitLValue(inf.X).getPointer(); + mlir::Type resTy = convertType(inf.V->getType()); + auto op = mlir::acc::AtomicReadOp::create(builder, start, x, v, resTy, + /*ifCond=*/{}); + emitOpenACCClauses(op, s.getDirectiveKind(), s.getDirectiveLoc(), + s.clauses()); + return mlir::success(); } diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6020684..c423c4b 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -234,9 +234,12 @@ public: }; } // namespace -static AllocTokenOptions getAllocTokenOptions(const CodeGenOptions &CGOpts) { +static AllocTokenOptions getAllocTokenOptions(const LangOptions &LangOpts, + const CodeGenOptions &CGOpts) { AllocTokenOptions Opts; - Opts.MaxTokens = CGOpts.AllocTokenMax; + if (LangOpts.AllocTokenMode) + Opts.Mode = *LangOpts.AllocTokenMode; + Opts.MaxTokens = LangOpts.AllocTokenMax; Opts.Extended = CGOpts.SanitizeAllocTokenExtended; Opts.FastABI = CGOpts.SanitizeAllocTokenFastABI; return Opts; @@ -430,12 +433,6 @@ static bool initTargetOptions(const CompilerInstance &CI, Options.NoInfsFPMath = LangOpts.NoHonorInfs; Options.NoNaNsFPMath = LangOpts.NoHonorNaNs; Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; - Options.UnsafeFPMath = LangOpts.AllowFPReassoc && LangOpts.AllowRecip && - LangOpts.NoSignedZero && LangOpts.ApproxFunc && - (LangOpts.getDefaultFPContractMode() == - LangOptions::FPModeKind::FPM_Fast || - LangOpts.getDefaultFPContractMode() == - LangOptions::FPModeKind::FPM_FastHonorPragmas); Options.BBAddrMap = CodeGenOpts.BBAddrMap; Options.BBSections = @@ -808,7 +805,7 @@ static void addSanitizers(const Triple &TargetTriple, // memory allocation function detection. MPM.addPass(InferFunctionAttrsPass()); } - MPM.addPass(AllocTokenPass(getAllocTokenOptions(CodeGenOpts))); + MPM.addPass(AllocTokenPass(getAllocTokenOptions(LangOpts, CodeGenOpts))); } }; if (ClSanitizeOnOptimizerEarlyEP) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e490b1c..3746bc04 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1325,22 +1325,29 @@ void CodeGenModule::Release() { "tag-stack-memory-buildattr", 1); if (T.isARM() || T.isThumb() || T.isAArch64()) { + // Previously 1 is used and meant for the backed to derive the function + // attribute form it. 2 now means function attributes already set for all + // functions in this module, so no need to propagate those from the module + // flag. Value is only used in case of LTO module merge because the backend + // will see all required function attribute set already. Value is used + // before modules got merged. Any posive value means the feature is active + // and required binary markings need to be emit accordingly. if (LangOpts.BranchTargetEnforcement) getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement", - 1); + 2); if (LangOpts.BranchProtectionPAuthLR) getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", - 1); + 2); if (LangOpts.GuardedControlStack) - getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1); + getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 2); if (LangOpts.hasSignReturnAddress()) - getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1); + getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 2); if (LangOpts.isSignReturnAddressScopeAll()) getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all", - 1); + 2); if (!LangOpts.isSignReturnAddressWithAKey()) getModule().addModuleFlag(llvm::Module::Min, - "sign-return-address-with-bkey", 1); + "sign-return-address-with-bkey", 2); if (LangOpts.PointerAuthELFGOT) getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1); diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp index 0bc4b4b7..e4ad078 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -439,9 +439,11 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes( return; const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); - if (FD) + if (FD) { setFunctionDeclAttributes(FD, F, M); - + if (FD->hasAttr<DeviceKernelAttr>() && !M.getLangOpts().OpenCL) + F->setCallingConv(getDeviceKernelCallingConv()); + } if (!getABIInfo().getCodeGenOpts().EmitIEEENaNCompliantInsts) F->addFnAttr("amdgpu-ieee", "false"); } @@ -658,7 +660,7 @@ llvm::Value *AMDGPUTargetCodeGenInfo::createEnqueuedBlockKernel( // kernel address (only the kernel descriptor). auto *F = llvm::Function::Create(FT, llvm::GlobalValue::InternalLinkage, Name, &Mod); - F->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL); + F->setCallingConv(getDeviceKernelCallingConv()); llvm::AttrBuilder KernelAttrs(C); // FIXME: The invoke isn't applying the right attributes either diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp index 53f2fc4..f6715861 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -264,7 +264,7 @@ void NVPTXTargetCodeGenInfo::setTargetAttributes( // And kernel functions are not subject to inlining F->addFnAttr(llvm::Attribute::NoInline); if (FD->hasAttr<CUDAGlobalAttr>()) { - F->setCallingConv(llvm::CallingConv::PTX_Kernel); + F->setCallingConv(getDeviceKernelCallingConv()); for (auto IV : llvm::enumerate(FD->parameters())) if (IV.value()->hasAttr<CUDAGridConstantAttr>()) @@ -278,7 +278,7 @@ void NVPTXTargetCodeGenInfo::setTargetAttributes( } // Attach kernel metadata directly if compiling for NVPTX. if (FD->hasAttr<DeviceKernelAttr>()) - F->setCallingConv(llvm::CallingConv::PTX_Kernel); + F->setCallingConv(getDeviceKernelCallingConv()); } void NVPTXTargetCodeGenInfo::addNVVMMetadata(llvm::GlobalValue *GV, diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 80e096e..15d0b35 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -64,6 +64,8 @@ public: llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const override; + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; }; class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo { public: @@ -268,6 +270,22 @@ CommonSPIRTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::ConstantPointerNull::get(NPT), PT); } +void CommonSPIRTargetCodeGenInfo::setTargetAttributes( + const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { + if (M.getLangOpts().OpenCL || GV->isDeclaration()) + return; + + const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); + if (!FD) + return; + + llvm::Function *F = dyn_cast<llvm::Function>(GV); + assert(F && "Expected GlobalValue to be a Function"); + + if (FD->hasAttr<DeviceKernelAttr>()) + F->setCallingConv(getDeviceKernelCallingConv()); +} + LangAS SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const { @@ -292,19 +310,23 @@ SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, void SPIRVTargetCodeGenInfo::setTargetAttributes( const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { - if (!M.getLangOpts().HIP || - M.getTarget().getTriple().getVendor() != llvm::Triple::AMD) - return; if (GV->isDeclaration()) return; - auto F = dyn_cast<llvm::Function>(GV); - if (!F) + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); + if (!FD) return; - auto FD = dyn_cast_or_null<FunctionDecl>(D); - if (!FD) + llvm::Function *F = dyn_cast<llvm::Function>(GV); + assert(F && "Expected GlobalValue to be a Function"); + + if (FD->hasAttr<DeviceKernelAttr>()) + F->setCallingConv(getDeviceKernelCallingConv()); + + if (!M.getLangOpts().HIP || + M.getTarget().getTriple().getVendor() != llvm::Triple::AMD) return; + if (!FD->hasAttr<CUDAGlobalAttr>()) return; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index a7310ba..caf7478 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -9099,6 +9099,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, }; auto ShouldForward = [&](const llvm::DenseSet<unsigned> &Set, Arg *A, const ToolChain &TC) { + // CMake hack to avoid printing verbose informatoin for HIP non-RDC mode. + if (A->getOption().matches(OPT_v) && JA.getType() == types::TY_Object) + return false; return (Set.contains(A->getOption().getID()) || (A->getOption().getGroup().isValid() && Set.contains(A->getOption().getGroup().getID()))) && @@ -9174,7 +9177,12 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString("--host-triple=" + getToolChain().getTripleString())); - if (Args.hasArg(options::OPT_v)) + + // CMake hack, suppress passing verbose arguments for the special-case HIP + // non-RDC mode compilation. This confuses default CMake implicit linker + // argument parsing when the language is set to HIP and the system linker is + // also `ld.lld`. + if (Args.hasArg(options::OPT_v) && JA.getType() != types::TY_Object) CmdArgs.push_back("--wrapper-verbose"); if (Arg *A = Args.getLastArg(options::OPT_cuda_path_EQ)) CmdArgs.push_back( diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c97a9e8..25971d2 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3791,12 +3791,18 @@ static bool isFunctionDeclarationName(const LangOptions &LangOpts, if (Current.is(TT_FunctionDeclarationName)) return true; - if (Current.isNoneOf(tok::identifier, tok::kw_operator)) + if (!Current.Tok.getIdentifierInfo()) return false; const auto *Prev = Current.getPreviousNonComment(); assert(Prev); + if (Prev->is(tok::coloncolon)) + Prev = Prev->Previous; + + if (!Prev) + return false; + const auto &Previous = *Prev; if (const auto *PrevPrev = Previous.getPreviousNonComment(); @@ -3845,8 +3851,6 @@ static bool isFunctionDeclarationName(const LangOptions &LangOpts, // Find parentheses of parameter list. if (Current.is(tok::kw_operator)) { - if (Line.startsWith(tok::kw_friend)) - return true; if (Previous.Tok.getIdentifierInfo() && Previous.isNoneOf(tok::kw_return, tok::kw_co_return)) { return true; diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index cb44568..d53b64a 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1651,6 +1651,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( AST->Reader = nullptr; // Create a file manager object to provide access to and cache the filesystem. + Clang->setVirtualFileSystem(AST->getVirtualFileSystemPtr()); Clang->setFileManager(AST->getFileManagerPtr()); // Create the source manager. @@ -2290,6 +2291,7 @@ void ASTUnit::CodeComplete( "IR inputs not support here!"); // Use the source and file managers that we were given. + Clang->setVirtualFileSystem(FileMgr->getVirtualFileSystemPtr()); Clang->setFileManager(FileMgr); Clang->setSourceManager(SourceMgr); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 5844366..374138f 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -160,8 +160,6 @@ bool CompilerInstance::createTarget() { } void CompilerInstance::setFileManager(IntrusiveRefCntPtr<FileManager> Value) { - if (!hasVirtualFileSystem()) - setVirtualFileSystem(Value->getVirtualFileSystemPtr()); assert(Value == nullptr || getVirtualFileSystemPtr() == Value->getVirtualFileSystemPtr()); FileMgr = std::move(Value); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5bd15f5..d2cb751 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1833,10 +1833,6 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, serializeSanitizerKinds(Opts.SanitizeAnnotateDebugInfo)) GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer); - if (Opts.AllocTokenMax) - GenerateArg(Consumer, OPT_falloc_token_max_EQ, - std::to_string(*Opts.AllocTokenMax)); - if (!Opts.EmitVersionIdentMetadata) GenerateArg(Consumer, OPT_Qn); @@ -2350,15 +2346,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, } } - if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_max_EQ)) { - StringRef S = Arg->getValue(); - uint64_t Value = 0; - if (S.getAsInteger(0, Value)) - Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S; - else - Opts.AllocTokenMax = Value; - } - Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); if (!LangOpts->CUDAIsDevice) @@ -3966,6 +3953,29 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, if (!Opts.RandstructSeed.empty()) GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed); + + if (Opts.AllocTokenMax) + GenerateArg(Consumer, OPT_falloc_token_max_EQ, + std::to_string(*Opts.AllocTokenMax)); + + if (Opts.AllocTokenMode) { + StringRef S; + switch (*Opts.AllocTokenMode) { + case llvm::AllocTokenMode::Increment: + S = "increment"; + break; + case llvm::AllocTokenMode::Random: + S = "random"; + break; + case llvm::AllocTokenMode::TypeHash: + S = "typehash"; + break; + case llvm::AllocTokenMode::TypeHashPointerSplit: + S = "typehashpointersplit"; + break; + } + GenerateArg(Consumer, OPT_falloc_token_mode_EQ, S); + } } bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, @@ -4544,6 +4554,23 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ)) Opts.RandstructSeed = A->getValue(0); + if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_max_EQ)) { + StringRef S = Arg->getValue(); + uint64_t Value = 0; + if (S.getAsInteger(0, Value)) + Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S; + else + Opts.AllocTokenMax = Value; + } + + if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_mode_EQ)) { + StringRef S = Arg->getValue(); + if (auto Mode = getAllocTokenModeFromString(S)) + Opts.AllocTokenMode = Mode; + else + Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S; + } + // Validate options for HLSL if (Opts.HLSL) { // TODO: Revisit restricting SPIR-V to logical once we've figured out how to diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 0daa20a..ed1169e 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -945,6 +945,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. + CI.setVirtualFileSystem(AST->getVirtualFileSystemPtr()); CI.setFileManager(AST->getFileManagerPtr()); CI.setSourceManager(AST->getSourceManagerPtr()); CI.setPreprocessor(AST->getPreprocessorPtr()); diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp index 03f70b7..9bf18b4 100644 --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -479,16 +479,12 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( Diagnostics->Reset(); ProcessWarningOptions(*Diagnostics, Clang->getDiagnosticOpts(), *VFS); - VFS = createVFSFromCompilerInvocation(Clang->getInvocation(), *Diagnostics, - VFS); - // Create a file manager object to provide access to and cache the filesystem. - Clang->setFileManager( - llvm::makeIntrusiveRefCnt<FileManager>(Clang->getFileSystemOpts(), VFS)); + Clang->createVirtualFileSystem(VFS); + Clang->createFileManager(); // Create the source manager. - Clang->setSourceManager(llvm::makeIntrusiveRefCnt<SourceManager>( - *Diagnostics, Clang->getFileManager())); + Clang->createSourceManager(); auto PreambleDepCollector = std::make_shared<PreambleDependencyCollector>(); Clang->addDependencyCollector(PreambleDepCollector); diff --git a/clang/lib/Headers/avx512ifmavlintrin.h b/clang/lib/Headers/avx512ifmavlintrin.h index c4449c7..b377c17 100644 --- a/clang/lib/Headers/avx512ifmavlintrin.h +++ b/clang/lib/Headers/avx512ifmavlintrin.h @@ -37,6 +37,7 @@ #endif +#if !(defined(__AVXIFMA__) || defined(__AVX512IFMA__)) #define _mm_madd52hi_epu64(X, Y, Z) \ ((__m128i)__builtin_ia32_vpmadd52huq128((__v2di)(X), (__v2di)(Y), \ (__v2di)(Z))) @@ -52,56 +53,83 @@ #define _mm256_madd52lo_epu64(X, Y, Z) \ ((__m256i)__builtin_ia32_vpmadd52luq256((__v4di)(X), (__v4di)(Y), \ (__v4di)(Z))) +#endif + +#if defined(__AVX512IFMA__) +static __inline__ __m128i __DEFAULT_FN_ATTRS128 +_mm_madd52hi_epu64(__m128i __X, __m128i __Y, __m128i __Z) { + return (__m128i)__builtin_ia32_vpmadd52huq128((__v2di)__X, (__v2di)__Y, + (__v2di)__Z); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS256 +_mm256_madd52hi_epu64(__m256i __X, __m256i __Y, __m256i __Z) { + return (__m256i)__builtin_ia32_vpmadd52huq256((__v4di)__X, (__v4di)__Y, + (__v4di)__Z); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS128 +_mm_madd52lo_epu64(__m128i __X, __m128i __Y, __m128i __Z) { + return (__m128i)__builtin_ia32_vpmadd52luq128((__v2di)__X, (__v2di)__Y, + (__v2di)__Z); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS256 +_mm256_madd52lo_epu64(__m256i __X, __m256i __Y, __m256i __Z) { + return (__m256i)__builtin_ia32_vpmadd52luq256((__v4di)__X, (__v4di)__Y, + (__v4di)__Z); +} +#endif static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_mask_madd52hi_epu64(__m128i __W, __mmask8 __M, __m128i __X, __m128i __Y) { return (__m128i)__builtin_ia32_selectq_128( - __M, (__v2di)_mm_madd52hi_epu64(__W, __X, __Y), (__v2di)__W); + __M, (__v2di)__builtin_ia32_vpmadd52huq128(__W, __X, __Y), (__v2di)__W); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_maskz_madd52hi_epu64(__mmask8 __M, __m128i __X, __m128i __Y, __m128i __Z) { return (__m128i)__builtin_ia32_selectq_128( - __M, (__v2di)_mm_madd52hi_epu64(__X, __Y, __Z), + __M, (__v2di)__builtin_ia32_vpmadd52huq128(__X, __Y, __Z), (__v2di)_mm_setzero_si128()); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_mask_madd52hi_epu64( __m256i __W, __mmask8 __M, __m256i __X, __m256i __Y) { return (__m256i)__builtin_ia32_selectq_256( - __M, (__v4di)_mm256_madd52hi_epu64(__W, __X, __Y), (__v4di)__W); + __M, (__v4di)__builtin_ia32_vpmadd52huq256(__W, __X, __Y), (__v4di)__W); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_maskz_madd52hi_epu64( __mmask8 __M, __m256i __X, __m256i __Y, __m256i __Z) { return (__m256i)__builtin_ia32_selectq_256( - __M, (__v4di)_mm256_madd52hi_epu64(__X, __Y, __Z), + __M, (__v4di)__builtin_ia32_vpmadd52huq256(__X, __Y, __Z), (__v4di)_mm256_setzero_si256()); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_mask_madd52lo_epu64(__m128i __W, __mmask8 __M, __m128i __X, __m128i __Y) { return (__m128i)__builtin_ia32_selectq_128( - __M, (__v2di)_mm_madd52lo_epu64(__W, __X, __Y), (__v2di)__W); + __M, (__v2di)__builtin_ia32_vpmadd52luq128(__W, __X, __Y), (__v2di)__W); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_maskz_madd52lo_epu64(__mmask8 __M, __m128i __X, __m128i __Y, __m128i __Z) { return (__m128i)__builtin_ia32_selectq_128( - __M, (__v2di)_mm_madd52lo_epu64(__X, __Y, __Z), + __M, (__v2di)__builtin_ia32_vpmadd52luq128(__X, __Y, __Z), (__v2di)_mm_setzero_si128()); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_mask_madd52lo_epu64( __m256i __W, __mmask8 __M, __m256i __X, __m256i __Y) { return (__m256i)__builtin_ia32_selectq_256( - __M, (__v4di)_mm256_madd52lo_epu64(__W, __X, __Y), (__v4di)__W); + __M, (__v4di)__builtin_ia32_vpmadd52luq256(__W, __X, __Y), (__v4di)__W); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_maskz_madd52lo_epu64( __mmask8 __M, __m256i __X, __m256i __Y, __m256i __Z) { return (__m256i)__builtin_ia32_selectq_256( - __M, (__v4di)_mm256_madd52lo_epu64(__X, __Y, __Z), + __M, (__v4di)__builtin_ia32_vpmadd52luq256(__X, __Y, __Z), (__v4di)_mm256_setzero_si256()); } diff --git a/clang/lib/Headers/avxifmaintrin.h b/clang/lib/Headers/avxifmaintrin.h index a2ef601..e452d5f 100644 --- a/clang/lib/Headers/avxifmaintrin.h +++ b/clang/lib/Headers/avxifmaintrin.h @@ -31,6 +31,13 @@ __min_vector_width__(256))) #endif +#if !defined(__AVX512IFMA__) && defined(__AVXIFMA__) +#define _mm_madd52hi_epu64(X, Y, Z) _mm_madd52hi_avx_epu64(X, Y, Z) +#define _mm_madd52lo_epu64(X, Y, Z) _mm_madd52lo_avx_epu64(X, Y, Z) +#define _mm256_madd52hi_epu64(X, Y, Z) _mm256_madd52hi_avx_epu64(X, Y, Z) +#define _mm256_madd52lo_epu64(X, Y, Z) _mm256_madd52lo_avx_epu64(X, Y, Z) +#endif + // must vex-encoding /// Multiply packed unsigned 52-bit integers in each 64-bit element of \a __Y diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp index cbdefaa..056e133 100644 --- a/clang/lib/Sema/HeuristicResolver.cpp +++ b/clang/lib/Sema/HeuristicResolver.cpp @@ -450,7 +450,12 @@ QualType HeuristicResolverImpl::resolveExprToType(const Expr *E) { if (const auto *CE = dyn_cast<CallExpr>(E)) { if (QualType Resolved = resolveTypeOfCallExpr(CE); !Resolved.isNull()) return Resolved; + + // Don't proceed to try resolveExprToDecls(), it would just call + // resolveTypeOfCallExpr() again. + return E->getType(); } + // Similarly, unwrapping a unary dereference operation does not work via // resolveExprToDecls. if (const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts())) { diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 215ac18..8ed3df7 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1484,6 +1484,13 @@ void Sema::ActOnEndOfTranslationUnit() { Consumer.CompleteTentativeDefinition(VD); } + // In incremental mode, tentative definitions belong to the current + // partial translation unit (PTU). Once they have been completed and + // emitted to codegen, drop them to prevent re-emission in future PTUs. + if (PP.isIncrementalProcessingEnabled()) + TentativeDefinitions.erase(TentativeDefinitions.begin(ExternalSource.get()), + TentativeDefinitions.end()); + for (auto *D : ExternalDeclarations) { if (!D || D->isInvalidDecl() || D->getPreviousDecl() || !D->isUsed()) continue; diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 54cbfe4..a1163e9 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -417,8 +417,8 @@ class ConstraintSatisfactionChecker { const NamedDecl *Template; SourceLocation TemplateNameLoc; UnsignedOrNone PackSubstitutionIndex; - ConstraintSatisfaction &Satisfaction; + bool BuildExpression; private: ExprResult @@ -461,10 +461,11 @@ public: ConstraintSatisfactionChecker(Sema &SemaRef, const NamedDecl *Template, SourceLocation TemplateNameLoc, UnsignedOrNone PackSubstitutionIndex, - ConstraintSatisfaction &Satisfaction) + ConstraintSatisfaction &Satisfaction, + bool BuildExpression) : S(SemaRef), Template(Template), TemplateNameLoc(TemplateNameLoc), PackSubstitutionIndex(PackSubstitutionIndex), - Satisfaction(Satisfaction) {} + Satisfaction(Satisfaction), BuildExpression(BuildExpression) {} ExprResult Evaluate(const NormalizedConstraint &Constraint, const MultiLevelTemplateArgumentList &MLTAL); @@ -821,9 +822,10 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow( Satisfaction.ContainsErrors = false; ExprResult Expr = ConstraintSatisfactionChecker(S, Template, TemplateNameLoc, - UnsignedOrNone(I), Satisfaction) + UnsignedOrNone(I), Satisfaction, + /*BuildExpression=*/false) .Evaluate(Constraint.getNormalizedPattern(), *SubstitutedArgs); - if (Expr.isUsable()) { + if (BuildExpression && Expr.isUsable()) { if (Out.isUnset()) Out = Expr; else @@ -834,7 +836,7 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow( Constraint.getBeginLoc(), FPOptionsOverride{}); } else { - assert(!Satisfaction.IsSatisfied); + assert(!BuildExpression || !Satisfaction.IsSatisfied); } if (!Conjunction && Satisfaction.IsSatisfied) { Satisfaction.Details.erase(Satisfaction.Details.begin() + @@ -985,7 +987,7 @@ ExprResult ConstraintSatisfactionChecker::Evaluate( ExprResult E = Evaluate(Constraint.getNormalizedConstraint(), MLTAL); - if (!E.isUsable()) { + if (E.isInvalid()) { Satisfaction.Details.insert(Satisfaction.Details.begin() + Size, ConceptId); return E; } @@ -1041,7 +1043,7 @@ ExprResult ConstraintSatisfactionChecker::Evaluate( if (Conjunction && (!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors)) return LHS; - if (!Conjunction && LHS.isUsable() && Satisfaction.IsSatisfied && + if (!Conjunction && !LHS.isInvalid() && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors) return LHS; @@ -1050,12 +1052,15 @@ ExprResult ConstraintSatisfactionChecker::Evaluate( ExprResult RHS = Evaluate(Constraint.getRHS(), MLTAL); - if (RHS.isUsable() && Satisfaction.IsSatisfied && + if (!Conjunction && !RHS.isInvalid() && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors) Satisfaction.Details.erase(Satisfaction.Details.begin() + EffectiveDetailEndIndex, Satisfaction.Details.end()); + if (!BuildExpression) + return Satisfaction.ContainsErrors ? ExprError() : ExprEmpty(); + if (!LHS.isUsable()) return RHS; @@ -1136,10 +1141,11 @@ static bool CheckConstraintSatisfaction( Template, /*CSE=*/nullptr, S.ArgPackSubstIndex); - ExprResult Res = - ConstraintSatisfactionChecker(S, Template, TemplateIDRange.getBegin(), - S.ArgPackSubstIndex, Satisfaction) - .Evaluate(*C, TemplateArgsLists); + ExprResult Res = ConstraintSatisfactionChecker( + S, Template, TemplateIDRange.getBegin(), + S.ArgPackSubstIndex, Satisfaction, + /*BuildExpression=*/ConvertedExpr != nullptr) + .Evaluate(*C, TemplateArgsLists); if (Res.isInvalid()) return true; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 9475b8a..964a2a7 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5206,16 +5206,36 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const auto *FD = dyn_cast_or_null<FunctionDecl>(D); bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate(); - if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) { + llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple(); + const LangOptions &LangOpts = S.getLangOpts(); + // OpenCL has its own error messages. + if (!LangOpts.OpenCL && FD && !FD->isExternallyVisible()) { + S.Diag(AL.getLoc(), diag::err_hidden_device_kernel) << FD; + AL.setInvalid(); + return; + } + if (Triple.isNVPTX()) { handleGlobalAttr(S, D, AL); } else { // OpenCL C++ will throw a more specific error. - if (!S.getLangOpts().OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) { + if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) { S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str) << AL << AL.isRegularKeywordAttribute() << "functions"; + AL.setInvalid(); + return; } handleSimpleAttribute<DeviceKernelAttr>(S, D, AL); } + // TODO: isGPU() should probably return true for SPIR. + bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() || + LangOpts.isTargetDevice() || LangOpts.OpenCL; + if (!TargetDeviceEnvironment) { + S.Diag(AL.getLoc(), diag::warn_cconv_unsupported) + << AL << (int)Sema::CallingConventionIgnoredReason::ForThisTarget; + AL.setInvalid(); + return; + } + // Make sure we validate the CC with the target // and warn/error if necessary. handleCallConvAttr(S, D, AL); diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 3bb8080..ee9b2b3 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2999,11 +2999,11 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( BinOp = BinaryOperatorKind::BO_LT; break; case OpenACCReductionOperator::And: + BinOp = BinaryOperatorKind::BO_LAnd; + break; case OpenACCReductionOperator::Or: - // We just want a 'NYI' error in the backend, so leave an empty combiner - // recipe, and claim success. - CombinerRecipes.push_back({nullptr, nullptr, nullptr}); - return false; + BinOp = BinaryOperatorKind::BO_LOr; + break; } // If VarTy is an array type, at the top level only, we want to do our @@ -3068,8 +3068,21 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( : CombinerFailureKind::Assignment}; } case OpenACCReductionOperator::And: - case OpenACCReductionOperator::Or: - llvm_unreachable("And/Or not implemented, but should fail earlier"); + case OpenACCReductionOperator::Or: { + // These are done as LHS = LHS && RHS (or LHS = LHS || RHS). So after the + // binop, all we have to do is the assignment. + if (!BinOpRes.isUsable()) + return {BinOpRes, CombinerFailureKind::BinOp}; + + // Build assignment. + ExprResult Assignment = SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, + BinaryOperatorKind::BO_Assign, + LHSDRE, BinOpRes.get(), + /*ForFoldExpr=*/false); + return {Assignment, Assignment.isUsable() + ? CombinerFailureKind::None + : CombinerFailureKind::Assignment}; + } case OpenACCReductionOperator::Invalid: llvm_unreachable("Invalid should have been caught above"); } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7c1fb12..280b3c9 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -134,7 +134,6 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr, case ParsedAttr::AT_VectorCall: \ case ParsedAttr::AT_AArch64VectorPcs: \ case ParsedAttr::AT_AArch64SVEPcs: \ - case ParsedAttr::AT_DeviceKernel: \ case ParsedAttr::AT_MSABI: \ case ParsedAttr::AT_SysVABI: \ case ParsedAttr::AT_Pcs: \ @@ -3786,7 +3785,8 @@ static CallingConv getCCForDeclaratorChunk( } } } - for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) { + for (const ParsedAttr &AL : llvm::concat<ParsedAttr>( + D.getDeclSpec().getAttributes(), D.getAttributes())) { if (AL.getKind() == ParsedAttr::AT_DeviceKernel) { CC = CC_DeviceKernel; break; @@ -7569,8 +7569,6 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) { return createSimpleAttr<AArch64SVEPcsAttr>(Ctx, Attr); case ParsedAttr::AT_ArmStreaming: return createSimpleAttr<ArmStreamingAttr>(Ctx, Attr); - case ParsedAttr::AT_DeviceKernel: - return createSimpleAttr<DeviceKernelAttr>(Ctx, Attr); case ParsedAttr::AT_Pcs: { // The attribute may have had a fixit applied where we treated an // identifier as a string literal. The contents of the string are valid, @@ -8809,16 +8807,6 @@ static void HandleHLSLParamModifierAttr(TypeProcessingState &State, } } -static bool isMultiSubjectAttrAllowedOnType(const ParsedAttr &Attr) { - // The DeviceKernel attribute is shared for many targets, and - // it is only allowed to be a type attribute with the AMDGPU - // spelling, so skip processing the attr as a type attr - // unless it has that spelling. - if (Attr.getKind() != ParsedAttr::AT_DeviceKernel) - return true; - return DeviceKernelAttr::isAMDGPUSpelling(Attr); -} - static void processTypeAttrs(TypeProcessingState &state, QualType &type, TypeAttrLocation TAL, const ParsedAttributesView &attrs, @@ -9072,8 +9060,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, break; [[fallthrough]]; FUNCTION_TYPE_ATTRS_CASELIST: - if (!isMultiSubjectAttrAllowedOnType(attr)) - break; attr.setUsedAsTypeAttr(); diff --git a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp index 5301f88..531c642b 100644 --- a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp @@ -93,6 +93,7 @@ void ModelInjector::onBodySynthesis(const NamedDecl *D) { // The instance wants to take ownership, however DisableFree frontend option // is set to true to avoid double free issues + Instance.setVirtualFileSystem(CI.getVirtualFileSystemPtr()); Instance.setFileManager(CI.getFileManagerPtr()); Instance.setSourceManager(SM); Instance.setPreprocessor(CI.getPreprocessorPtr()); diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index ea5a372..e8eef5e 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -446,6 +446,7 @@ bool FrontendActionFactory::runInvocation( DiagnosticConsumer *DiagConsumer) { // Create a compiler instance to handle the actual work. CompilerInstance Compiler(std::move(Invocation), std::move(PCHContainerOps)); + Compiler.setVirtualFileSystem(Files->getVirtualFileSystemPtr()); Compiler.setFileManager(Files); // The FrontendAction can have lifetime requirements for Compiler or its |