[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)
https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/130417 >From 1747df81cf0bf83838777a71ec577b083a66d85d Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Sat, 8 Mar 2025 21:50:19 +0800 Subject: [PATCH] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` Fixes: #119554 --- .../bugprone/OptionalValueConversionCheck.cpp | 14 ++ clang-tools-extra/docs/ReleaseNotes.rst| 4 ...ptional-value-conversion-construct-from-std.cpp | 13 + 3 files changed, 31 insertions(+) diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp index 33e823ac07490..cb5a1c7bea801 100644 --- a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp @@ -12,6 +12,7 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" #include using namespace clang::ast_matchers; @@ -31,6 +32,7 @@ constexpr std::array MakeSmartPtrList{ "::std::make_unique", "::std::make_shared", }; +constexpr StringRef MakeOptional = "::std::make_optional"; } // namespace @@ -86,6 +88,18 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { callee(functionDecl( matchers::matchesAnyListedName(MakeSmartPtrList), hasTemplateArgument(0, refersToType(BindOptionalType, + hasArgument(0, OptionalDerefMatcher)), + callExpr( + // match first std::make_optional by limit argument count (1) + // and template count (1). + // 1. template< class T > constexpr + //std::optional> make_optional(T&& value); + // 2. template< class T, class... Args > constexpr + //std::optional make_optional(Args&&... args); + argumentCountIs(1), + callee(functionDecl(templateArgumentCountIs(1), + hasName(MakeOptional), + returns(BindOptionalType))), hasArgument(0, OptionalDerefMatcher))), unless(anyOf(hasAncestor(typeLoc()), hasAncestor(expr(matchers::hasUnevaluatedContext()) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index ce1418a2a7d58..a726015a708f7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -115,6 +115,10 @@ Changes in existing checks no longer be needed and will be removed. Also fixing false positive from const reference accessors to objects containing optional member. +- Improved :doc:`bugprone-optional-value-conversion + ` check to detect + conversion in argument of ``std::make_optional``. + - Improved :doc:`bugprone-unsafe-functions ` check to allow specifying additional C++ member functions to match. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp index 768ab1ce014ce..305fd6890710d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp @@ -27,9 +27,19 @@ class unique_ptr {}; template class shared_ptr {}; +template +class initializer_list {}; + template unique_ptr make_unique(Args &&...args); template shared_ptr make_shared(Args &&...args); +template +constexpr std::optional<__decay(T)> make_optional(T &&value); +template +constexpr std::optional make_optional(Args &&...args); +template +constexpr std::optional make_optional(std::initializer_list il, Args &&...args); + } // namespace std struct A { @@ -45,9 +55,12 @@ void invalid() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] std::make_shared>(opt.value()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] + std::make_optional(opt.value()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] } void valid() { s
[llvm-branch-commits] [llvm] [AMDGPU] Deallocate VGPRs before exiting in dynamic VGPR mode (PR #130037)
https://github.com/arsenm approved this pull request. https://github.com/llvm/llvm-project/pull/130037 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] [sanitizer] add pseudofunction to indicate array-bounds check (PR #128977)
https://github.com/vitalybuka approved this pull request. https://github.com/llvm/llvm-project/pull/128977 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] [sanitizer] add pseudofunction to indicate array-bounds check (PR #128977)
@@ -355,12 +355,12 @@ class CGDebugInfo { llvm::ArrayRef PreviousFieldsDI, const RecordDecl *RD); /// A cache that maps names of artificial inlined functions to subprograms. - llvm::StringMap InlinedTrapFuncMap; + llvm::StringMap InlinedSubprogramMap; vitalybuka wrote: Can you rename in a separate NFC patch? https://github.com/llvm/llvm-project/pull/128977 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [AArch64] Fix BE popcount casts. (#129879) (PR #129996)
https://github.com/alexrp approved this pull request. https://github.com/llvm/llvm-project/pull/129996 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU] Support image_bvh8_intersect_ray instruction and intrinsic. (PR #130041)
https://github.com/mariusz-sikora-at-amd created https://github.com/llvm/llvm-project/pull/130041 None >From 2377e74544b379a34b1623df2269c3e173496994 Mon Sep 17 00:00:00 2001 From: Ivan Kosarev Date: Mon, 3 Mar 2025 05:34:48 -0500 Subject: [PATCH] [AMDGPU] Support image_bvh8_intersect_ray instruction and intrinsic. --- llvm/include/llvm/IR/IntrinsicsAMDGPU.td | 11 +++ .../AMDGPU/AMDGPUInstructionSelector.cpp | 1 + .../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 21 +++-- llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h | 3 +- .../Target/AMDGPU/AMDGPURegisterBankInfo.cpp | 18 ++-- llvm/lib/Target/AMDGPU/MIMGInstructions.td| 32 --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 16 ++-- llvm/lib/Target/AMDGPU/SIInstructions.td | 8 ++ .../AMDGPU/llvm.amdgcn.bvh8_intersect_ray.ll | 87 +++ llvm/test/MC/AMDGPU/gfx12_asm_vimage.s| 3 + llvm/test/MC/AMDGPU/gfx12_asm_vimage_alias.s | 3 + .../Disassembler/AMDGPU/gfx12_dasm_vimage.txt | 3 + 12 files changed, 171 insertions(+), 35 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.bvh8_intersect_ray.ll diff --git a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td index f93439b30523e..d0ce9f0b8322d 100644 --- a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td @@ -2812,6 +2812,17 @@ def int_amdgcn_image_bvh_dual_intersect_ray : llvm_v3f32_ty, llvm_v2i32_ty, llvm_v4i32_ty], [IntrReadMem, IntrWillReturn]>; +// , , +// llvm.amdgcn.image.bvh8.intersect.ray , , +//, , +//, , +// +def int_amdgcn_image_bvh8_intersect_ray : + Intrinsic<[llvm_v10i32_ty, llvm_v3f32_ty, llvm_v3f32_ty], +[llvm_i64_ty, llvm_float_ty, llvm_i8_ty, llvm_v3f32_ty, + llvm_v3f32_ty, llvm_i32_ty, llvm_v4i32_ty], +[IntrReadMem, IntrWillReturn]>; + // llvm.amdgcn.permlane16.var def int_amdgcn_permlane16_var : ClangBuiltin<"__builtin_amdgcn_permlane16_var">, Intrinsic<[llvm_i32_ty], diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp index 9c3bdd74a5cb0..8777a440c613b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -4090,6 +4090,7 @@ bool AMDGPUInstructionSelector::select(MachineInstr &I) { } case AMDGPU::G_AMDGPU_BVH_DUAL_INTERSECT_RAY: case AMDGPU::G_AMDGPU_BVH_INTERSECT_RAY: + case AMDGPU::G_AMDGPU_BVH8_INTERSECT_RAY: return selectBVHIntersectRayIntrinsic(I); case AMDGPU::G_SBFX: case AMDGPU::G_UBFX: diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp index cd0554a5c5b99..3e4c946ee9010 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -7183,8 +7183,8 @@ bool AMDGPULegalizerInfo::legalizeBVHIntersectRayIntrinsic( return true; } -bool AMDGPULegalizerInfo::legalizeBVHDualIntrinsic(MachineInstr &MI, - MachineIRBuilder &B) const { +bool AMDGPULegalizerInfo::legalizeBVHDualOrBVH8IntersectRayIntrinsic( +MachineInstr &MI, MachineIRBuilder &B) const { const LLT S32 = LLT::scalar(32); const LLT V2S32 = LLT::fixed_vector(2, 32); @@ -7207,11 +7207,14 @@ bool AMDGPULegalizerInfo::legalizeBVHDualIntrinsic(MachineInstr &MI, return false; } + bool IsBVH8 = cast(MI).getIntrinsicID() == +Intrinsic::amdgcn_image_bvh8_intersect_ray; const unsigned NumVDataDwords = 10; - const unsigned NumVAddrDwords = 12; - int Opcode = AMDGPU::getMIMGOpcode(AMDGPU::IMAGE_BVH_DUAL_INTERSECT_RAY, - AMDGPU::MIMGEncGfx12, NumVDataDwords, - NumVAddrDwords); + const unsigned NumVAddrDwords = IsBVH8 ? 11 : 12; + int Opcode = AMDGPU::getMIMGOpcode( + IsBVH8 ? AMDGPU::IMAGE_BVH8_INTERSECT_RAY + : AMDGPU::IMAGE_BVH_DUAL_INTERSECT_RAY, + AMDGPU::MIMGEncGfx12, NumVDataDwords, NumVAddrDwords); assert(Opcode != -1); SmallVector Ops; @@ -7223,7 +7226,8 @@ bool AMDGPULegalizerInfo::legalizeBVHDualIntrinsic(MachineInstr &MI, Ops.push_back(RayDir); Ops.push_back(Offsets); - auto MIB = B.buildInstr(AMDGPU::G_AMDGPU_BVH_DUAL_INTERSECT_RAY) + auto MIB = B.buildInstr(IsBVH8 ? AMDGPU::G_AMDGPU_BVH8_INTERSECT_RAY + : AMDGPU::G_AMDGPU_BVH_DUAL_INTERSECT_RAY) .addDef(DstReg) .addDef(DstOrigin) .addDef(DstDir) @@ -7587,7 +7591,8 @@ bool AMDGPULegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, case Intrinsic::amdgcn_image_bvh_intersect_ray: return legalizeBVHIntersectRayIntrinsic(MI, B); case Intrinsic::a
[llvm-branch-commits] [flang] Reland " [flang] Rely on global initialization for simpler derived types" (PR #130290)
llvmbot wrote: @llvm/pr-subscribers-flang-openmp Author: None (jeanPerier) Changes Reland #114002 with an implementation of the FIXME that should solve the regressions that have been seen. The first commit is the original PR, the second is the fix. --- Patch is 42.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130290.diff 9 Files Affected: - (modified) flang/include/flang/Optimizer/Support/InternalNames.h (+1) - (modified) flang/lib/Lower/ConvertVariable.cpp (+60-2) - (modified) flang/test/Lower/HLFIR/structure-constructor.f90 (+14-42) - (modified) flang/test/Lower/OpenMP/private-derived-type.f90 (+5-9) - (modified) flang/test/Lower/default-initialization.f90 (+17-24) - (modified) flang/test/Lower/derived-type-finalization.f90 (+6-2) - (modified) flang/test/Lower/derived-type-temp.f90 (+5-5) - (modified) flang/test/Lower/forall/forall-allocatable-2.f90 (+2-6) - (modified) flang/test/Lower/pointer-default-init.f90 (+3-1) ``diff diff --git a/flang/include/flang/Optimizer/Support/InternalNames.h b/flang/include/flang/Optimizer/Support/InternalNames.h index 41f2cb9842dc7..62375ab8f9de3 100644 --- a/flang/include/flang/Optimizer/Support/InternalNames.h +++ b/flang/include/flang/Optimizer/Support/InternalNames.h @@ -30,6 +30,7 @@ static constexpr llvm::StringRef kProcPtrSeparator = ".p."; static constexpr llvm::StringRef kSpecialBindingSeparator = ".s."; static constexpr llvm::StringRef kBindingTableSeparator = ".v."; static constexpr llvm::StringRef boxprocSuffix = "UnboxProc"; +static constexpr llvm::StringRef kDerivedTypeInitSuffix = "DerivedInit"; /// Internal name mangling of identifiers /// diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 48f7b9f99e960..b11251ecabf05 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -798,8 +798,66 @@ void Fortran::lower::defaultInitializeAtRuntime( }) .end(); } else { -mlir::Value box = builder.createBox(loc, exv); -fir::runtime::genDerivedTypeInitialize(builder, loc, box); +/// For "simpler" types, relying on "_FortranAInitialize" +/// leads to poor runtime performance. Hence optimize +/// the same. +const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType(); +mlir::Type symTy = converter.genType(sym); +const auto *details = +sym.detailsIf(); +if (details && !Fortran::semantics::IsPolymorphic(sym) && +declTy->category() == +Fortran::semantics::DeclTypeSpec::Category::TypeDerived && +!mlir::isa(symTy) && +!sym.test(Fortran::semantics::Symbol::Flag::OmpPrivate) && +!sym.test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate)) { + std::string globalName = fir::NameUniquer::doGenerated( + (converter.mangleName(*declTy->AsDerived()) + fir::kNameSeparator + + fir::kDerivedTypeInitSuffix) + .str()); + mlir::Location loc = genLocation(converter, sym); + mlir::StringAttr linkage = builder.createInternalLinkage(); + fir::GlobalOp global = builder.getNamedGlobal(globalName); + if (!global && details->init()) { +global = builder.createGlobal(loc, symTy, globalName, linkage, + mlir::Attribute{}, + /*isConst=*/true, + /*isTarget=*/false, + /*dataAttr=*/{}); +Fortran::lower::createGlobalInitialization( +builder, global, [&](fir::FirOpBuilder &builder) { + Fortran::lower::StatementContext stmtCtx( + /*cleanupProhibited=*/true); + fir::ExtendedValue initVal = genInitializerExprValue( + converter, loc, details->init().value(), stmtCtx); + mlir::Value castTo = + builder.createConvert(loc, symTy, fir::getBase(initVal)); + builder.create(loc, castTo); +}); + } else if (!global) { +global = builder.createGlobal(loc, symTy, globalName, linkage, + mlir::Attribute{}, + /*isConst=*/true, + /*isTarget=*/false, + /*dataAttr=*/{}); +Fortran::lower::createGlobalInitialization( +builder, global, [&](fir::FirOpBuilder &builder) { + Fortran::lower::StatementContext stmtCtx( + /*cleanupProhibited=*/true); + mlir::Value initVal = genDefaultInitializerValue( + converter, loc, sym, symTy, stmtCtx); + mlir::Value castTo = builder.createConvert(loc, symTy, initVal); + builder.create(loc, castTo); +}); + } + auto addrOf = builder.create(loc, global.resultType(), +
[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Temporal divergence lowering (non i1) (PR #124298)
https://github.com/petar-avramovic updated https://github.com/llvm/llvm-project/pull/124298 >From f084882197a92f537c38ec19dfabdafdd9f15d09 Mon Sep 17 00:00:00 2001 From: Petar Avramovic Date: Fri, 28 Feb 2025 15:56:04 +0100 Subject: [PATCH] AMDGPU/GlobalISel: Temporal divergence lowering (non i1) Record all uses outside cycle with divergent exit during propagateTemporalDivergence in Uniformity analysis. With this list of candidates for temporal divergence lowering, excluding known lane masks from control flow intrinsics, find sources from inside the cycle that are not i1 and uniform. Temporal divergence lowering (non i1): create copy(v_mov) to vgpr, with implicit exec (to stop other passes from moving this copy outside of the cycle) and use this vgpr outside of the cycle instead of original uniform source. --- llvm/include/llvm/ADT/GenericUniformityImpl.h | 44 +++- llvm/include/llvm/ADT/GenericUniformityInfo.h | 5 ++ llvm/lib/Analysis/UniformityAnalysis.cpp | 3 +- .../lib/CodeGen/MachineUniformityAnalysis.cpp | 6 +-- .../AMDGPUGlobalISelDivergenceLowering.cpp| 52 ++- .../lib/Target/AMDGPU/AMDGPURegBankSelect.cpp | 25 +++-- llvm/lib/Target/AMDGPU/SILowerI1Copies.h | 6 +++ ...divergent-i1-phis-no-lane-mask-merging.mir | 7 +-- ...ergence-divergent-i1-used-outside-loop.mir | 19 +++ .../divergence-temporal-divergent-reg.ll | 38 +++--- .../divergence-temporal-divergent-reg.mir | 8 +-- .../AMDGPU/GlobalISel/regbankselect-mui.ll| 17 +++--- 12 files changed, 176 insertions(+), 54 deletions(-) diff --git a/llvm/include/llvm/ADT/GenericUniformityImpl.h b/llvm/include/llvm/ADT/GenericUniformityImpl.h index bd09f4fe43e08..51e9ac30391fe 100644 --- a/llvm/include/llvm/ADT/GenericUniformityImpl.h +++ b/llvm/include/llvm/ADT/GenericUniformityImpl.h @@ -51,6 +51,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SparseBitVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/Support/raw_ostream.h" #define DEBUG_TYPE "uniformity" @@ -342,6 +343,9 @@ template class GenericUniformityAnalysisImpl { typename SyncDependenceAnalysisT::DivergenceDescriptor; using BlockLabelMapT = typename SyncDependenceAnalysisT::BlockLabelMap; + using TemporalDivergenceTuple = + std::tuple; + GenericUniformityAnalysisImpl(const DominatorTreeT &DT, const CycleInfoT &CI, const TargetTransformInfo *TTI) : Context(CI.getSSAContext()), F(*Context.getFunction()), CI(CI), @@ -396,6 +400,11 @@ template class GenericUniformityAnalysisImpl { void print(raw_ostream &out) const; + SmallVector TemporalDivergenceList; + + void recordTemporalDivergence(ConstValueRefT, const InstructionT *, +const CycleT *); + protected: /// \brief Value/block pair representing a single phi input. struct PhiInput { @@ -1129,6 +1138,13 @@ void GenericUniformityAnalysisImpl::compute() { } } +template +void GenericUniformityAnalysisImpl::recordTemporalDivergence( +ConstValueRefT Val, const InstructionT *User, const CycleT *Cycle) { + TemporalDivergenceList.emplace_back(Val, const_cast(User), + Cycle); +} + template bool GenericUniformityAnalysisImpl::isAlwaysUniform( const InstructionT &Instr) const { @@ -1146,6 +1162,12 @@ template void GenericUniformityAnalysisImpl::print(raw_ostream &OS) const { bool haveDivergentArgs = false; + // When we print Value, LLVM IR instruction, we want to print extra new line. + // In LLVM IR print function for Value does not print new line at the end. + // In MIR print for MachineInstr prints new line at the end. + constexpr bool IsMIR = std::is_same::value; + std::string NewLine = IsMIR ? "" : "\n"; + // Control flow instructions may be divergent even if their inputs are // uniform. Thus, although exceedingly rare, it is possible to have a program // with no divergent values but with divergent control structures. @@ -1180,6 +1202,16 @@ void GenericUniformityAnalysisImpl::print(raw_ostream &OS) const { } } + if (!TemporalDivergenceList.empty()) { +OS << "\nTEMPORAL DIVERGENCE LIST:\n"; + +for (auto [Val, UseInst, Cycle] : TemporalDivergenceList) { + OS << "Value :" << Context.print(Val) << NewLine + << "Used by :" << Context.print(UseInst) << NewLine + << "Outside cycle :" << Cycle->print(Context) << "\n\n"; +} + } + for (auto &block : F) { OS << "\nBLOCK " << Context.print(&block) << '\n'; @@ -1191,7 +1223,7 @@ void GenericUniformityAnalysisImpl::print(raw_ostream &OS) const { OS << " DIVERGENT: "; else OS << " "; - OS << Context.print(value) << '\n'; + OS << Context.print(value) << NewLine; } OS << "TERMINATORS\n"; @@ -1203,13 +1235,21 @@ void GenericUniformityAnalysisImpl::prin
[llvm-branch-commits] [clang] [CUDA][HIP] fix virtual dtor host/device attr (#128926) (PR #130126)
https://github.com/yxsamliu created https://github.com/llvm/llvm-project/pull/130126 When inferring host device attr of virtual dtor of explicit template class instantiation, clang should be conservative. This guarantees dtors that may call host functions not to have implicit device attr, therefore will not be emitted on device side. Backports: 0f0665db067f d37a39207bc1 Fixes: #108548 >From 604bf957fa8a8932e5163d8b10ed910d9a944382 Mon Sep 17 00:00:00 2001 From: "Yaxun (Sam) Liu" Date: Fri, 28 Feb 2025 09:58:19 -0500 Subject: [PATCH] [CUDA][HIP] fix virtual dtor host/device attr (#128926) When inferring host device attr of virtual dtor of explicit template class instantiation, clang should be conservative. This guarantees dtors that may call host functions not to have implicit device attr, therefore will not be emitted on device side. Backports: 0f0665db067f d37a39207bc1 Fixes: #108548 --- clang/docs/HIPSupport.rst | 20 ++ clang/include/clang/Sema/Sema.h | 2 +- clang/lib/Sema/Sema.cpp | 43 + clang/lib/Sema/SemaCUDA.cpp | 23 ++- clang/lib/Sema/SemaDecl.cpp | 15 + clang/test/SemaCUDA/dtor.cu | 104 6 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCUDA/dtor.cu diff --git a/clang/docs/HIPSupport.rst b/clang/docs/HIPSupport.rst index 481ed39230813..8f473c21e1918 100644 --- a/clang/docs/HIPSupport.rst +++ b/clang/docs/HIPSupport.rst @@ -286,6 +286,26 @@ Example Usage basePtr->virtualFunction(); // Allowed since obj is constructed in device code } +Host and Device Attributes of Default Destructors +=== + +If a default destructor does not have explicit host or device attributes, +clang infers these attributes based on the destructors of its data members +and base classes. If any conflicts are detected among these destructors, +clang diagnoses the issue. Otherwise, clang adds an implicit host or device +attribute according to whether the data members's and base classes's +destructors can execute on the host or device side. + +For explicit template classes with virtual destructors, which must be emitted, +the inference adopts a conservative approach. In this case, implicit host or +device attributes from member and base class destructors are ignored. This +precaution is necessary because, although a constexpr destructor carries +implicit host or device attributes, a constexpr function may call a +non-constexpr function, which is by default a host function. + +Users can override the inferred host and device attributes of default +destructors by adding explicit host and device attributes to them. + C++ Standard Parallelism Offload Support: Compiler And Runtime == diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a30a7076ea5d4..af648d7f9c63f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4336,11 +4336,11 @@ class Sema final : public SemaBase { // Whether the callee should be ignored in CUDA/HIP/OpenMP host/device check. bool shouldIgnoreInHostDeviceCheck(FunctionDecl *Callee); -private: /// Function or variable declarations to be checked for whether the deferred /// diagnostics should be emitted. llvm::SmallSetVector DeclsToCheckForDeferredDiags; +private: /// Map of current shadowing declarations to shadowed declarations. Warn if /// it looks like the user is trying to modify the shadowing declaration. llvm::DenseMap ShadowingDecls; diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 9507d7602aa40..e0eac690e6e65 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1789,6 +1789,47 @@ class DeferredDiagnosticsEmitter Inherited::visitUsedDecl(Loc, D); } + // Visitor member and parent dtors called by this dtor. + void VisitCalledDestructors(CXXDestructorDecl *DD) { +const CXXRecordDecl *RD = DD->getParent(); + +// Visit the dtors of all members +for (const FieldDecl *FD : RD->fields()) { + QualType FT = FD->getType(); + if (const auto *RT = FT->getAs()) +if (const auto *ClassDecl = dyn_cast(RT->getDecl())) + if (ClassDecl->hasDefinition()) +if (CXXDestructorDecl *MemberDtor = ClassDecl->getDestructor()) + asImpl().visitUsedDecl(MemberDtor->getLocation(), MemberDtor); +} + +// Also visit base class dtors +for (const auto &Base : RD->bases()) { + QualType BaseType = Base.getType(); + if (const auto *RT = BaseType->getAs()) +if (const auto *BaseDecl = dyn_cast(RT->getDecl())) + if (BaseDecl->hasDefinition()) +if (CXXDestructorDecl *BaseDtor = BaseDecl->getDestructor()) + asImpl().visitUsedDecl(BaseDtor->getLocation(), BaseDtor); +} + } + + void VisitDeclStmt(DeclStmt *DS) { +
[llvm-branch-commits] [llvm] obj2yaml: Introduce CovMap dump (PR #127432)
https://github.com/chapuni updated https://github.com/llvm/llvm-project/pull/127432 >From 7e29d6ace39058b631dcfff5533d8aee055de6dd Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 3 Mar 2025 12:25:13 +0900 Subject: [PATCH] obj2yaml --- llvm/include/llvm/ObjectYAML/CovMap.h | 47 ++- llvm/include/llvm/ProfileData/InstrProf.h | 6 + llvm/lib/ObjectYAML/CovMap.cpp | 377 +++- llvm/lib/ProfileData/InstrProf.cpp | 23 +- llvm/test/tools/obj2yaml/ELF/covmap-be.yaml | 2 + llvm/test/tools/obj2yaml/ELF/covmap.yaml| 2 + llvm/tools/obj2yaml/elf2yaml.cpp| 59 ++- llvm/tools/obj2yaml/obj2yaml.cpp| 2 +- llvm/tools/obj2yaml/obj2yaml.h | 4 + 9 files changed, 512 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h index 3a0b86435d490..406204ee024fb 100644 --- a/llvm/include/llvm/ObjectYAML/CovMap.h +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -16,7 +16,7 @@ // // - llvm::covmap // -// Provides YAML encoder for coverage map. +// Provides YAML encoder and decoder for coverage map. // //===--===// @@ -27,6 +27,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" #include "llvm/Support/YAMLTraits.h" #include #include @@ -41,6 +42,8 @@ class raw_ostream; namespace llvm::coverage::yaml { +struct DecoderContext; + /// Base Counter, corresponding to coverage::Counter. struct CounterTy { enum TagTy : uint8_t { @@ -65,6 +68,12 @@ struct CounterTy { virtual void mapping(llvm::yaml::IO &IO); + /// Holds Val for extensions. + Error decodeOrTag(DecoderContext &Data); + + /// Raise Error if Val isn't empty. + Error decode(DecoderContext &Data); + void encode(raw_ostream &OS) const; }; @@ -85,6 +94,8 @@ struct DecisionTy { void mapping(llvm::yaml::IO &IO); + Error decode(DecoderContext &Data); + void encode(raw_ostream &OS) const; }; @@ -118,6 +129,8 @@ struct RecTy : CounterTy { void mapping(llvm::yaml::IO &IO) override; + Error decode(DecoderContext &Data); + void encode(uint64_t &StartLoc, raw_ostream &OS) const; }; @@ -142,6 +155,10 @@ struct CovFunTy { void mapping(llvm::yaml::IO &IO); + /// Depends on CovMap and SymTab(IPSK_names) + Expected decode(const ArrayRef Content, uint64_t Offset, +endianness Endianness); + void encode(raw_ostream &OS, endianness Endianness) const; }; @@ -170,6 +187,9 @@ struct CovMapTy { bool useWD() const { return (!Version || *Version >= 4); } StringRef getWD() const { return (WD ? *WD : StringRef()); } + Expected decode(const ArrayRef Content, uint64_t Offset, +endianness Endianness); + /// Generate Accumulated list with WD. /// Returns a single element {WD} if AccFiles is not given. std::vector @@ -236,6 +256,31 @@ LLVM_COVERAGE_YAML_ELEM_MAPPING(CovMapTy) namespace llvm::covmap { +class Decoder { +protected: + endianness Endianness; + +public: + Decoder(endianness Endianness) : Endianness(Endianness) {} + virtual ~Decoder() {} + + /// Returns DecoderImpl. + static std::unique_ptr get(endianness Endianness, + bool CovMapEnabled); + + /// Called from the Sections loop in advance of the final dump. + /// Decoder predecodes CovMap for Version info. + virtual Error acquire(unsigned AddressAlign, StringRef Name, +ArrayRef Content) = 0; + + /// Make contents on ELFYAML object. CovMap is predecoded. + virtual Error make(ELFYAML::CovMapSectionBase *Base, + ArrayRef Content) = 0; + + /// Suppress emission of CovMap unless enabled. + static bool enabled; +}; + class Encoder { protected: endianness Endianness; diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 7133c0c6a302c..e20424da3cac2 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -545,6 +545,12 @@ class InstrProfSymtab { /// This method is a wrapper to \c readAndDecodeStrings method. Error create(StringRef NameStrings); + // PrfNames is nested array. + using PrfNamesTy = SmallVector; + using PrfNamesChunksTy = SmallVector; + + Expected createAndGetList(ArrayRef Content); + /// Initialize symtab states with function names and vtable names. \c /// FuncNameStrings is a string composed of one or more encoded function name /// strings, and \c VTableNameStrings composes of one or more encoded vtable diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp index 7662284caee76..dcf90f7b109cb 100644 --- a/llvm/lib/ObjectYAML/CovMap.cpp +++ b/llvm/lib/ObjectYAML/CovMap.cpp @@ -6,7 +6,7 @@ // //===--
[llvm-branch-commits] [libcxx] [libc++][CI] Update action runner base image. (PR #130433)
llvmbot wrote: @llvm/pr-subscribers-libcxx Author: Mark de Wever (mordante) Changes Updates to the latest release. The side effect of this change is updating all compilers to the latest upstream version. --- Full diff: https://github.com/llvm/llvm-project/pull/130433.diff 1 Files Affected: - (modified) libcxx/utils/ci/docker-compose.yml (+1-1) ``diff diff --git a/libcxx/utils/ci/docker-compose.yml b/libcxx/utils/ci/docker-compose.yml index 16db1b0e3acb3..68e89db5cf452 100644 --- a/libcxx/utils/ci/docker-compose.yml +++ b/libcxx/utils/ci/docker-compose.yml @@ -10,7 +10,7 @@ services: dockerfile: Dockerfile target: actions-builder args: -BASE_IMAGE: ghcr.io/actions/actions-runner:2.319.1 +BASE_IMAGE: ghcr.io/actions/actions-runner:2.322.0 <<: *compiler_versions android-buildkite-builder: `` https://github.com/llvm/llvm-project/pull/130433 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++][CI] Update action runner base image. (PR #130433)
https://github.com/mordante created https://github.com/llvm/llvm-project/pull/130433 Updates to the latest release. The side effect of this change is updating all compilers to the latest upstream version. >From 02c75830fe16e7de91d8406d9422575bc560fac2 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Sat, 8 Mar 2025 20:26:32 +0100 Subject: [PATCH] [libc++][CI] Update action runner base image. Updates to the latest release. The side effect of this change is updating all compilers to the latest upstream version. --- libcxx/utils/ci/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/utils/ci/docker-compose.yml b/libcxx/utils/ci/docker-compose.yml index 16db1b0e3acb3..68e89db5cf452 100644 --- a/libcxx/utils/ci/docker-compose.yml +++ b/libcxx/utils/ci/docker-compose.yml @@ -10,7 +10,7 @@ services: dockerfile: Dockerfile target: actions-builder args: -BASE_IMAGE: ghcr.io/actions/actions-runner:2.319.1 +BASE_IMAGE: ghcr.io/actions/actions-runner:2.322.0 <<: *compiler_versions android-buildkite-builder: ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.copy` (PR #130437)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/130437 Implement runtime op verification for `memref.copy`. Only ranked memrefs are verified at the moment. >From 7bb852c420fb718eec9198ec3659fbcd1221ca33 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Sat, 8 Mar 2025 21:34:30 +0100 Subject: [PATCH] [mlir][memref] Add runtime verification for `memref.copy` --- .../Transforms/RuntimeOpVerification.cpp | 48 +++ .../MemRef/copy-runtime-verification.mlir | 28 +++ 2 files changed, 76 insertions(+) create mode 100644 mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index ceea27a35a225..c604af249ba2e 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -182,6 +182,53 @@ struct CastOpInterface } }; +struct CopyOpInterface +: public RuntimeVerifiableOpInterface::ExternalModel { + void generateRuntimeVerification(Operation *op, OpBuilder &builder, + Location loc) const { +auto copyOp = cast(op); +BaseMemRefType sourceType = copyOp.getSource().getType(); +BaseMemRefType targetType = copyOp.getTarget().getType(); +auto rankedSourceType = dyn_cast(sourceType); +auto rankedTargetType = dyn_cast(targetType); + +// TODO: Verification for unranked memrefs is not supported yet. +if (!rankedSourceType || !rankedTargetType) + return; + +assert(sourceType.getRank() == targetType.getRank() && "rank mismatch"); +for (int64_t i = 0, e = sourceType.getRank(); i < e; ++i) { + // Fully static dimensions in both source and target operand are already + // verified by the op verifier. + if (!rankedSourceType.isDynamicDim(i) && + !rankedTargetType.isDynamicDim(i)) +continue; + Value sourceDim; + if (rankedSourceType.isDynamicDim(i)) { +sourceDim = builder.create(loc, copyOp.getSource(), i); + } else { +sourceDim = builder.create( +loc, rankedSourceType.getDimSize(i)); + } + Value targetDim; + if (rankedTargetType.isDynamicDim(i)) { +targetDim = builder.create(loc, copyOp.getTarget(), i); + } else { +targetDim = builder.create( +loc, rankedTargetType.getDimSize(i)); + } + Value sameDimSize = builder.create( + loc, arith::CmpIPredicate::eq, sourceDim, targetDim); + builder.create( + loc, sameDimSize, + RuntimeVerifiableOpInterface::generateErrorMessage( + op, "size of " + std::to_string(i) + + "-th source/target dim does not match")); +} + } +}; + struct DimOpInterface : public RuntimeVerifiableOpInterface::ExternalModel { @@ -383,6 +430,7 @@ void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( AssumeAlignmentOp::attachInterface(*ctx); AtomicRMWOp::attachInterface>(*ctx); CastOp::attachInterface(*ctx); +CopyOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); GenericAtomicRMWOp::attachInterface< diff --git a/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir new file mode 100644 index 0..95b9db2832cee --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir @@ -0,0 +1,28 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -expand-strided-metadata \ +// RUN: -test-cf-assert \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +// Put memref.copy in a function, otherwise the memref.cast may fold. +func.func @memcpy_helper(%src: memref, %dest: memref) { + memref.copy %src, %dest : memref to memref + return +} + +func.func @main() { + %alloca1 = memref.alloca() : memref<4xf32> + %alloca2 = memref.alloca() : memref<5xf32> + %cast1 = memref.cast %alloca1 : memref<4xf32> to memref + %cast2 = memref.cast %alloca2 : memref<5xf32> to memref + + // CHECK: ERROR: Runtime op verification failed + // CHECK-NEXT: "memref.copy"(%{{.*}}, %{{.*}}) : (memref, memref) -> () + // CHECK-NEXT: ^ size of 0-th source/target dim does not match + // CHECK-NEXT: Location: loc({{.*}}) + call @memcpy_helper(%cast1, %cast2) : (memref, memref) -> () + + return +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.copy` (PR #130437)
llvmbot wrote: @llvm/pr-subscribers-mlir-memref Author: Matthias Springer (matthias-springer) Changes Implement runtime op verification for `memref.copy`. Only ranked memrefs are verified at the moment. --- Full diff: https://github.com/llvm/llvm-project/pull/130437.diff 2 Files Affected: - (modified) mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp (+48) - (added) mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir (+28) ``diff diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index ceea27a35a225..c604af249ba2e 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -182,6 +182,53 @@ struct CastOpInterface } }; +struct CopyOpInterface +: public RuntimeVerifiableOpInterface::ExternalModel { + void generateRuntimeVerification(Operation *op, OpBuilder &builder, + Location loc) const { +auto copyOp = cast(op); +BaseMemRefType sourceType = copyOp.getSource().getType(); +BaseMemRefType targetType = copyOp.getTarget().getType(); +auto rankedSourceType = dyn_cast(sourceType); +auto rankedTargetType = dyn_cast(targetType); + +// TODO: Verification for unranked memrefs is not supported yet. +if (!rankedSourceType || !rankedTargetType) + return; + +assert(sourceType.getRank() == targetType.getRank() && "rank mismatch"); +for (int64_t i = 0, e = sourceType.getRank(); i < e; ++i) { + // Fully static dimensions in both source and target operand are already + // verified by the op verifier. + if (!rankedSourceType.isDynamicDim(i) && + !rankedTargetType.isDynamicDim(i)) +continue; + Value sourceDim; + if (rankedSourceType.isDynamicDim(i)) { +sourceDim = builder.create(loc, copyOp.getSource(), i); + } else { +sourceDim = builder.create( +loc, rankedSourceType.getDimSize(i)); + } + Value targetDim; + if (rankedTargetType.isDynamicDim(i)) { +targetDim = builder.create(loc, copyOp.getTarget(), i); + } else { +targetDim = builder.create( +loc, rankedTargetType.getDimSize(i)); + } + Value sameDimSize = builder.create( + loc, arith::CmpIPredicate::eq, sourceDim, targetDim); + builder.create( + loc, sameDimSize, + RuntimeVerifiableOpInterface::generateErrorMessage( + op, "size of " + std::to_string(i) + + "-th source/target dim does not match")); +} + } +}; + struct DimOpInterface : public RuntimeVerifiableOpInterface::ExternalModel { @@ -383,6 +430,7 @@ void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( AssumeAlignmentOp::attachInterface(*ctx); AtomicRMWOp::attachInterface>(*ctx); CastOp::attachInterface(*ctx); +CopyOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); GenericAtomicRMWOp::attachInterface< diff --git a/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir new file mode 100644 index 0..95b9db2832cee --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir @@ -0,0 +1,28 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -expand-strided-metadata \ +// RUN: -test-cf-assert \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +// Put memref.copy in a function, otherwise the memref.cast may fold. +func.func @memcpy_helper(%src: memref, %dest: memref) { + memref.copy %src, %dest : memref to memref + return +} + +func.func @main() { + %alloca1 = memref.alloca() : memref<4xf32> + %alloca2 = memref.alloca() : memref<5xf32> + %cast1 = memref.cast %alloca1 : memref<4xf32> to memref + %cast2 = memref.cast %alloca2 : memref<5xf32> to memref + + // CHECK: ERROR: Runtime op verification failed + // CHECK-NEXT: "memref.copy"(%{{.*}}, %{{.*}}) : (memref, memref) -> () + // CHECK-NEXT: ^ size of 0-th source/target dim does not match + // CHECK-NEXT: Location: loc({{.*}}) + call @memcpy_helper(%cast1, %cast2) : (memref, memref) -> () + + return +} `` https://github.com/llvm/llvm-project/pull/130437 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add Metadata generation of Root Signatures for Attr (PR #125131)
@@ -0,0 +1,108 @@ +//===- HLSLRootSignature.cpp - HLSL Root Signature helper objects +//--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +/// +/// \file This file contains helpers for working with HLSL Root Signatures. +/// +//===--===// + +#include "llvm/Frontend/HLSL/HLSLRootSignature.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" + +namespace llvm { +namespace hlsl { +namespace rootsig { + +// Static helper functions + +static MDString *ClauseTypeToName(LLVMContext &Ctx, ClauseType Type) { + StringRef Name; + switch (Type) { + case ClauseType::CBuffer: +Name = "CBV"; +break; + case ClauseType::SRV: +Name = "SRV"; +break; + case ClauseType::UAV: +Name = "UAV"; +break; + case ClauseType::Sampler: +Name = "Sampler"; +break; + } + return MDString::get(Ctx, Name); +} + +// Helper struct so that we can use the overloaded notation of std::visit +template struct OverloadBuilds : Ts... { + using Ts::operator()...; +}; +template OverloadBuilds(Ts...) -> OverloadBuilds; + +MDNode *MetadataBuilder::BuildRootSignature() { + for (const RootElement &Element : Elements) { +MDNode *ElementMD = +std::visit(OverloadBuilds{ + [&](DescriptorTable Table) -> MDNode * { + return BuildDescriptorTable(Table); + }, + [&](DescriptorTableClause Clause) -> MDNode * { + return BuildDescriptorTableClause(Clause); + }, + }, + Element); +GeneratedMetadata.push_back(ElementMD); + } + + return MDNode::get(Ctx, GeneratedMetadata); +} + +MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) { + IRBuilder<> B(Ctx); + SmallVector TableOperands; + // Set the mandatory arguments + TableOperands.push_back(MDString::get(Ctx, "DescriptorTable")); + TableOperands.push_back(ConstantAsMetadata::get( + B.getInt32(llvm::to_underlying(Table.Visibility; + + // Remaining operands are references to the table's clauses. The in-memory + // representation of the Root Elements created from parsing will ensure that + // the previous N elements are the clauses for this table. + assert(Table.NumClauses <= GeneratedMetadata.size() && + "Table expected all owned clauses to be generated already"); + // So, add a refence to each clause to our operands + TableOperands.append(GeneratedMetadata.end() - Table.NumClauses, + GeneratedMetadata.end()); + // Then, remove those clauses from the general list of Root Elements + GeneratedMetadata.pop_back_n(Table.NumClauses); + + return MDNode::get(Ctx, TableOperands); +} + +MDNode *MetadataBuilder::BuildDescriptorTableClause( +const DescriptorTableClause &Clause) { + IRBuilder<> B(Ctx); + return MDNode::get( + Ctx, { + ClauseTypeToName(Ctx, Clause.Type), + ConstantAsMetadata::get(B.getInt32(Clause.NumDescriptors)), + ConstantAsMetadata::get(B.getInt32(Clause.Register.Number)), + ConstantAsMetadata::get(B.getInt32(Clause.Space)), + ConstantAsMetadata::get( joaosaffran wrote: Those seem like the binary representation for Descriptor Table, not their HLSL representation. The offset, specifically, seems the kind of field that should be calculated by the backend when serializing it. https://github.com/llvm/llvm-project/pull/125131 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.copy` (PR #130437)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes Implement runtime op verification for `memref.copy`. Only ranked memrefs are verified at the moment. --- Full diff: https://github.com/llvm/llvm-project/pull/130437.diff 2 Files Affected: - (modified) mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp (+48) - (added) mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir (+28) ``diff diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index ceea27a35a225..c604af249ba2e 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -182,6 +182,53 @@ struct CastOpInterface } }; +struct CopyOpInterface +: public RuntimeVerifiableOpInterface::ExternalModel { + void generateRuntimeVerification(Operation *op, OpBuilder &builder, + Location loc) const { +auto copyOp = cast(op); +BaseMemRefType sourceType = copyOp.getSource().getType(); +BaseMemRefType targetType = copyOp.getTarget().getType(); +auto rankedSourceType = dyn_cast(sourceType); +auto rankedTargetType = dyn_cast(targetType); + +// TODO: Verification for unranked memrefs is not supported yet. +if (!rankedSourceType || !rankedTargetType) + return; + +assert(sourceType.getRank() == targetType.getRank() && "rank mismatch"); +for (int64_t i = 0, e = sourceType.getRank(); i < e; ++i) { + // Fully static dimensions in both source and target operand are already + // verified by the op verifier. + if (!rankedSourceType.isDynamicDim(i) && + !rankedTargetType.isDynamicDim(i)) +continue; + Value sourceDim; + if (rankedSourceType.isDynamicDim(i)) { +sourceDim = builder.create(loc, copyOp.getSource(), i); + } else { +sourceDim = builder.create( +loc, rankedSourceType.getDimSize(i)); + } + Value targetDim; + if (rankedTargetType.isDynamicDim(i)) { +targetDim = builder.create(loc, copyOp.getTarget(), i); + } else { +targetDim = builder.create( +loc, rankedTargetType.getDimSize(i)); + } + Value sameDimSize = builder.create( + loc, arith::CmpIPredicate::eq, sourceDim, targetDim); + builder.create( + loc, sameDimSize, + RuntimeVerifiableOpInterface::generateErrorMessage( + op, "size of " + std::to_string(i) + + "-th source/target dim does not match")); +} + } +}; + struct DimOpInterface : public RuntimeVerifiableOpInterface::ExternalModel { @@ -383,6 +430,7 @@ void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( AssumeAlignmentOp::attachInterface(*ctx); AtomicRMWOp::attachInterface>(*ctx); CastOp::attachInterface(*ctx); +CopyOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); GenericAtomicRMWOp::attachInterface< diff --git a/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir new file mode 100644 index 0..95b9db2832cee --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/copy-runtime-verification.mlir @@ -0,0 +1,28 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -expand-strided-metadata \ +// RUN: -test-cf-assert \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +// Put memref.copy in a function, otherwise the memref.cast may fold. +func.func @memcpy_helper(%src: memref, %dest: memref) { + memref.copy %src, %dest : memref to memref + return +} + +func.func @main() { + %alloca1 = memref.alloca() : memref<4xf32> + %alloca2 = memref.alloca() : memref<5xf32> + %cast1 = memref.cast %alloca1 : memref<4xf32> to memref + %cast2 = memref.cast %alloca2 : memref<5xf32> to memref + + // CHECK: ERROR: Runtime op verification failed + // CHECK-NEXT: "memref.copy"(%{{.*}}, %{{.*}}) : (memref, memref) -> () + // CHECK-NEXT: ^ size of 0-th source/target dim does not match + // CHECK-NEXT: Location: loc({{.*}}) + call @memcpy_helper(%cast1, %cast2) : (memref, memref) -> () + + return +} `` https://github.com/llvm/llvm-project/pull/130437 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.atomic_rmw` (PR #130414)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/130414 Implement runtime verification for `memref.atomic_rmw` and `memref.generic_atomic_rmw`. >From c37848a198f4abac8bfdd20cf9a687263f8a8241 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Sat, 8 Mar 2025 14:34:54 +0100 Subject: [PATCH] [mlir][memref] Add runtime verification for `memref.atomic_rmw` --- .../Transforms/RuntimeOpVerification.cpp | 45 +++ .../atomic-rmw-runtime-verification.mlir | 45 +++ .../MemRef/store-runtime-verification.mlir| 45 +++ 3 files changed, 116 insertions(+), 19 deletions(-) create mode 100644 mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir create mode 100644 mlir/test/Integration/Dialect/MemRef/store-runtime-verification.mlir diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index c8e7325d7ac89..ceea27a35a225 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -35,6 +35,26 @@ Value generateInBoundsCheck(OpBuilder &builder, Location loc, Value value, return inBounds; } +/// Generate a runtime check to see if the given indices are in-bounds with +/// respect to the given ranked memref. +Value generateIndicesInBoundsCheck(OpBuilder &builder, Location loc, + Value memref, ValueRange indices) { + auto memrefType = cast(memref.getType()); + assert(memrefType.getRank() == static_cast(indices.size()) && + "rank mismatch"); + Value cond = builder.create( + loc, builder.getIntegerAttr(builder.getI1Type(), 1)); + + auto zero = builder.create(loc, 0); + for (auto [dim, idx] : llvm::enumerate(indices)) { +Value dimOp = builder.createOrFold(loc, memref, dim); +Value inBounds = generateInBoundsCheck(builder, loc, idx, zero, dimOp); +cond = builder.createOrFold(loc, cond, inBounds); + } + + return cond; +} + struct AssumeAlignmentOpInterface : public RuntimeVerifiableOpInterface::ExternalModel< AssumeAlignmentOpInterface, AssumeAlignmentOp> { @@ -186,26 +206,10 @@ struct LoadStoreOpInterface void generateRuntimeVerification(Operation *op, OpBuilder &builder, Location loc) const { auto loadStoreOp = cast(op); - -auto memref = loadStoreOp.getMemref(); -auto rank = memref.getType().getRank(); -if (rank == 0) { - return; -} -auto indices = loadStoreOp.getIndices(); - -auto zero = builder.create(loc, 0); -Value assertCond; -for (auto i : llvm::seq(0, rank)) { - Value dimOp = builder.createOrFold(loc, memref, i); - Value inBounds = - generateInBoundsCheck(builder, loc, indices[i], zero, dimOp); - assertCond = - i > 0 ? builder.createOrFold(loc, assertCond, inBounds) -: inBounds; -} +Value cond = generateIndicesInBoundsCheck( +builder, loc, loadStoreOp.getMemref(), loadStoreOp.getIndices()); builder.create( -loc, assertCond, +loc, cond, RuntimeVerifiableOpInterface::generateErrorMessage( op, "out-of-bounds access")); } @@ -377,9 +381,12 @@ void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) { AssumeAlignmentOp::attachInterface(*ctx); +AtomicRMWOp::attachInterface>(*ctx); CastOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); +GenericAtomicRMWOp::attachInterface< +LoadStoreOpInterface>(*ctx); LoadOp::attachInterface>(*ctx); ReinterpretCastOp::attachInterface(*ctx); StoreOp::attachInterface>(*ctx); diff --git a/mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir new file mode 100644 index 0..9f70c5ca66f65 --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir @@ -0,0 +1,45 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -test-cf-assert \ +// RUN: -expand-strided-metadata \ +// RUN: -lower-affine \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +func.func @store_dynamic(%memref: memref, %index: index) { + %cst = arith.constant 1.0 : f32 + memref.atomic_rmw addf %cst, %memref[%index] : (f32, memref) -> f32 + return +} + +func.func @main() { + // Allocate a memref<10xf32>, but disguise it as a memref<5xf32>. This is + // necessary because "-test-cf-assert" does not abort the program and we do + // not want to segfault when running t
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.atomic_rmw` (PR #130414)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes Implement runtime verification for `memref.atomic_rmw` and `memref.generic_atomic_rmw`. --- Full diff: https://github.com/llvm/llvm-project/pull/130414.diff 3 Files Affected: - (modified) mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp (+26-19) - (added) mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir (+45) - (added) mlir/test/Integration/Dialect/MemRef/store-runtime-verification.mlir (+45) ``diff diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index c8e7325d7ac89..ceea27a35a225 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -35,6 +35,26 @@ Value generateInBoundsCheck(OpBuilder &builder, Location loc, Value value, return inBounds; } +/// Generate a runtime check to see if the given indices are in-bounds with +/// respect to the given ranked memref. +Value generateIndicesInBoundsCheck(OpBuilder &builder, Location loc, + Value memref, ValueRange indices) { + auto memrefType = cast(memref.getType()); + assert(memrefType.getRank() == static_cast(indices.size()) && + "rank mismatch"); + Value cond = builder.create( + loc, builder.getIntegerAttr(builder.getI1Type(), 1)); + + auto zero = builder.create(loc, 0); + for (auto [dim, idx] : llvm::enumerate(indices)) { +Value dimOp = builder.createOrFold(loc, memref, dim); +Value inBounds = generateInBoundsCheck(builder, loc, idx, zero, dimOp); +cond = builder.createOrFold(loc, cond, inBounds); + } + + return cond; +} + struct AssumeAlignmentOpInterface : public RuntimeVerifiableOpInterface::ExternalModel< AssumeAlignmentOpInterface, AssumeAlignmentOp> { @@ -186,26 +206,10 @@ struct LoadStoreOpInterface void generateRuntimeVerification(Operation *op, OpBuilder &builder, Location loc) const { auto loadStoreOp = cast(op); - -auto memref = loadStoreOp.getMemref(); -auto rank = memref.getType().getRank(); -if (rank == 0) { - return; -} -auto indices = loadStoreOp.getIndices(); - -auto zero = builder.create(loc, 0); -Value assertCond; -for (auto i : llvm::seq(0, rank)) { - Value dimOp = builder.createOrFold(loc, memref, i); - Value inBounds = - generateInBoundsCheck(builder, loc, indices[i], zero, dimOp); - assertCond = - i > 0 ? builder.createOrFold(loc, assertCond, inBounds) -: inBounds; -} +Value cond = generateIndicesInBoundsCheck( +builder, loc, loadStoreOp.getMemref(), loadStoreOp.getIndices()); builder.create( -loc, assertCond, +loc, cond, RuntimeVerifiableOpInterface::generateErrorMessage( op, "out-of-bounds access")); } @@ -377,9 +381,12 @@ void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) { AssumeAlignmentOp::attachInterface(*ctx); +AtomicRMWOp::attachInterface>(*ctx); CastOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); +GenericAtomicRMWOp::attachInterface< +LoadStoreOpInterface>(*ctx); LoadOp::attachInterface>(*ctx); ReinterpretCastOp::attachInterface(*ctx); StoreOp::attachInterface>(*ctx); diff --git a/mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir new file mode 100644 index 0..9f70c5ca66f65 --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/atomic-rmw-runtime-verification.mlir @@ -0,0 +1,45 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -test-cf-assert \ +// RUN: -expand-strided-metadata \ +// RUN: -lower-affine \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +func.func @store_dynamic(%memref: memref, %index: index) { + %cst = arith.constant 1.0 : f32 + memref.atomic_rmw addf %cst, %memref[%index] : (f32, memref) -> f32 + return +} + +func.func @main() { + // Allocate a memref<10xf32>, but disguise it as a memref<5xf32>. This is + // necessary because "-test-cf-assert" does not abort the program and we do + // not want to segfault when running the test case. + %alloc = memref.alloca() : memref<10xf32> + %ptr = memref.extract_aligned_pointer_as_index %alloc : memref<10xf32> -> index + %ptr_i64 = arith.index_cast %ptr : index to i64 + %ptr_llvm = llvm.inttoptr %ptr_i64 : i64 to !llvm.ptr + %c0 = llvm.mlir.constant(0 : index) : i64 +
[llvm-branch-commits] [clang] [AstMatcher]`templateArgumentCountIs` support `FunctionDecl` (PR #130416)
https://github.com/HerrCai0907 created https://github.com/llvm/llvm-project/pull/130416 `hasTemplateArgument` and `templateArgumentCountIs` are always used together. It is more convenient to make then support `FunctionDecl`. >From 97ea31513d00893e797ff3c97ac441e54a11bbb8 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Sat, 8 Mar 2025 21:33:02 +0800 Subject: [PATCH] [AstMatcher]`templateArgumentCountIs` support `FunctionDecl` `hasTemplateArgument` and `templateArgumentCountIs` are always used together. It is more convenient to make then support `FunctionDecl`. --- clang/include/clang/ASTMatchers/ASTMatchers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 0f7e3a8a01762..03d522072f6c1 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1090,6 +1090,7 @@ AST_POLYMORPHIC_MATCHER_P2( AST_POLYMORPHIC_MATCHER_P( templateArgumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, +VarTemplateSpecializationDecl, FunctionDecl, TemplateSpecializationType), unsigned, N) { return internal::getTemplateSpecializationArgs(Node).size() == N; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)
https://github.com/HerrCai0907 created https://github.com/llvm/llvm-project/pull/130417 Fixes: #119554 >From 51d2bd7e75426ee5c34bda94ff212d82da3354b7 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Sat, 8 Mar 2025 21:50:19 +0800 Subject: [PATCH] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` Fixes: #119554 --- .../bugprone/OptionalValueConversionCheck.cpp | 18 ++ clang-tools-extra/docs/ReleaseNotes.rst| 4 ...nal-value-conversion-construct-from-std.cpp | 13 + 3 files changed, 35 insertions(+) diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp index 33e823ac07490..a3c6bebe3d17f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp @@ -12,6 +12,7 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" #include using namespace clang::ast_matchers; @@ -27,10 +28,15 @@ AST_MATCHER_P(QualType, hasCleanType, Matcher, InnerMatcher) { Finder, Builder); } +AST_MATCHER_P(FunctionDecl, hasReturnType, Matcher, InnerMatcher) { + return InnerMatcher.matches(Node.getReturnType(), Finder, Builder); +} + constexpr std::array MakeSmartPtrList{ "::std::make_unique", "::std::make_shared", }; +constexpr StringRef MakeOptional = "::std::make_optional"; } // namespace @@ -86,6 +92,18 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { callee(functionDecl( matchers::matchesAnyListedName(MakeSmartPtrList), hasTemplateArgument(0, refersToType(BindOptionalType, + hasArgument(0, OptionalDerefMatcher)), + callExpr( + // match first std::make_optional by limit argument count (1) + // and template count (1). + // 1. template< class T > constexpr + //std::optional> make_optional(T&& value); + // 2. template< class T, class... Args > constexpr + //std::optional make_optional(Args&&... args); + argumentCountIs(1), + callee(functionDecl(templateArgumentCountIs(1), + hasName(MakeOptional), + hasReturnType(BindOptionalType))), hasArgument(0, OptionalDerefMatcher))), unless(anyOf(hasAncestor(typeLoc()), hasAncestor(expr(matchers::hasUnevaluatedContext()) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index ce1418a2a7d58..a726015a708f7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -115,6 +115,10 @@ Changes in existing checks no longer be needed and will be removed. Also fixing false positive from const reference accessors to objects containing optional member. +- Improved :doc:`bugprone-optional-value-conversion + ` check to detect + conversion in argument of ``std::make_optional``. + - Improved :doc:`bugprone-unsafe-functions ` check to allow specifying additional C++ member functions to match. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp index 768ab1ce014ce..305fd6890710d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp @@ -27,9 +27,19 @@ class unique_ptr {}; template class shared_ptr {}; +template +class initializer_list {}; + template unique_ptr make_unique(Args &&...args); template shared_ptr make_shared(Args &&...args); +template +constexpr std::optional<__decay(T)> make_optional(T &&value); +template +constexpr std::optional make_optional(Args &&...args); +template +constexpr std::optional make_optional(std::initializer_list il, Args &&...args); + } // namespace std struct A { @@ -45,9 +55,12 @@ void invalid() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] std::make_shared>(opt.value()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] + std::make_optio
[llvm-branch-commits] [clang] [AstMatcher]`templateArgumentCountIs` support `FunctionDecl` (PR #130416)
HerrCai0907 wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/130416?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#130417** https://app.graphite.dev/github/pr/llvm/llvm-project/130417?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#130416** https://app.graphite.dev/github/pr/llvm/llvm-project/130416?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/130416?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#130415** https://app.graphite.dev/github/pr/llvm/llvm-project/130415?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/130416 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)
HerrCai0907 wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/130417?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#130417** https://app.graphite.dev/github/pr/llvm/llvm-project/130417?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/130417?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#130416** https://app.graphite.dev/github/pr/llvm/llvm-project/130416?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#130415** https://app.graphite.dev/github/pr/llvm/llvm-project/130415?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/130417 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy Author: Congcong Cai (HerrCai0907) Changes Fixes: #119554 --- Full diff: https://github.com/llvm/llvm-project/pull/130417.diff 3 Files Affected: - (modified) clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp (+18) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4) - (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp (+13) ``diff diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp index 33e823ac07490..a3c6bebe3d17f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp @@ -12,6 +12,7 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" #include using namespace clang::ast_matchers; @@ -27,10 +28,15 @@ AST_MATCHER_P(QualType, hasCleanType, Matcher, InnerMatcher) { Finder, Builder); } +AST_MATCHER_P(FunctionDecl, hasReturnType, Matcher, InnerMatcher) { + return InnerMatcher.matches(Node.getReturnType(), Finder, Builder); +} + constexpr std::array MakeSmartPtrList{ "::std::make_unique", "::std::make_shared", }; +constexpr StringRef MakeOptional = "::std::make_optional"; } // namespace @@ -86,6 +92,18 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { callee(functionDecl( matchers::matchesAnyListedName(MakeSmartPtrList), hasTemplateArgument(0, refersToType(BindOptionalType, + hasArgument(0, OptionalDerefMatcher)), + callExpr( + // match first std::make_optional by limit argument count (1) + // and template count (1). + // 1. template< class T > constexpr + //std::optional> make_optional(T&& value); + // 2. template< class T, class... Args > constexpr + //std::optional make_optional(Args&&... args); + argumentCountIs(1), + callee(functionDecl(templateArgumentCountIs(1), + hasName(MakeOptional), + hasReturnType(BindOptionalType))), hasArgument(0, OptionalDerefMatcher))), unless(anyOf(hasAncestor(typeLoc()), hasAncestor(expr(matchers::hasUnevaluatedContext()) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index ce1418a2a7d58..a726015a708f7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -115,6 +115,10 @@ Changes in existing checks no longer be needed and will be removed. Also fixing false positive from const reference accessors to objects containing optional member. +- Improved :doc:`bugprone-optional-value-conversion + ` check to detect + conversion in argument of ``std::make_optional``. + - Improved :doc:`bugprone-unsafe-functions ` check to allow specifying additional C++ member functions to match. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp index 768ab1ce014ce..305fd6890710d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp @@ -27,9 +27,19 @@ class unique_ptr {}; template class shared_ptr {}; +template +class initializer_list {}; + template unique_ptr make_unique(Args &&...args); template shared_ptr make_shared(Args &&...args); +template +constexpr std::optional<__decay(T)> make_optional(T &&value); +template +constexpr std::optional make_optional(Args &&...args); +template +constexpr std::optional make_optional(std::initializer_list il, Args &&...args); + } // namespace std struct A { @@ -45,9 +55,12 @@ void invalid() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] std::make_shared>(opt.value()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] + std::make_optional(opt.value()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and
[llvm-branch-commits] [clang] [AstMatcher]`templateArgumentCountIs` support `FunctionDecl` (PR #130416)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Congcong Cai (HerrCai0907) Changes `hasTemplateArgument` and `templateArgumentCountIs` are always used together. It is more convenient to make then support `FunctionDecl`. --- Full diff: https://github.com/llvm/llvm-project/pull/130416.diff 1 Files Affected: - (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+1) ``diff diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 0f7e3a8a01762..03d522072f6c1 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1090,6 +1090,7 @@ AST_POLYMORPHIC_MATCHER_P2( AST_POLYMORPHIC_MATCHER_P( templateArgumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, +VarTemplateSpecializationDecl, FunctionDecl, TemplateSpecializationType), unsigned, N) { return internal::getTemplateSpecializationArgs(Node).size() == N; `` https://github.com/llvm/llvm-project/pull/130416 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)
https://github.com/HerrCai0907 ready_for_review https://github.com/llvm/llvm-project/pull/130417 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [AstMatcher]`templateArgumentCountIs` support `FunctionDecl` (PR #130416)
https://github.com/HerrCai0907 ready_for_review https://github.com/llvm/llvm-project/pull/130416 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.assume_alignment` (PR #130412)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes Implement runtime verification for `memref.assume_alignment`. --- Full diff: https://github.com/llvm/llvm-project/pull/130412.diff 2 Files Affected: - (modified) mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp (+24-1) - (added) mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir (+37) ``diff diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index f825d7d9d42c2..c8e7325d7ac89 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -23,7 +23,7 @@ using namespace mlir; namespace mlir { namespace memref { namespace { -/// Generate a runtime check for lb <= value < ub. +/// Generate a runtime check for lb <= value < ub. Value generateInBoundsCheck(OpBuilder &builder, Location loc, Value value, Value lb, Value ub) { Value inBounds1 = builder.createOrFold( @@ -35,6 +35,28 @@ Value generateInBoundsCheck(OpBuilder &builder, Location loc, Value value, return inBounds; } +struct AssumeAlignmentOpInterface +: public RuntimeVerifiableOpInterface::ExternalModel< + AssumeAlignmentOpInterface, AssumeAlignmentOp> { + void generateRuntimeVerification(Operation *op, OpBuilder &builder, + Location loc) const { +auto assumeOp = cast(op); +Value ptr = builder.create( +loc, assumeOp.getMemref()); +Value rest = builder.create( +loc, ptr, +builder.create(loc, assumeOp.getAlignment())); +Value isAligned = builder.create( +loc, arith::CmpIPredicate::eq, rest, +builder.create(loc, 0)); +builder.create( +loc, isAligned, +RuntimeVerifiableOpInterface::generateErrorMessage( +op, "memref is not aligned to " + +std::to_string(assumeOp.getAlignment(; + } +}; + struct CastOpInterface : public RuntimeVerifiableOpInterface::ExternalModel { @@ -354,6 +376,7 @@ struct ExpandShapeOpInterface void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) { +AssumeAlignmentOp::attachInterface(*ctx); CastOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); diff --git a/mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir new file mode 100644 index 0..394648d1b8bfa --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir @@ -0,0 +1,37 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -expand-strided-metadata \ +// RUN: -test-cf-assert \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +func.func @main() { + // This buffer is properly aligned. There should be no error. + // CHECK-NOT: ^ memref is not aligned to 8 + %alloc = memref.alloca() : memref<5xf64> + memref.assume_alignment %alloc, 8 : memref<5xf64> + + // Construct a memref descriptor with a pointer that is not aligned to 4. + // This cannot be done with just the memref dialect. We have to resort to + // the LLVM dialect. + %c0 = llvm.mlir.constant(0 : index) : i64 + %c1 = llvm.mlir.constant(1 : index) : i64 + %c3 = llvm.mlir.constant(3 : index) : i64 + %unaligned_ptr = llvm.inttoptr %c3 : i64 to !llvm.ptr + %4 = llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %5 = llvm.insertvalue %unaligned_ptr, %4[0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %6 = llvm.insertvalue %unaligned_ptr, %5[1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %8 = llvm.insertvalue %c0, %6[2] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %9 = llvm.insertvalue %c1, %8[3, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %10 = llvm.insertvalue %c1, %9[4, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %buffer = builtin.unrealized_conversion_cast %10 : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> to memref<1xf32> + + // CHECK: ERROR: Runtime op verification failed + // CHECK-NEXT: "memref.assume_alignment"(%{{.*}}) <{alignment = 4 : i32}> : (memref<1xf32>) -> () + // CHECK-NEXT: ^ memref is not aligned to 4 + // CHECK-NEXT: Location: loc({{.*}}) + memref.assume_alignment %buffer, 4 : memref<1xf32> + + return +} `` https://github.com/llvm/llvm-project/pull/130412
[llvm-branch-commits] [llvm] [CodeGen][NPM] Port StackFrameLayoutAnalysisPass to NPM (PR #130070)
https://github.com/optimisan updated https://github.com/llvm/llvm-project/pull/130070 >From d4ed8c036554f66384ab9578c32f00a50426a88e Mon Sep 17 00:00:00 2001 From: Akshat Oke Date: Thu, 6 Mar 2025 10:45:25 + Subject: [PATCH] [CodeGen][NPM] Port StackFrameLayoutAnalysisPass to NPM --- .../CodeGen/StackFrameLayoutAnalysisPass.h| 26 llvm/include/llvm/InitializePasses.h | 2 +- llvm/include/llvm/Passes/CodeGenPassBuilder.h | 3 + .../llvm/Passes/MachinePassRegistry.def | 2 +- llvm/lib/CodeGen/CodeGen.cpp | 2 +- .../CodeGen/StackFrameLayoutAnalysisPass.cpp | 61 +-- llvm/lib/Passes/PassBuilder.cpp | 1 + 7 files changed, 74 insertions(+), 23 deletions(-) create mode 100644 llvm/include/llvm/CodeGen/StackFrameLayoutAnalysisPass.h diff --git a/llvm/include/llvm/CodeGen/StackFrameLayoutAnalysisPass.h b/llvm/include/llvm/CodeGen/StackFrameLayoutAnalysisPass.h new file mode 100644 index 0..5283cda30da12 --- /dev/null +++ b/llvm/include/llvm/CodeGen/StackFrameLayoutAnalysisPass.h @@ -0,0 +1,26 @@ +//===- llvm/CodeGen/StackFrameLayoutAnalysisPass.h --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CODEGEN_STACKFRAMELAYOUTANALYSISPASS_H +#define LLVM_CODEGEN_STACKFRAMELAYOUTANALYSISPASS_H + +#include "llvm/CodeGen/MachinePassManager.h" + +namespace llvm { + +class StackFrameLayoutAnalysisPass +: public PassInfoMixin { +public: + PreservedAnalyses run(MachineFunction &MF, +MachineFunctionAnalysisManager &MFAM); + static bool isRequired() { return true; } +}; + +} // namespace llvm + +#endif // LLVM_CODEGEN_STACKFRAMELAYOUTANALYSISPASS_H diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index c7bc4320cf8f0..9068aee8f8193 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -290,7 +290,7 @@ void initializeSlotIndexesWrapperPassPass(PassRegistry &); void initializeSpeculativeExecutionLegacyPassPass(PassRegistry &); void initializeSpillPlacementWrapperLegacyPass(PassRegistry &); void initializeStackColoringLegacyPass(PassRegistry &); -void initializeStackFrameLayoutAnalysisPassPass(PassRegistry &); +void initializeStackFrameLayoutAnalysisLegacyPass(PassRegistry &); void initializeStaticDataSplitterPass(PassRegistry &); void initializeStackMapLivenessPass(PassRegistry &); void initializeStackProtectorPass(PassRegistry &); diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h index 74cdc7d66810b..8cba36b36fbb2 100644 --- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h +++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h @@ -80,6 +80,7 @@ #include "llvm/CodeGen/ShadowStackGCLowering.h" #include "llvm/CodeGen/SjLjEHPrepare.h" #include "llvm/CodeGen/StackColoring.h" +#include "llvm/CodeGen/StackFrameLayoutAnalysisPass.h" #include "llvm/CodeGen/StackProtector.h" #include "llvm/CodeGen/StackSlotColoring.h" #include "llvm/CodeGen/TailDuplication.h" @@ -1015,6 +1016,8 @@ Error CodeGenPassBuilder::addMachinePasses( addPass(MachineOutlinerPass(RunOnAllFunctions)); } + addPass(StackFrameLayoutAnalysisPass()); + // Add passes that directly emit MI after all other MI passes. derived().addPreEmitPass2(addPass); diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def index 8fa21751392f3..01dd423de6955 100644 --- a/llvm/include/llvm/Passes/MachinePassRegistry.def +++ b/llvm/include/llvm/Passes/MachinePassRegistry.def @@ -187,6 +187,7 @@ MACHINE_FUNCTION_PASS("remove-redundant-debug-values", RemoveRedundantDebugValue MACHINE_FUNCTION_PASS("require-all-machine-function-properties", RequireAllMachineFunctionPropertiesPass()) MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass()) +MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass()) MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass()) MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass()) MACHINE_FUNCTION_PASS("trigger-verifier-error", TriggerVerifierErrorPass()) @@ -295,7 +296,6 @@ DUMMY_MACHINE_FUNCTION_PASS("regallocscoringpass", RegAllocScoringPass) DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass) DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass) DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass) -DUMMY_MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass) DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass) DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachine
[llvm-branch-commits] [libcxx] release/20.x: [libc++][test] extend XFAIL clauses to cover Amazon Linux too (#129377) (PR #129566)
DavidSpickett wrote: That's expected, PRs to release branches can only be merged by a release manager. They'll do that if they judge it to be valid and the timing is right. https://github.com/llvm/llvm-project/pull/129566 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] PeepholeOpt: Remove subreg def check for insert_subreg (PR #130085)
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/130085 None >From 924dae6487d294c2cccb1862be4585d28a33bbc0 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 6 Mar 2025 18:51:01 +0700 Subject: [PATCH] PeepholeOpt: Remove subreg def check for insert_subreg --- llvm/lib/CodeGen/PeepholeOptimizer.cpp | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp index 2a328039c3032..4d0fd86eb216f 100644 --- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp +++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp @@ -2028,12 +2028,7 @@ ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() { ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() { assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) && "Invalid definition"); - - if (Def->getOperand(DefIdx).getSubReg()) -// If we are composing subreg, bail out. -// Same remark as getNextSourceFromRegSequence. -// I.e., this may be turned into an assert. -return ValueTrackerResult(); + assert(!Def->getOperand(DefIdx).getSubReg() && "no subreg defs in SSA"); RegSubRegPair BaseReg; RegSubRegPairAndIdx InsertedReg; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][memref] Add runtime verification for `memref.assume_alignment` (PR #130412)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/130412 Implement runtime verification for `memref.assume_alignment`. >From 7cf452f01303e82cb3dd63fed1a1ce306f311e95 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Sat, 8 Mar 2025 13:45:45 +0100 Subject: [PATCH] [mlir][memref] Add runtime verification for `memref.assume_alignment` --- .../Transforms/RuntimeOpVerification.cpp | 25 - ...assume-alignment-runtime-verification.mlir | 37 +++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp index f825d7d9d42c2..c8e7325d7ac89 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp @@ -23,7 +23,7 @@ using namespace mlir; namespace mlir { namespace memref { namespace { -/// Generate a runtime check for lb <= value < ub. +/// Generate a runtime check for lb <= value < ub. Value generateInBoundsCheck(OpBuilder &builder, Location loc, Value value, Value lb, Value ub) { Value inBounds1 = builder.createOrFold( @@ -35,6 +35,28 @@ Value generateInBoundsCheck(OpBuilder &builder, Location loc, Value value, return inBounds; } +struct AssumeAlignmentOpInterface +: public RuntimeVerifiableOpInterface::ExternalModel< + AssumeAlignmentOpInterface, AssumeAlignmentOp> { + void generateRuntimeVerification(Operation *op, OpBuilder &builder, + Location loc) const { +auto assumeOp = cast(op); +Value ptr = builder.create( +loc, assumeOp.getMemref()); +Value rest = builder.create( +loc, ptr, +builder.create(loc, assumeOp.getAlignment())); +Value isAligned = builder.create( +loc, arith::CmpIPredicate::eq, rest, +builder.create(loc, 0)); +builder.create( +loc, isAligned, +RuntimeVerifiableOpInterface::generateErrorMessage( +op, "memref is not aligned to " + +std::to_string(assumeOp.getAlignment(; + } +}; + struct CastOpInterface : public RuntimeVerifiableOpInterface::ExternalModel { @@ -354,6 +376,7 @@ struct ExpandShapeOpInterface void mlir::memref::registerRuntimeVerifiableOpInterfaceExternalModels( DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) { +AssumeAlignmentOp::attachInterface(*ctx); CastOp::attachInterface(*ctx); DimOp::attachInterface(*ctx); ExpandShapeOp::attachInterface(*ctx); diff --git a/mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir b/mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir new file mode 100644 index 0..394648d1b8bfa --- /dev/null +++ b/mlir/test/Integration/Dialect/MemRef/assume-alignment-runtime-verification.mlir @@ -0,0 +1,37 @@ +// RUN: mlir-opt %s -generate-runtime-verification \ +// RUN: -expand-strided-metadata \ +// RUN: -test-cf-assert \ +// RUN: -convert-to-llvm | \ +// RUN: mlir-runner -e main -entry-point-result=void \ +// RUN: -shared-libs=%mlir_runner_utils 2>&1 | \ +// RUN: FileCheck %s + +func.func @main() { + // This buffer is properly aligned. There should be no error. + // CHECK-NOT: ^ memref is not aligned to 8 + %alloc = memref.alloca() : memref<5xf64> + memref.assume_alignment %alloc, 8 : memref<5xf64> + + // Construct a memref descriptor with a pointer that is not aligned to 4. + // This cannot be done with just the memref dialect. We have to resort to + // the LLVM dialect. + %c0 = llvm.mlir.constant(0 : index) : i64 + %c1 = llvm.mlir.constant(1 : index) : i64 + %c3 = llvm.mlir.constant(3 : index) : i64 + %unaligned_ptr = llvm.inttoptr %c3 : i64 to !llvm.ptr + %4 = llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %5 = llvm.insertvalue %unaligned_ptr, %4[0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %6 = llvm.insertvalue %unaligned_ptr, %5[1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %8 = llvm.insertvalue %c0, %6[2] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %9 = llvm.insertvalue %c1, %8[3, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %10 = llvm.insertvalue %c1, %9[4, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> + %buffer = builtin.unrealized_conversion_cast %10 : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> to memref<1xf32> + + // CHECK: ERROR: Runtime op verification failed + // CHECK-NEXT: "memref.assume_alignment"(%{{.*}}) <{alignment = 4 : i32}> : (memref<1xf32>) -> () + // CHECK-NEXT: ^ memref is not ali