[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread Matt Arsenault via llvm-branch-commits

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)

2025-03-08 Thread Vitaly Buka via llvm-branch-commits

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)

2025-03-08 Thread Vitaly Buka via llvm-branch-commits


@@ -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)

2025-03-08 Thread Alex Rønne Petersen via llvm-branch-commits

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)

2025-03-08 Thread Mariusz Sikora via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread Petar Avramovic via llvm-branch-commits

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)

2025-03-08 Thread Yaxun Liu via llvm-branch-commits

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)

2025-03-08 Thread NAKAMURA Takumi via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread Mark de Wever via llvm-branch-commits

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)

2025-03-08 Thread Matthias Springer via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits


@@ -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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread Matthias Springer via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread Congcong Cai via llvm-branch-commits

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)

2025-03-08 Thread via llvm-branch-commits

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)

2025-03-08 Thread Akshat Oke via llvm-branch-commits

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)

2025-03-08 Thread David Spickett via llvm-branch-commits

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)

2025-03-08 Thread Matt Arsenault via llvm-branch-commits

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)

2025-03-08 Thread Matthias Springer via llvm-branch-commits

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