[llvm-branch-commits] [llvm] [LV] Mask off possibly aliasing vector lanes (PR #100579)

2025-09-23 Thread Florian Hahn via llvm-branch-commits


@@ -1347,6 +1354,11 @@ class TargetTransformInfo {
   PartialReductionExtendKind OpBExtend, std::optional BinOp,
   TTI::TargetCostKind CostKind) const;
 
+  /// \return true if a mask should be formed that disables lanes that could
+  /// alias between two pointers. The mask is created by the
+  /// loop_dependence_{war,raw}_mask intrinsics.
+  LLVM_ABI bool useSafeEltsMask(ElementCount VF) const;

fhahn wrote:

We could still check if the cost is < some bound for which vectorization is 
worthwhile?

https://github.com/llvm/llvm-project/pull/100579
___
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] [AllocToken] Introduce AllocToken instrumentation pass (PR #156838)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -0,0 +1,30 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 5
+; Test for all allocation functions that should be ignored by default.
+;
+; RUN: opt < %s -passes=inferattrs,alloc-token -S | FileCheck %s
+
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare ptr @strdup(ptr)
+declare ptr @__strdup(ptr)
+declare ptr @strndup(ptr, i64)
+declare ptr @__strndup(ptr, i64)
+
+define ptr @test_ignorable_allocation_functions(ptr %ptr) sanitize_alloc_token 
{
+; CHECK-LABEL: define ptr @test_ignorable_allocation_functions(

zmodem wrote:

nit: s/ignorable/ignored/

https://github.com/llvm/llvm-project/pull/156838
___
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] [llvm][mustache] Avoid excessive hash lookups in EscapeStringStream (PR #160166)

2025-09-23 Thread Nikita Popov via llvm-branch-commits

nikic wrote:

In these tests, at which point are you constructing the std::array? Is it 
inside each EscapeStream or once when Template is constructed?

It's possible that `std::array` wasn't the right suggestion -- maybe the fact 
that it stores std::string makes it too large. But if you check what 
find_first_of actually does 
https://github.com/llvm/llvm-project/blob/ebcf1bf2ecba6b25ece3c2bbddb4485e76189387/llvm/lib/Support/StringRef.cpp#L240-L242
 it will just take that string of characters you pass it an convert it into a 
bitset. We may as well directly create the bitset instead of creating the char 
string and then converting it to a bit set on every call.

https://github.com/llvm/llvm-project/pull/160166
___
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] [lldb] release/21.x: [lldb][Instrumentation] Set selected frame to outside sanitizer libraries (PR #157568)

2025-09-23 Thread via llvm-branch-commits

https://github.com/llvmbot updated 
https://github.com/llvm/llvm-project/pull/157568

>From 54896838ca5e1f69f0f3040fe6847546db0463d4 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Mon, 8 Sep 2025 17:18:25 +0100
Subject: [PATCH 1/4] [lldb][Target] Clear selected frame index after a
 StopInfo::PerformAction (#133078)

The motivation for this patch is that
`StopInfo::GetSuggestedStackFrameIndex` would not take effect for
`InstrumentationRuntimeStopInfo` (which we plan to implement in
https://github.com/llvm/llvm-project/pull/133079). This was happening
because the instrumentation runtime plugins would run utility
expressions as part of the stop that would set the
`m_selected_frame_idx`. This means `SelectMostRelevantFrame` was never
called, and we would not be able to report the selected frame via the
`StopInfo` object.

This patch makes sure we clear the `m_selected_frame_idx` to allow
`GetSuggestedStackFrameIndex` to take effect, regardless of what the
frame recognizers choose to do.

(cherry picked from commit 39572f5e9168b1b44c2f9078494616fed8752086)
---
 lldb/include/lldb/Target/StackFrameList.h | 12 
 lldb/include/lldb/Target/Thread.h |  5 +
 lldb/source/Target/Process.cpp|  8 
 lldb/source/Target/StackFrameList.cpp |  2 ++
 4 files changed, 27 insertions(+)

diff --git a/lldb/include/lldb/Target/StackFrameList.h 
b/lldb/include/lldb/Target/StackFrameList.h
index 8a66296346f2d..8d455dc831df3 100644
--- a/lldb/include/lldb/Target/StackFrameList.h
+++ b/lldb/include/lldb/Target/StackFrameList.h
@@ -46,6 +46,9 @@ class StackFrameList {
   /// Mark a stack frame as the currently selected frame and return its index.
   uint32_t SetSelectedFrame(lldb_private::StackFrame *frame);
 
+  /// Resets the selected frame index of this object.
+  void ClearSelectedFrameIndex();
+
   /// Get the currently selected frame index.
   /// We should only call SelectMostRelevantFrame if (a) the user hasn't 
already
   /// selected a frame, and (b) if this really is a user facing
@@ -172,6 +175,15 @@ class StackFrameList {
   /// The currently selected frame. An optional is used to record whether 
anyone
   /// has set the selected frame on this stack yet. We only let recognizers
   /// change the frame if this is the first time GetSelectedFrame is called.
+  ///
+  /// Thread-safety:
+  /// This member is not protected by a mutex.
+  /// LLDB really only should have an opinion about the selected frame index
+  /// when a process stops, before control gets handed back to the user.
+  /// After that, it's up to them to change it whenever they feel like it.
+  /// If two parts of lldb decided they wanted to be in control of the selected
+  /// frame index on stop the right way to fix it would need to be some 
explicit
+  /// negotiation for who gets to control this.
   std::optional m_selected_frame_idx;
 
   /// The number of concrete frames fetched while filling the frame list. This
diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index 6ede7fa301a82..688c056da2633 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -479,6 +479,11 @@ class Thread : public std::enable_shared_from_this,
   bool SetSelectedFrameByIndexNoisily(uint32_t frame_idx,
   Stream &output_stream);
 
+  /// Resets the selected frame index of this object.
+  void ClearSelectedFrameIndex() {
+return GetStackFrameList()->ClearSelectedFrameIndex();
+  }
+
   void SetDefaultFileAndLineToSelectedFrame() {
 GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame();
   }
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 2aa02fd58335e..a2fa88b569135 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -4257,6 +4257,14 @@ bool Process::ProcessEventData::ShouldStop(Event 
*event_ptr,
 // appropriately. We also need to stop processing actions, since they
 // aren't expecting the target to be running.
 
+// Clear the selected frame which may have been set as part of utility
+// expressions that have been run as part of this stop. If we didn't
+// clear this, then StopInfo::GetSuggestedStackFrameIndex would not
+// take affect when we next called SelectMostRelevantFrame.
+// PerformAction should not be the one setting a selected frame, 
instead
+// this should be done via GetSuggestedStackFrameIndex.
+thread_sp->ClearSelectedFrameIndex();
+
 // FIXME: we might have run.
 if (stop_info_sp->HasTargetRunSinceMe()) {
   SetRestarted(true);
diff --git a/lldb/source/Target/StackFrameList.cpp 
b/lldb/source/Target/StackFrameList.cpp
index 16cd2548c2784..931b73b1e3633 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -936,3 +936,5 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t 
first_frame,
  

[llvm-branch-commits] [mlir] [mlir][OpenMP] Improve canonloop/iv naming (PR #159773)

2025-09-23 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur edited 
https://github.com/llvm/llvm-project/pull/159773
___
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] 113f01a - [PowerPC] Implement AES Acceleration Instructions (#157725)

2025-09-23 Thread via llvm-branch-commits

Author: Lei Huang
Date: 2025-09-23T10:44:18-04:00
New Revision: 113f01aa82d055410f22a9d03b3468fa68600589

URL: 
https://github.com/llvm/llvm-project/commit/113f01aa82d055410f22a9d03b3468fa68600589
DIFF: 
https://github.com/llvm/llvm-project/commit/113f01aa82d055410f22a9d03b3468fa68600589.diff

LOG: [PowerPC] Implement AES Acceleration Instructions (#157725)

Implement AES Acceleration Instructions:
  * xxaesencp
  * xxaesdecp
  * xxaesgenlkp
  * xxgfmul128

Added: 


Modified: 
llvm/lib/Target/PowerPC/PPCInstrFuture.td
llvm/test/MC/Disassembler/PowerPC/ppc-encoding-ISAFuture.txt
llvm/test/MC/Disassembler/PowerPC/ppc64le-encoding-ISAFuture.txt
llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s

Removed: 




diff  --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td 
b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 5751d7dc1628b..a61b347f912f0 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -120,6 +120,74 @@ class VXForm_VRTAB5 xo, dag OOL, dag IOL, string 
asmstr,
   let Inst{21...31} = xo;
 }
 
+class XX3Form_XTBp5_M2 xo, dag OOL, dag IOL, string asmstr,
+   list pattern>
+: I<60, OOL, IOL, asmstr, NoItinerary> {
+
+  bits<5> XTp;
+  bits<5> XBp;
+  bits<2> M;
+
+  let Pattern = pattern;
+
+  let Inst{6...9} = XTp{3...0};
+  let Inst {10} = XTp{4};
+  let Inst{15} = M{0};
+  let Inst{16...19} = XBp{3...0};
+  let Inst{20} = M{1};
+  let Inst{21...29} = xo;
+  let Inst{30} = XBp{4};
+}
+
+class XX3Form_XTABp5_M2 xo, dag OOL, dag IOL, string asmstr,
+list pattern>
+: I<60, OOL, IOL, asmstr, NoItinerary> {
+
+  bits<5> XTp;
+  bits<5> XAp;
+  bits<5> XBp;
+  bits<2> M;
+
+  let Pattern = pattern;
+
+  let Inst{6...9} = XTp{3...0};
+  let Inst{10} = XTp{4};
+  let Inst{11...14} = XAp{3...0};
+  let Inst{15} = M{0};
+  let Inst{16...19} = XBp{3...0};
+  let Inst{20} = M{1};
+  let Inst{21...28} = xo;
+  let Inst{29} = XAp{4};
+  let Inst{30} = XBp{4};
+}
+
+class XX3Form_XTAB6_P1 xo, dag OOL, dag IOL, string asmstr,
+   list pattern>
+: I<60, OOL, IOL, asmstr, NoItinerary> {
+
+  bits<6> XT;
+  bits<6> XA;
+  bits<6> XB;
+  bits<1> P;
+
+  let Pattern = pattern;
+
+  let Inst{6...10} = XT{4...0};
+  let Inst{11...15} = XA{4...0};
+  let Inst{16...20} = XB{4...0};
+  let Inst{21...22} = 3;
+  let Inst{23} = P;
+  let Inst{24...28} = xo;
+  let Inst{29} = XA{5};
+  let Inst{30} = XB{5};
+  let Inst{31} = XT{5};
+}
+
+//-- Instruction definitions 
-//
+// Predicate combinations available:
+// [IsISAFuture]
+// [HasVSX, IsISAFuture]
+
 let Predicates = [IsISAFuture] in {
   defm SUBFUS : XOForm_RTAB5_L1r<31, 72, (outs g8rc:$RT),
  (ins g8rc:$RA, g8rc:$RB, u1imm:$L), "subfus",
@@ -191,6 +259,53 @@ let Predicates = [HasVSX, IsISAFuture] in {
   def VUCMPRLH
   : VXForm_VRTAB5<323, (outs vrrc:$VRT), (ins vrrc:$VRA, vrrc:$VRB),
   "vucmprlh $VRT, $VRA, $VRB", []>;
+
+  // AES Acceleration Instructions
+  def XXAESENCP : XX3Form_XTABp5_M2<194, (outs vsrprc:$XTp),
+(ins vsrprc:$XAp, vsrprc:$XBp, u2imm:$M),
+"xxaesencp $XTp, $XAp, $XBp, $M", []>;
+  def XXAESDECP : XX3Form_XTABp5_M2<202, (outs vsrprc:$XTp),
+(ins vsrprc:$XAp, vsrprc:$XBp, u2imm:$M),
+"xxaesdecp $XTp, $XAp, $XBp, $M", []>;
+  def XXAESGENLKP : XX3Form_XTBp5_M2<420, (outs vsrprc:$XTp),
+ (ins vsrprc:$XBp, u2imm:$M),
+ "xxaesgenlkp $XTp, $XBp, $M", []>;
+  def XXGFMUL128 : XX3Form_XTAB6_P1<26, (outs vsrc:$XT),
+(ins vsrc:$XA, vsrc:$XB, u1imm:$P),
+"xxgfmul128 $XT, $XA, $XB, $P", []>;
+}
+
+// Anonymous Patterns 
//
+// Predicate combinations available:
+
+
+// Instruction aliases 
---//
+// Predicate combinations available:
+// [HasVSX, IsISAFuture]
+
+let Predicates = [HasVSX, IsISAFuture] in {
+  def : InstAlias<"xxaes128encp $XTp, $XAp, $XBp",
+  (XXAESENCP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 0)>;
+  def : InstAlias<"xxaes192encp $XTp, $XAp, $XBp",
+  (XXAESENCP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 1)>;
+  def : InstAlias<"xxaes256encp $XTp, $XAp, $XBp",
+  (XXAESENCP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 2)>;
+  def : InstAlias<"xxaes128decp $XTp, $XAp, $XBp",
+  (XXAESDECP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 0)>;
+  def : InstAlias<"xxaes192decp $XTp, $XAp, $XBp",
+  (XXAESDECP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 1)>;
+  def : InstAlias<"xxaes2

[llvm-branch-commits] [clang] [llvm] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)

2025-09-23 Thread via llvm-branch-commits




joaosaffran wrote:

Sorry, made a mistake, I will fix it in the next commit

https://github.com/llvm/llvm-project/pull/160210
___
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] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)

2025-09-23 Thread via llvm-branch-commits


@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const 
StaticSampler &Sampler) {
   ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
   ConstantAsMetadata::get(
   Builder.getInt32(to_underlying(Sampler.Visibility))),
+  ConstantAsMetadata::get(Builder.getInt32(0)),

joaosaffran wrote:

Yeah, this is just a temporary fix, I've a follow up PR focused on the frontend 
changes. I need to add this here, otherwise metadata generation will Fail. 
Maybe instead of hard coding I can add the flags to StaticSamplers and set them 
to be None, as this is the default anyway

https://github.com/llvm/llvm-project/pull/160210
___
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] b708aea - [SCEV] Don't perform implication checks with many predicates (#158652)

2025-09-23 Thread Tom Stellard via llvm-branch-commits

Author: Nikita Popov
Date: 2025-09-23T12:22:24-07:00
New Revision: b708aea0bc7127adf4ec643660699c8bcdde1273

URL: 
https://github.com/llvm/llvm-project/commit/b708aea0bc7127adf4ec643660699c8bcdde1273
DIFF: 
https://github.com/llvm/llvm-project/commit/b708aea0bc7127adf4ec643660699c8bcdde1273.diff

LOG: [SCEV] Don't perform implication checks with many predicates (#158652)

When adding a new predicate to a union, we currently do a bidirectional
implication for all the contained predicates. This means that the number
of implication checks is quadratic in the number of total predicates (if
they don't end up being eliminated).

Fix this by not checking for implication if the number of predicates
grows too large. The expectation is that if there is a large number of
predicates, we should be discarding them later anyway, as expanding them
would be too expensive.

Fixes https://github.com/llvm/llvm-project/issues/156114.

(cherry picked from commit 7af659d0f117802627fc47f73ca5dd20439c5d7b)

Added: 


Modified: 
llvm/lib/Analysis/ScalarEvolution.cpp

Removed: 




diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp 
b/llvm/lib/Analysis/ScalarEvolution.cpp
index 24adfa346c642..221468a2d1a84 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -15093,15 +15093,20 @@ void SCEVUnionPredicate::add(const SCEVPredicate *N, 
ScalarEvolution &SE) {
 return;
   }
 
+  // Implication checks are quadratic in the number of predicates. Stop doing
+  // them if there are many predicates, as they should be too expensive to use
+  // anyway at that point.
+  bool CheckImplies = Preds.size() < 16;
+
   // Only add predicate if it is not already implied by this union predicate.
-  if (implies(N, SE))
+  if (CheckImplies && implies(N, SE))
 return;
 
   // Build a new vector containing the current predicates, except the ones that
   // are implied by the new predicate N.
   SmallVector PrunedPreds;
   for (auto *P : Preds) {
-if (N->implies(P, SE))
+if (CheckImplies && N->implies(P, SE))
   continue;
 PrunedPreds.push_back(P);
   }



___
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] simplify placeholder type deduction for constant template parameters (PR #160439)

2025-09-23 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)


Changes

This makes the deduction for dependent types operate in more similar ways to 
the non-dependent one, such as when matching template template parameters, 
making errors in those generate similar diagnostics to the non-dependent ones. 
This also removes some superfluous implicit casts, simplifying the resulting 
AST a little bit.

---
Full diff: https://github.com/llvm/llvm-project/pull/160439.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2-1) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+33-35) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+12-20) 
- (modified) clang/test/SemaTemplate/temp_arg_template_p0522.cpp (+5-5) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 70c82b090107a..1932135ceed1b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -292,7 +292,8 @@ Improvements to Clang's diagnostics
   "format specifies type 'unsigned int' but the argument has type 'int', which 
differs in signedness [-Wformat-signedness]"
   "signedness of format specifier 'u' is incompatible with 'c' 
[-Wformat-signedness]"
   and the API-visible diagnostic id will be appropriate.
-
+- Clang now produces better diagnostics for template template parameter 
matching
+  involving 'auto' template parameters.
 - Fixed false positives in ``-Waddress-of-packed-member`` diagnostics when
   potential misaligned members get processed before they can get discarded.
   (#GH144729)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index f051a246f954f..5a48ba0c344b7 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7068,22 +7068,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, 
QualType ParamType,
 
   // If the parameter type somehow involves auto, deduce the type now.
   DeducedType *DeducedT = ParamType->getContainedDeducedType();
-  if (getLangOpts().CPlusPlus17 && DeducedT && !DeducedT->isDeduced()) {
-// During template argument deduction, we allow 'decltype(auto)' to
-// match an arbitrary dependent argument.
-// FIXME: The language rules don't say what happens in this case.
-// FIXME: We get an opaque dependent type out of decltype(auto) if the
-// expression is merely instantiation-dependent; is this enough?
-if (DeductionArg->isTypeDependent()) {
-  auto *AT = dyn_cast(DeducedT);
-  if (AT && AT->isDecltypeAuto()) {
-SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false);
-CanonicalConverted = TemplateArgument(
-Context.getCanonicalTemplateArgument(SugaredConverted));
-return Arg;
-  }
-}
-
+  bool IsDeduced = DeducedT && !DeducedT->isDeduced();
+  if (IsDeduced) {
 // When checking a deduced template argument, deduce from its type even if
 // the type is dependent, in order to check the types of non-type template
 // arguments line up properly in partial ordering.
@@ -7112,17 +7098,21 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl 
*Param, QualType ParamType,
  // along with the other associated constraints after
  // checking the template argument list.
  /*IgnoreConstraints=*/true);
-  if (Result == TemplateDeductionResult::AlreadyDiagnosed) {
-return ExprError();
-  } else if (Result != TemplateDeductionResult::Success) {
-if (const auto *NTTP = dyn_cast(Param)) {
-  Diag(Arg->getExprLoc(),
-   diag::err_non_type_template_parm_type_deduction_failure)
-  << Param->getDeclName() << NTTP->getType() << Arg->getType()
-  << Arg->getSourceRange();
+  if (Result != TemplateDeductionResult::Success) {
+ParamType = TSI->getType();
+if (StrictCheck || !DeductionArg->isTypeDependent()) {
+  if (Result == TemplateDeductionResult::AlreadyDiagnosed)
+return ExprError();
+  if (const auto *NTTP = dyn_cast(Param))
+Diag(Arg->getExprLoc(),
+ diag::err_non_type_template_parm_type_deduction_failure)
+<< Param->getDeclName() << NTTP->getType() << Arg->getType()
+<< Arg->getSourceRange();
+  NoteTemplateParameterLocation(*Param);
+  return ExprError();
 }
-NoteTemplateParameterLocation(*Param);
-return ExprError();
+ParamType = SubstAutoTypeDependent(ParamType);
+assert(!ParamType.isNull() && "substituting DependentTy can't fail");
   }
 }
 // CheckNonTypeTemplateParameterType will produce a diagnostic if there's
@@ -7144,14 +7134,16 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl 
*Param, QualType ParamType,
   // type-dependent, there's nothing we can check now.
   if (ParamType->isDependentType() || DeductionArg->isTypeDependent()) {
 // Force the 

[llvm-branch-commits] [clang] port 5b4819e to release (PR #159209)

2025-09-23 Thread David Blaikie via llvm-branch-commits

dwblaikie wrote:

> Are the test failures legitimate?

sync and merge seems to have cleared them up

https://github.com/llvm/llvm-project/pull/159209
___
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] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)

2025-09-23 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic commented:

LGTM, just some nits

https://github.com/llvm/llvm-project/pull/160184
___
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] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)

2025-09-23 Thread Finn Plummer via llvm-branch-commits


@@ -209,6 +209,12 @@ DXContainerYAML::RootSignatureYamlDesc::create(
 NewS.RegisterSpace = S.RegisterSpace;
 NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);
 
+if (Version > 2) {
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)   
\
+  NewS.Enum =  
\
+  (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)) > 0;

inbelic wrote:

nit: I think the `> 0` comparison is redundant

https://github.com/llvm/llvm-project/pull/160184
___
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] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)

2025-09-23 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic edited 
https://github.com/llvm/llvm-project/pull/160184
___
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] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/159991
___
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/21.x: [SCEV] Don't perform implication checks with many predicates (#158652) (PR #158798)

2025-09-23 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar closed 
https://github.com/llvm/llvm-project/pull/158798
___
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] 6d4bb20 - [X86] Invalid fp16 comparison fix (#160304)

2025-09-23 Thread via llvm-branch-commits

Author: azwolski
Date: 2025-09-23T17:24:59+02:00
New Revision: 6d4bb2088818784c89eea8ecc799852ea48e086b

URL: 
https://github.com/llvm/llvm-project/commit/6d4bb2088818784c89eea8ecc799852ea48e086b
DIFF: 
https://github.com/llvm/llvm-project/commit/6d4bb2088818784c89eea8ecc799852ea48e086b.diff

LOG: [X86] Invalid fp16 comparison fix (#160304)

Missing `VCMPPHZrrik`, `VCMPPHZ128rrik`, and `VCMPPHZ256rrik` opcodes in
`commuteInstructionImpl` and `findCommutedOpIndices` led to improper
handling of compare instruction during optimization. Operands were
commuted, but swapping of the immediate was not called.
 
 Fixes: #159723

Added: 


Modified: 
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/test/CodeGen/X86/pr159723.ll

Removed: 




diff  --git a/llvm/lib/Target/X86/X86InstrInfo.cpp 
b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 58d526269ff3c..497441d8b6f93 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -2573,10 +2573,13 @@ MachineInstr 
*X86InstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI,
   case X86::VCMPPSZ256rri:
   case X86::VCMPPDZrrik:
   case X86::VCMPPSZrrik:
+  case X86::VCMPPHZrrik:
   case X86::VCMPPDZ128rrik:
   case X86::VCMPPSZ128rrik:
+  case X86::VCMPPHZ128rrik:
   case X86::VCMPPDZ256rrik:
   case X86::VCMPPSZ256rrik:
+  case X86::VCMPPHZ256rrik:
 WorkingMI = CloneIfNew(MI);
 WorkingMI->getOperand(MI.getNumExplicitOperands() - 1)
 .setImm(X86::getSwappedVCMPImm(
@@ -2830,10 +2833,13 @@ bool X86InstrInfo::findCommutedOpIndices(const 
MachineInstr &MI,
   case X86::VCMPPSZ256rri:
   case X86::VCMPPDZrrik:
   case X86::VCMPPSZrrik:
+  case X86::VCMPPHZrrik:
   case X86::VCMPPDZ128rrik:
   case X86::VCMPPSZ128rrik:
+  case X86::VCMPPHZ128rrik:
   case X86::VCMPPDZ256rrik:
-  case X86::VCMPPSZ256rrik: {
+  case X86::VCMPPSZ256rrik:
+  case X86::VCMPPHZ256rrik: {
 unsigned OpOffset = X86II::isKMasked(Desc.TSFlags) ? 1 : 0;
 
 // Float comparison can be safely commuted for

diff  --git a/llvm/test/CodeGen/X86/pr159723.ll 
b/llvm/test/CodeGen/X86/pr159723.ll
index cab4abb043639..c66b101fff990 100644
--- a/llvm/test/CodeGen/X86/pr159723.ll
+++ b/llvm/test/CodeGen/X86/pr159723.ll
@@ -17,7 +17,7 @@ define <8 x i1> @test_cmp_v8half_ogt(<8 x half> %rhs, <8 x 
i1> %mask) nounwind {
 ; CHECK-NEXT:kmovw %k1, {{[-0-9]+}}(%r{{[sb]}}p) # 2-byte Spill
 ; CHECK-NEXT:callq test_call_8@PLT
 ; CHECK-NEXT:kmovw {{[-0-9]+}}(%r{{[sb]}}p), %k1 # 2-byte Reload
-; CHECK-NEXT:vcmpltph {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %k0 {%k1} # 16-byte 
Folded Reload
+; CHECK-NEXT:vcmpgtph {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %k0 {%k1} # 16-byte 
Folded Reload
 ; CHECK-NEXT:vpmovm2w %k0, %xmm0
 ; CHECK-NEXT:addq $40, %rsp
 ; CHECK-NEXT:retq
@@ -79,7 +79,7 @@ define <16 x i1> @test_cmp_v16half_olt_commute(<16 x half> 
%rhs, <16 x i1> %mask
 ; CHECK-NEXT:kmovw %k1, {{[-0-9]+}}(%r{{[sb]}}p) # 2-byte Spill
 ; CHECK-NEXT:callq test_call_16@PLT
 ; CHECK-NEXT:kmovw {{[-0-9]+}}(%r{{[sb]}}p), %k1 # 2-byte Reload
-; CHECK-NEXT:vcmpltph {{[-0-9]+}}(%r{{[sb]}}p), %ymm0, %k0 {%k1} # 32-byte 
Folded Reload
+; CHECK-NEXT:vcmpgtph {{[-0-9]+}}(%r{{[sb]}}p), %ymm0, %k0 {%k1} # 32-byte 
Folded Reload
 ; CHECK-NEXT:vpmovm2b %k0, %xmm0
 ; CHECK-NEXT:addq $56, %rsp
 ; CHECK-NEXT:vzeroupper
@@ -100,7 +100,7 @@ define <32 x i1> @test_cmp_v32half_oge(<32 x half> %rhs, 
<32 x i1> %mask) nounwi
 ; CHECK-NEXT:kmovd %k1, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
 ; CHECK-NEXT:callq test_call_32@PLT
 ; CHECK-NEXT:kmovd {{[-0-9]+}}(%r{{[sb]}}p), %k1 # 4-byte Reload
-; CHECK-NEXT:vcmpleph {{[-0-9]+}}(%r{{[sb]}}p), %zmm0, %k0 {%k1} # 64-byte 
Folded Reload
+; CHECK-NEXT:vcmpgeph {{[-0-9]+}}(%r{{[sb]}}p), %zmm0, %k0 {%k1} # 64-byte 
Folded Reload
 ; CHECK-NEXT:vpmovm2b %k0, %ymm0
 ; CHECK-NEXT:addq $88, %rsp
 ; CHECK-NEXT:retq



___
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] 99618de - [Tooling] Simplify a use of std::is_same (NFC) (#160237)

2025-09-23 Thread via llvm-branch-commits

Author: Kazu Hirata
Date: 2025-09-23T08:11:08-07:00
New Revision: 99618dec185e985db4f19ca5e61e00d30b9a8b74

URL: 
https://github.com/llvm/llvm-project/commit/99618dec185e985db4f19ca5e61e00d30b9a8b74
DIFF: 
https://github.com/llvm/llvm-project/commit/99618dec185e985db4f19ca5e61e00d30b9a8b74.diff

LOG: [Tooling] Simplify a use of std::is_same (NFC) (#160237)

std::is_same<...>::type is functionally the same as std::is_same<...>.
This patch removes the redundant ::type at the end.

Added: 


Modified: 
clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h

Removed: 




diff  --git 
a/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h 
b/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
index 3234b0976a8e7..ed2aa55c99279 100644
--- a/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
@@ -37,11 +37,11 @@ namespace internal {
 template  struct HasHandle {
 private:
   template 
-  static auto check(ClassT *) -> typename std::is_same<
-  decltype(std::declval().visit(
-  std::declval(),
-  *std::declval *>())),
-  void>::type;
+  static auto check(ClassT *)
+  -> std::is_same().visit(
+  std::declval(),
+  *std::declval *>())),
+  void>;
 
   template  static std::false_type check(...);
 



___
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] c2fe408 - [ADT] Use list-initialization for returning pairs (#160238)

2025-09-23 Thread via llvm-branch-commits

Author: Kazu Hirata
Date: 2025-09-23T08:11:16-07:00
New Revision: c2fe408dda2977c17f47a4b11433c2244c7cd6dc

URL: 
https://github.com/llvm/llvm-project/commit/c2fe408dda2977c17f47a4b11433c2244c7cd6dc
DIFF: 
https://github.com/llvm/llvm-project/commit/c2fe408dda2977c17f47a4b11433c2244c7cd6dc.diff

LOG: [ADT] Use list-initialization for returning pairs (#160238)

In C++17 and later, "return {A, B};" guarantees copy elision for a
std::pair return type, ensuring the object is constructed directly in
the return slot.  This patch updates those instances under ADT/.

Added: 


Modified: 
llvm/include/llvm/ADT/DenseMapInfo.h
llvm/include/llvm/ADT/STLExtras.h
llvm/include/llvm/ADT/SparseMultiSet.h
llvm/include/llvm/ADT/StringRef.h

Removed: 




diff  --git a/llvm/include/llvm/ADT/DenseMapInfo.h 
b/llvm/include/llvm/ADT/DenseMapInfo.h
index 57a8674e35015..f24aeb4371e7f 100644
--- a/llvm/include/llvm/ADT/DenseMapInfo.h
+++ b/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -139,13 +139,11 @@ struct DenseMapInfo> {
   using SecondInfo = DenseMapInfo;
 
   static constexpr Pair getEmptyKey() {
-return std::make_pair(FirstInfo::getEmptyKey(),
-  SecondInfo::getEmptyKey());
+return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()};
   }
 
   static constexpr Pair getTombstoneKey() {
-return std::make_pair(FirstInfo::getTombstoneKey(),
-  SecondInfo::getTombstoneKey());
+return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()};
   }
 
   static unsigned getHashValue(const Pair& PairVal) {

diff  --git a/llvm/include/llvm/ADT/STLExtras.h 
b/llvm/include/llvm/ADT/STLExtras.h
index 4e7e42e9f4a5f..4a91b061dd3b7 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1371,7 +1371,7 @@ class indexed_accessor_range
   offset_base(const std::pair &base, ptr
diff _t index) {
 // We encode the internal base as a pair of the derived base and a start
 // index into the derived base.
-return std::make_pair(base.first, base.second + index);
+return {base.first, base.second + index};
   }
   /// See `detail::indexed_accessor_range_base` for details.
   static ReferenceT

diff  --git a/llvm/include/llvm/ADT/SparseMultiSet.h 
b/llvm/include/llvm/ADT/SparseMultiSet.h
index cf7603158b28b..0aa7edbcea673 100644
--- a/llvm/include/llvm/ADT/SparseMultiSet.h
+++ b/llvm/include/llvm/ADT/SparseMultiSet.h
@@ -400,7 +400,7 @@ class SparseMultiSet {
   RangePair equal_range(const KeyT &K) {
 iterator B = find(K);
 iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx);
-return std::make_pair(B, E);
+return {B, E};
   }
 
   /// Insert a new element at the tail of the subset list. Returns an iterator

diff  --git a/llvm/include/llvm/ADT/StringRef.h 
b/llvm/include/llvm/ADT/StringRef.h
index 49a52fbe1a6f7..7aee2aa67ddec 100644
--- a/llvm/include/llvm/ADT/StringRef.h
+++ b/llvm/include/llvm/ADT/StringRef.h
@@ -717,8 +717,8 @@ namespace llvm {
 split(StringRef Separator) const {
   size_t Idx = find(Separator);
   if (Idx == npos)
-return std::make_pair(*this, StringRef());
-  return std::make_pair(slice(0, Idx), substr(Idx + Separator.size()));
+return {*this, StringRef()};
+  return {slice(0, Idx), substr(Idx + Separator.size())};
 }
 
 /// Split into two substrings around the last occurrence of a separator
@@ -735,8 +735,8 @@ namespace llvm {
 rsplit(StringRef Separator) const {
   size_t Idx = rfind(Separator);
   if (Idx == npos)
-return std::make_pair(*this, StringRef());
-  return std::make_pair(slice(0, Idx), substr(Idx + Separator.size()));
+return {*this, StringRef()};
+  return {slice(0, Idx), substr(Idx + Separator.size())};
 }
 
 /// Split into substrings around the occurrences of a separator string.



___
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] a3ab719 - [NFC][MC][ARM] Reorder decoder functions N/N (#158767)

2025-09-23 Thread via llvm-branch-commits

Author: Rahul Joshi
Date: 2025-09-23T08:04:25-07:00
New Revision: a3ab7191a73412d5bfe85d416158999b8d5d6e19

URL: 
https://github.com/llvm/llvm-project/commit/a3ab7191a73412d5bfe85d416158999b8d5d6e19
DIFF: 
https://github.com/llvm/llvm-project/commit/a3ab7191a73412d5bfe85d416158999b8d5d6e19.diff

LOG: [NFC][MC][ARM] Reorder decoder functions N/N (#158767)

Move `DecodeT2AddrModeImm8` and `DecodeT2Imm8` definition before its
first use and eliminate the last remaining forward declarations of
decode functions.

Work on https://github.com/llvm/llvm-project/issues/156560 : Reorder ARM
disassembler decode functions to eliminate forward declarations

Added: 


Modified: 
llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp

Removed: 




diff  --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp 
b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index b25b7e7104f20..d358913d38af9 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -157,12 +157,6 @@ class ARMDisassembler : public MCDisassembler {
 
 } // end anonymous namespace
 
-// Forward declare these because the autogenerated code will reference them.
-// Definitions are further down.
-static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
- uint64_t Address,
- const MCDisassembler *Decoder);
-
 typedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val,
 uint64_t Address,
 const MCDisassembler *Decoder);
@@ -3167,6 +3161,65 @@ static DecodeStatus DecodeT2LoadShift(MCInst &Inst, 
unsigned Insn,
   return S;
 }
 
+static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
+ const MCDisassembler *Decoder) {
+  int imm = Val & 0xFF;
+  if (Val == 0)
+imm = INT32_MIN;
+  else if (!(Val & 0x100))
+imm *= -1;
+  Inst.addOperand(MCOperand::createImm(imm));
+
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+  DecodeStatus S = MCDisassembler::Success;
+
+  unsigned Rn = fieldFromInstruction(Val, 9, 4);
+  unsigned imm = fieldFromInstruction(Val, 0, 9);
+
+  // Thumb stores cannot use PC as dest register.
+  switch (Inst.getOpcode()) {
+  case ARM::t2STRT:
+  case ARM::t2STRBT:
+  case ARM::t2STRHT:
+  case ARM::t2STRi8:
+  case ARM::t2STRHi8:
+  case ARM::t2STRBi8:
+if (Rn == 15)
+  return MCDisassembler::Fail;
+break;
+  default:
+break;
+  }
+
+  // Some instructions always use an additive offset.
+  switch (Inst.getOpcode()) {
+case ARM::t2LDRT:
+case ARM::t2LDRBT:
+case ARM::t2LDRHT:
+case ARM::t2LDRSBT:
+case ARM::t2LDRSHT:
+case ARM::t2STRT:
+case ARM::t2STRBT:
+case ARM::t2STRHT:
+  imm |= 0x100;
+  break;
+default:
+  break;
+  }
+
+  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+return MCDisassembler::Fail;
+  if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
+return MCDisassembler::Fail;
+
+  return S;
+}
+
 static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
  uint64_t Address,
  const MCDisassembler *Decoder) {
@@ -3476,18 +3529,6 @@ static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst 
&Inst, unsigned Val,
   return S;
 }
 
-static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
- const MCDisassembler *Decoder) {
-  int imm = Val & 0xFF;
-  if (Val == 0)
-imm = INT32_MIN;
-  else if (!(Val & 0x100))
-imm *= -1;
-  Inst.addOperand(MCOperand::createImm(imm));
-
-  return MCDisassembler::Success;
-}
-
 template 
 static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, uint64_t Address,
  const MCDisassembler *Decoder) {
@@ -3503,53 +3544,6 @@ static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned 
Val, uint64_t Address,
   return MCDisassembler::Success;
 }
 
-static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
- uint64_t Address,
- const MCDisassembler *Decoder) {
-  DecodeStatus S = MCDisassembler::Success;
-
-  unsigned Rn = fieldFromInstruction(Val, 9, 4);
-  unsigned imm = fieldFromInstruction(Val, 0, 9);
-
-  // Thumb stores cannot use PC as dest register.
-  switch (Inst.getOpcode()) {
-  case ARM::t2STRT:
-  case ARM::t2STRBT:
-  case ARM::t2STRHT:
-  case ARM::t2STRi8:
-  case ARM::t2STRHi8:
-  case ARM::t2STRBi8:
-if (Rn == 15)
-  return MCDisassembler::Fail;
-  

[llvm-branch-commits] [clang] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Gábor Horváth via llvm-branch-commits


@@ -371,3 +371,152 @@ void no_error_if_dangle_then_rescue_gsl() {
   v = safe;// 'v' is "rescued" before use by reassigning to a valid object.
   v.use(); // This is safe.
 }
+
+
+//===--===//
+// Lifetimebound Attribute Tests
+//===--===//
+
+View Identity(View v [[clang::lifetimebound]]);
+View Choose(bool cond, View a [[clang::lifetimebound]], View b 
[[clang::lifetimebound]]);
+MyObj* GetPointer(const MyObj& obj [[clang::lifetimebound]]);
+
+struct [[gsl::Pointer()]] LifetimeBoundView {
+  LifetimeBoundView();
+  LifetimeBoundView(const MyObj& obj [[clang::lifetimebound]]);
+  LifetimeBoundView pass() [[clang::lifetimebound]] { return *this; }
+  operator View() const [[clang::lifetimebound]];
+};
+
+void lifetimebound_simple_function() {
+  View v;
+  {
+MyObj obj;
+v = Identity(obj); // expected-warning {{object whose reference is 
captured does not live long enough}}
+  }// expected-note {{destroyed here}}
+  v.use(); // expected-note {{later used here}}
+}
+
+void lifetimebound_multiple_args_definite() {
+  View v;
+  {
+MyObj obj1, obj2;
+v = Choose(true,
+   obj1,  // expected-warning {{object whose reference is captured 
does not live long enough}}
+   obj2); // expected-warning {{object whose reference is captured 
does not live long enough}}
+  }  // expected-note 2 {{destroyed here}}
+  v.use();   // expected-note 2 {{later used here}}
+}
+
+void lifetimebound_multiple_args_potential(bool cond) {
+  MyObj safe;
+  View v = safe;
+  {
+MyObj obj1;
+if (cond) {
+  MyObj obj2;
+  v = Choose(true, 
+ obj1, // expected-warning {{object whose 
reference is captured may not live long enough}}
+ obj2);// expected-warning {{object whose 
reference is captured may not live long enough}}
+}  // expected-note {{destroyed here}}
+  }// expected-note {{destroyed here}}
+  v.use(); // expected-note 2 {{later used here}}
+}
+
+View SelectFirst(View a [[clang::lifetimebound]], View b);
+void lifetimebound_mixed_args() {
+  View v;
+  {
+MyObj obj1, obj2;
+v = SelectFirst(obj1,// expected-warning {{object whose reference 
is captured does not live long enough}}
+obj2);
+  }  // expected-note {{destroyed here}}
+  v.use();   // expected-note {{later used here}}
+}
+
+void lifetimebound_member_function() {
+  LifetimeBoundView lbv, lbv2;
+  {
+MyObj obj;
+lbv = obj;// expected-warning {{object whose reference is captured 
does not live long enough}}
+lbv2 = lbv.pass();
+  }   // expected-note {{destroyed here}}
+  View v = lbv2;  // expected-note {{later used here}}
+  v.use();
+}
+
+void lifetimebound_conversion_operator() {
+  View v;
+  {
+MyObj obj;
+LifetimeBoundView lbv = obj; // expected-warning {{object whose reference 
is captured does not live long enough}}
+v = lbv; // Conversion operator is lifetimebound
+  }  // expected-note {{destroyed here}}
+  v.use();   // expected-note {{later used here}}
+}
+
+void lifetimebound_chained_calls() {
+  View v;
+  {
+MyObj obj;
+v = Identity(Identity(Identity(obj))); // expected-warning {{object whose 
reference is captured does not live long enough}}
+  }// expected-note {{destroyed here}}
+  v.use(); // expected-note {{later used here}}
+}
+
+void lifetimebound_with_pointers() {
+  MyObj* ptr;
+  {
+MyObj obj;
+ptr = GetPointer(obj); // expected-warning {{object whose reference is 
captured does not live long enough}}
+  }// expected-note {{destroyed here}}
+  (void)*ptr;  // expected-note {{later used here}}
+}
+
+void lifetimebound_no_error_safe_usage() {
+  MyObj obj;
+  View v1 = Identity(obj);  // No warning - obj lives long enough
+  View v2 = Choose(true, v1, Identity(obj)); // No warning - all args are safe
+  v2.use(); // Safe usage
+}
+
+void lifetimebound_partial_safety(bool cond) {
+  MyObj safe_obj;
+  View v = safe_obj;
+  
+  if (cond) {
+MyObj temp_obj;
+v = Choose(true, 
+   safe_obj,
+   temp_obj); // expected-warning {{object whose reference is 
captured may not live long enough}}
+  }   // expected-note {{destroyed here}}
+  v.use();// expected-note {{later used here}}
+}
+
+// FIXME: Creating reference from lifetimebound call doesn't propagate loans.
+const MyObj& GetObject(View v [[clang::lifet

[llvm-branch-commits] [clang] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Gábor Horváth via llvm-branch-commits


@@ -353,6 +366,23 @@ class UseFact : public Fact {
   }
 };
 
+class KillOriginFact : public Fact {

Xazax-hun wrote:

Do we still need this now that `OriginFlowFact` has a `KillDest`?

https://github.com/llvm/llvm-project/pull/158489
___
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] 2800ac2 - [Support] Use "inline static" to initialize Registry (NFC) (#160235)

2025-09-23 Thread via llvm-branch-commits

Author: Kazu Hirata
Date: 2025-09-23T08:11:00-07:00
New Revision: 2800ac203cba9e82f31334ff5439b9a91f7444fa

URL: 
https://github.com/llvm/llvm-project/commit/2800ac203cba9e82f31334ff5439b9a91f7444fa
DIFF: 
https://github.com/llvm/llvm-project/commit/2800ac203cba9e82f31334ff5439b9a91f7444fa.diff

LOG: [Support] Use "inline static" to initialize Registry (NFC) (#160235)

In C++17, we can initialize a static member variable with "inline
static" as part of the class definition.  With this, we can eliminate
the out-of-line static initializers involving boilerplate template
code.

Added: 


Modified: 
llvm/include/llvm/Support/Registry.h

Removed: 




diff  --git a/llvm/include/llvm/Support/Registry.h 
b/llvm/include/llvm/Support/Registry.h
index ff9226c39359c..c02f15e5e32b8 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -58,8 +58,8 @@ namespace llvm {
 // declaration causing error C2487 "member of dll interface class may not
 // be declared with dll interface".
 // 
https://developercommunity.visualstudio.com/t/c2487-in-dllexport-class-with-static-members/69878
-static node *Head;
-static node *Tail;
+static inline node *Head = nullptr;
+static inline node *Tail = nullptr;
 
   public:
 /// Node in linked list of entries.
@@ -143,19 +143,11 @@ namespace llvm {
 /// Instantiate a registry class.
 #define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS)  
\
   namespace llvm { 
\
-  template 
\
-  typename Registry::node *Registry::Head = nullptr; 
\
-  template 
\
-  typename Registry::node *Registry::Tail = nullptr; 
\
   template class LLVM_ABI_EXPORT Registry;   
\
   }
 #else
 #define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS)  
\
   namespace llvm { 
\
-  template 
\
-  typename Registry::node *Registry::Head = nullptr; 
\
-  template 
\
-  typename Registry::node *Registry::Tail = nullptr; 
\
   template class Registry;   
\
   }
 #endif



___
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] [LV] Add ExtNegatedMulAccReduction expression type (PR #160154)

2025-09-23 Thread Sander de Smalen via llvm-branch-commits


@@ -3012,6 +3018,11 @@ class VPExpressionRecipe : public VPSingleDefRecipe {
  VPWidenRecipe *Mul, VPReductionRecipe *Red)
   : VPExpressionRecipe(ExpressionTypes::ExtMulAccReduction,
{Ext0, Ext1, Mul, Red}) {}
+  VPExpressionRecipe(VPWidenCastRecipe *Ext0, VPWidenCastRecipe *Ext1,
+ VPWidenRecipe *Mul, VPWidenRecipe *Sub,
+ VPReductionRecipe *Red)
+  : VPExpressionRecipe(ExpressionTypes::ExtNegatedMulAccReduction,
+   {Ext0, Ext1, Mul, Sub, Red}) {}

sdesmalen-arm wrote:

I think this should assert that `Red` is an `add`, `Sub` is a `sub(0, ...)` and 
`Mul` is a `Instruction::Mul`

https://github.com/llvm/llvm-project/pull/160154
___
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] [LV] Add ExtNegatedMulAccReduction expression type (PR #160154)

2025-09-23 Thread Sander de Smalen via llvm-branch-commits


@@ -3524,14 +3524,22 @@ 
tryToMatchAndCreateMulAccumulateReduction(VPReductionRecipe *Red,
   };
 
   VPValue *VecOp = Red->getVecOp();
+  VPValue *Mul = nullptr;
+  VPValue *Sub = nullptr;
   VPValue *A, *B;
+  // Sub reductions could have a sub between the add reduction and vec op.
+  if (match(VecOp,
+m_Binary(m_SpecificInt(0), m_VPValue(Mul
+Sub = VecOp;
+  else
+Mul = VecOp;

sdesmalen-arm wrote:

There is a lot of renaming going on, making this change a lot bigger than it 
should be. If you would write:
```
VPValue *Sub = nullptr;
// Sub reductions could have a sub between the add reduction and vec op.
if (match(VecOp,
  m_Binary(m_SpecificInt(0), m_VPValue(VecOp
  Sub = Red->getVecOp();
```
Then you can do away with the changes that just rename `VecOp` -> `Mul` and 
`Mul -> MulR`.

I mentioned this in a previous review, but this suggestion somehow got reverted 
again. 

https://github.com/llvm/llvm-project/pull/160154
___
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] [LV] Add ExtNegatedMulAccReduction expression type (PR #160154)

2025-09-23 Thread Sander de Smalen via llvm-branch-commits


@@ -2989,6 +2989,12 @@ class VPExpressionRecipe : public VPSingleDefRecipe {
 /// vector operands, performing a reduction.add on the result, and adding
 /// the scalar result to a chain.
 MulAccReduction,
+/// Represent an inloop multiply-accumulate reduction, multiplying the
+/// extended vector operands, negating the multiplication, performing a
+/// reduction.add
+/// on the result, and adding
+/// the scalar result to a chain.

sdesmalen-arm wrote:

nit: strange formatting

https://github.com/llvm/llvm-project/pull/160154
___
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] [LV] Add ExtNegatedMulAccReduction expression type (PR #160154)

2025-09-23 Thread Sander de Smalen via llvm-branch-commits


@@ -2861,12 +2861,17 @@ InstructionCost 
VPExpressionRecipe::computeCost(ElementCount VF,
 return Ctx.TTI.getMulAccReductionCost(false, Opcode, RedTy, SrcVecTy,
   Ctx.CostKind);
 
-  case ExpressionTypes::ExtMulAccReduction:
+  case ExpressionTypes::ExtNegatedMulAccReduction:
+  case ExpressionTypes::ExtMulAccReduction: {
+if (ExpressionType == ExpressionTypes::ExtNegatedMulAccReduction &&
+Opcode == Instruction::Add)
+  Opcode = Instruction::Sub;

sdesmalen-arm wrote:

Does it ever happen that `Opcode != Instruction::Add`? If not, this should be 
written as:

```suggestion
  case ExpressionTypes::ExtNegatedMulAccReduction:
  assert(Opcode == Instruction::Add && "Unexpected opcode");
  Opcode = Instruction::Sub;
  LLVM_FALLTHROUGH;
  case ExpressionTypes::ExtMulAccReduction:
```

https://github.com/llvm/llvm-project/pull/160154
___
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] [llvm-remarkutil] Introduce filter command (PR #159784)

2025-09-23 Thread Florian Hahn via llvm-branch-commits


@@ -14,6 +14,7 @@
 #include "RemarkUtilHelpers.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/Support/Regex.h"
+#include 

fhahn wrote:

why do we need to pull this in here now?

https://github.com/llvm/llvm-project/pull/159784
___
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] [llvm-remarkutil] Introduce filter command (PR #159784)

2025-09-23 Thread Florian Hahn via llvm-branch-commits


@@ -0,0 +1,84 @@
+//===- RemarkFilter.cpp 
---===//
+//
+// 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
+//
+//===--===//
+//
+// Generic tool to filter remarks
+//
+//===--===//
+
+#include "RemarkUtilHelpers.h"
+#include "RemarkUtilRegistry.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
+
+using namespace llvm;
+using namespace remarks;
+using namespace llvm::remarkutil;
+
+namespace filter {
+
+static cl::SubCommand FilterSub("filter",
+"Filter remarks based on specified criteria.");
+
+INPUT_FORMAT_COMMAND_LINE_OPTIONS(FilterSub)
+OUTPUT_FORMAT_COMMAND_LINE_OPTIONS(FilterSub)
+INPUT_OUTPUT_COMMAND_LINE_OPTIONS(FilterSub)
+REMARK_FILTER_COMMAND_LINE_OPTIONS(FilterSub)
+
+REMARK_FILTER_SETUP_FUNC()
+
+static Error tryFilter() {
+  auto MaybeFilter = getRemarkFilters();
+  if (!MaybeFilter)
+return MaybeFilter.takeError();
+  Filters &Filter = *MaybeFilter;
+
+  auto MaybeBuf = getInputMemoryBuffer(InputFileName);
+  if (!MaybeBuf)
+return MaybeBuf.takeError();
+  auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());
+  if (!MaybeParser)
+return MaybeParser.takeError();
+  auto &Parser = **MaybeParser;
+
+  Format SerializerFormat = OutputFormat;
+  if (SerializerFormat == Format::Auto) {
+SerializerFormat = Parser.ParserFormat;
+if (OutputFileName.empty() || OutputFileName == "-")
+  SerializerFormat = Format::YAML;
+  }
+
+  auto MaybeOF = getOutputFileForRemarks(OutputFileName, SerializerFormat);
+  if (!MaybeOF)
+return MaybeOF.takeError();
+  auto OF = std::move(*MaybeOF);
+
+  auto MaybeSerializer = createRemarkSerializer(SerializerFormat, OF->os());
+  if (!MaybeSerializer)
+return MaybeSerializer.takeError();
+  auto &Serializer = **MaybeSerializer;
+
+  auto MaybeRemark = Parser.next();
+  for (; MaybeRemark; MaybeRemark = Parser.next()) {
+Remark &Remark = **MaybeRemark;
+if (!Filter.filterRemark(Remark))
+  continue;
+Serializer.emit(Remark);
+  }

fhahn wrote:

would it be possible to create a iterator adopter that takes a parser and 
returns an iterator over filtered remarks and use it here and in 
RemarkCounter.cpp

https://github.com/llvm/llvm-project/pull/159784
___
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] SIMemoryLegalizer: Factor out check if memory operations can affect the global AS (PR #160129)

2025-09-23 Thread Fabian Ritter via llvm-branch-commits

https://github.com/ritter-x2a updated 
https://github.com/llvm/llvm-project/pull/160129

>From 9c10c3e64323070347be3cef1baec7bf9b062ba1 Mon Sep 17 00:00:00 2001
From: Fabian Ritter 
Date: Mon, 22 Sep 2025 11:20:16 -0400
Subject: [PATCH 1/2] [AMDGPU] SIMemoryLegalizer: Factor out check if memory
 operations can affect the global AS

Mostly NFC, and adds an assertion for gfx12 to ensure that no atomic scratch
instructions are present in the case of GloballyAddressableScratch. This should
always hold because of #154710.
---
 llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp | 53 +---
 1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp 
b/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
index c85d2bb9fe9ae..23133b28a4af8 100644
--- a/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
@@ -299,6 +299,10 @@ class SICacheControl {
   bool enableNamedBit(const MachineBasicBlock::iterator MI,
   AMDGPU::CPol::CPol Bit) const;
 
+  /// Check if any atomic operation on AS can affect memory accessible via the
+  /// global address space.
+  virtual bool canAffectGlobalAddrSpace(SIAtomicAddrSpace AS) const = 0;
+
 public:
 
   /// Create a cache control for the subtarget \p ST.
@@ -403,6 +407,10 @@ class SIGfx6CacheControl : public SICacheControl {
 return enableNamedBit(MI, AMDGPU::CPol::SLC);
   }
 
+  bool canAffectGlobalAddrSpace(SIAtomicAddrSpace AS) const override {
+return (AS & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE;
+  }
+
 public:
 
   SIGfx6CacheControl(const GCNSubtarget &ST) : SICacheControl(ST) {}
@@ -609,6 +617,15 @@ class SIGfx12CacheControl : public SIGfx11CacheControl {
   bool setAtomicScope(const MachineBasicBlock::iterator &MI,
   SIAtomicScope Scope, SIAtomicAddrSpace AddrSpace) const;
 
+  bool canAffectGlobalAddrSpace(SIAtomicAddrSpace AS) const override {
+assert((!ST.hasGloballyAddressableScratch() ||
+((AS & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) ||
+(AS & SIAtomicAddrSpace::SCRATCH) == SIAtomicAddrSpace::NONE) &&
+   "scratch instructions should already be replaced by flat "
+   "instructions if GloballyAddressableScratch is enabled");
+return (AS & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE;
+  }
+
 public:
   SIGfx12CacheControl(const GCNSubtarget &ST) : SIGfx11CacheControl(ST) {
 // GFX12.0 and GFX12.5 memory models greatly overlap, and in some cases
@@ -1016,7 +1033,7 @@ bool SIGfx6CacheControl::enableLoadCacheBypass(
   assert(MI->mayLoad() && !MI->mayStore());
   bool Changed = false;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1239,7 +1256,7 @@ bool 
SIGfx6CacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1299,7 +1316,7 @@ bool 
SIGfx7CacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1336,7 +1353,7 @@ bool SIGfx90ACacheControl::enableLoadCacheBypass(
   assert(MI->mayLoad() && !MI->mayStore());
   bool Changed = false;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1378,7 +1395,7 @@ bool SIGfx90ACacheControl::enableRMWCacheBypass(
   assert(MI->mayLoad() && MI->mayStore());
   bool Changed = false;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1487,7 +1504,7 @@ bool 
SIGfx90ACacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
   // Ensures that following loads will not see stale remote VMEM data or
@@ -1551,7 +1568,7 @@ bool 
SIGfx90ACacheControl::insertRelease(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {

[llvm-branch-commits] [clang] [Clang] Introduce -fsanitize=alloc-token (PR #156839)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -726,6 +726,7 @@ SanitizerMask BareMetal::getSupportedSanitizers() const {
   Res |= SanitizerKind::SafeStack;
   Res |= SanitizerKind::Thread;
   Res |= SanitizerKind::Scudo;
+  Res |= SanitizerKind::AllocToken;

zmodem wrote:

Can't we just add this in the base class (ToolChain::getSupportedSanitizers)?

https://github.com/llvm/llvm-project/pull/156839
___
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] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Gábor Horváth via llvm-branch-commits


@@ -0,0 +1,35 @@
+//===- LifetimeAnnotations.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
+//
+//===--===//
+// Helper functions to inspect and infer lifetime annotations.
+//===--===//
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
+
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+namespace lifetimes {
+
+const FunctionDecl *getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl 
*FD);
+
+const CXXMethodDecl *
+getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD);
+
+// Return true if this is an "normal" assignment operator.
+// We assume that a normal assignment operator always returns *this, that is,
+// an lvalue reference that is the same type as the implicit object parameter
+// (or the LHS for a non-member operator$=).
+bool isNormalAssignmentOperator(const FunctionDecl *FD);
+
+bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD);
+
+bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD);
+} // namespace lifetimes
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H

Xazax-hun wrote:

Nit: missing new line. 

https://github.com/llvm/llvm-project/pull/158489
___
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] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/159991

>From 73f7069f9100441ccb3027b0890284b5d7fcf80e Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy

---
 .../clang/Analysis/Analyses/LifetimeSafety.h  |   9 +-
 clang/lib/Analysis/LifetimeSafety.cpp | 392 +++---
 clang/test/Sema/warn-lifetime-safety.cpp  | 141 +++--
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
 4 files changed, 583 insertions(+), 460 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..2cc3fb3d69eb4 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -55,6 +55,7 @@ class Fact;
 class FactManager;
 class LoanPropagationAnalysis;
 class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
 struct LifetimeFactory;
 
 /// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
OriginID ID) {
 // TODO(opt): Consider using a bitset to represent the set of loans.
 using LoanSet = llvm::ImmutableSet;
 using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
 /// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,9 @@ class LifetimeSafetyAnalysis {
   /// Returns the set of loans an origin holds at a specific program point.
   LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
 
-  /// Returns the set of loans that have expired at a specific program point.
-  std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+  /// TODO:Document.
+  std::vector>
+  getLiveOriginsAtPoint(ProgramPoint PP) const;
 
   /// Finds the OriginID for a given declaration.
   /// Returns a null optional if not found.
@@ -138,7 +141,7 @@ class LifetimeSafetyAnalysis {
   std::unique_ptr Factory;
   std::unique_ptr FactMgr;
   std::unique_ptr LoanPropagation;
-  std::unique_ptr ExpiredLoans;
+  std::unique_ptr LiveOrigins;
 };
 } // namespace internal
 } // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety.cpp
index 14fb945382e65..01076a3cee7f2 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeProfiler.h"
 #include 
 #include 
@@ -873,19 +874,26 @@ class DataflowAnalysis {
 llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
 
 while (const CFGBlock *B = W.dequeue()) {
-  Lattice StateIn = getInState(B);
+  Lattice StateIn = *getInState(B);
   Lattice StateOut = transferBlock(B, StateIn);
   OutStates[B] = StateOut;
-  Visited.set(B->getBlockID());
   for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
 if (!AdjacentB)
   continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
+  OldInState = *In;
+  NewInState = D.join(OldInState, StateOut);
+} else {
+  OldInState = D.getInitialState();
+  SawFirstTime = true;
+  NewInState = StateOut;
+}
 // Enqueue the adjacent block if its in-state has changed or if we have
 // never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+if (SawFirstTime || NewInState != OldInState) {
   InStates[AdjacentB] = NewInState;
   W.enqueueBlock(AdjacentB);
 }
@@ -896,7 +904,12 @@ class DataflowAnalysis {
 protected:
   Lattice getState(ProgramPoint P) const { return PerPointStates.lookup(P); }
 
-  Lattice getInState(const CFGBlock *B) const { return InStates.lookup(B); }
+  const Lattice *getInState(const CFGBlock *B) const {
+auto It = InStates.find(B);
+if (It != InStates.end())
+  return &It->second;
+return nullptr;
+  }
 
   Lattice getOutState(const CFGBlock *B) const { return OutStates.lookup(B); }
 
@@ -992,22 +1005,26 @@ static bool isSubsetOf(const llvm::ImmutableSet &A,
 // instead of the current AVL-tree-based ImmutableMap.
 template 
 static llvm::ImmutableMap
-join(llvm::ImmutableMap A, llvm::ImmutableMap B,
+join(const llvm::ImmutableMap &A, const llvm::ImmutableMap &B,
  typename llvm::ImmutableMap::Factory &F, Joiner JoinValues) {
   if (A.getHeight() < B.getHeight())
-std::swap(A, B);

[llvm-branch-commits] [clang] [HLSL] NonUniformResourceIndex implementation (PR #159655)

2025-09-23 Thread Helena Kotas via llvm-branch-commits

https://github.com/hekota closed 
https://github.com/llvm/llvm-project/pull/159655
___
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] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits


@@ -353,6 +366,23 @@ class UseFact : public Fact {
   }
 };
 
+class KillOriginFact : public Fact {

usx95 wrote:

Makes sense to reuse it for this purpose.

https://github.com/llvm/llvm-project/pull/158489
___
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] [llvm][mustache] Avoid excessive hash lookups in EscapeStringStream (PR #160166)

2025-09-23 Thread Paul Kirth via llvm-branch-commits

ilovepi wrote:

> In these tests, at which point are you constructing the std::array? Is it 
> inside each EscapeStream or once when Template is constructed?
> 

Once when the template is constructed. I used a function w/ a static variable 
to provide the default escapes.

> It's possible that `std::array` wasn't the right suggestion -- maybe the fact 
> that it stores std::string makes it too large. But if you check what 
> find_first_of actually does
> 
> https://github.com/llvm/llvm-project/blob/ebcf1bf2ecba6b25ece3c2bbddb4485e76189387/llvm/lib/Support/StringRef.cpp#L240-L242
> 
> it will just take that string of characters you pass it an convert it into a 
> bitset. We may as well directly create the bitset instead of creating the 
> char string and then converting it to a bit set on every call.

Could be. I think the big win is that when we use find_first_of we pass a big 
stringref to the output stream instead of passing in one string at a time. 
There's no copy, and the number of iterations where we write to the stream is 
reduced.

https://github.com/llvm/llvm-project/pull/160166
___
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] SIMemoryLegalizer: Factor out check if memory operations can affect the global AS (PR #160129)

2025-09-23 Thread Fabian Ritter via llvm-branch-commits

https://github.com/ritter-x2a updated 
https://github.com/llvm/llvm-project/pull/160129

>From 8e61a9cceb44edcec4a7e2bf7d5d732753899ac6 Mon Sep 17 00:00:00 2001
From: Fabian Ritter 
Date: Mon, 22 Sep 2025 11:20:16 -0400
Subject: [PATCH 1/2] [AMDGPU] SIMemoryLegalizer: Factor out check if memory
 operations can affect the global AS

Mostly NFC, and adds an assertion for gfx12 to ensure that no atomic scratch
instructions are present in the case of GloballyAddressableScratch. This should
always hold because of #154710.
---
 llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp | 53 +---
 1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp 
b/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
index dc9c961e7de36..f807764e367f7 100644
--- a/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
@@ -299,6 +299,10 @@ class SICacheControl {
   bool enableNamedBit(const MachineBasicBlock::iterator MI,
   AMDGPU::CPol::CPol Bit) const;
 
+  /// Check if any atomic operation on AS can affect memory accessible via the
+  /// global address space.
+  virtual bool canAffectGlobalAddrSpace(SIAtomicAddrSpace AS) const = 0;
+
 public:
 
   /// Create a cache control for the subtarget \p ST.
@@ -403,6 +407,10 @@ class SIGfx6CacheControl : public SICacheControl {
 return enableNamedBit(MI, AMDGPU::CPol::SLC);
   }
 
+  bool canAffectGlobalAddrSpace(SIAtomicAddrSpace AS) const override {
+return (AS & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE;
+  }
+
 public:
 
   SIGfx6CacheControl(const GCNSubtarget &ST) : SICacheControl(ST) {}
@@ -609,6 +617,15 @@ class SIGfx12CacheControl : public SIGfx11CacheControl {
   bool setAtomicScope(const MachineBasicBlock::iterator &MI,
   SIAtomicScope Scope, SIAtomicAddrSpace AddrSpace) const;
 
+  bool canAffectGlobalAddrSpace(SIAtomicAddrSpace AS) const override {
+assert((!ST.hasGloballyAddressableScratch() ||
+((AS & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) ||
+(AS & SIAtomicAddrSpace::SCRATCH) == SIAtomicAddrSpace::NONE) &&
+   "scratch instructions should already be replaced by flat "
+   "instructions if GloballyAddressableScratch is enabled");
+return (AS & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE;
+  }
+
 public:
   SIGfx12CacheControl(const GCNSubtarget &ST) : SIGfx11CacheControl(ST) {
 // GFX12.0 and GFX12.5 memory models greatly overlap, and in some cases
@@ -1016,7 +1033,7 @@ bool SIGfx6CacheControl::enableLoadCacheBypass(
   assert(MI->mayLoad() && !MI->mayStore());
   bool Changed = false;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1239,7 +1256,7 @@ bool 
SIGfx6CacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1299,7 +1316,7 @@ bool 
SIGfx7CacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1336,7 +1353,7 @@ bool SIGfx90ACacheControl::enableLoadCacheBypass(
   assert(MI->mayLoad() && !MI->mayStore());
   bool Changed = false;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1378,7 +1395,7 @@ bool SIGfx90ACacheControl::enableRMWCacheBypass(
   assert(MI->mayLoad() && MI->mayStore());
   bool Changed = false;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
 case SIAtomicScope::AGENT:
@@ -1487,7 +1504,7 @@ bool 
SIGfx90ACacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {
 case SIAtomicScope::SYSTEM:
   // Ensures that following loads will not see stale remote VMEM data or
@@ -1551,7 +1568,7 @@ bool 
SIGfx90ACacheControl::insertRelease(MachineBasicBlock::iterator &MI,
   if (Pos == Position::AFTER)
 ++MI;
 
-  if ((AddrSpace & SIAtomicAddrSpace::GLOBAL) != SIAtomicAddrSpace::NONE) {
+  if (canAffectGlobalAddrSpace(AddrSpace)) {
 switch (Scope) {

[llvm-branch-commits] [llvm] [mlir] [flang][OpenMP] Support multi-block reduction combiner regions on the GPU (PR #156837)

2025-09-23 Thread Kareem Ergawy via llvm-branch-commits

https://github.com/ergawy updated 
https://github.com/llvm/llvm-project/pull/156837

>From b57797c27fcf88101be08767a5a28475db6187d0 Mon Sep 17 00:00:00 2001
From: ergawy 
Date: Thu, 4 Sep 2025 01:06:21 -0500
Subject: [PATCH 1/3] [flang][OpenMP] Support multi-block reduction combiner 
 regions on the GPU

Fixes a bug related to insertion points when inlining multi-block
combiner reduction regions. The IP at the end of the inlined region was
not used resulting in emitting BBs with multiple terminators.
---
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp |  3 +
 .../omptarget-multi-block-reduction.mlir  | 85 +++
 2 files changed, 88 insertions(+)
 create mode 100644 mlir/test/Target/LLVMIR/omptarget-multi-block-reduction.mlir

diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp 
b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 220eee3cb8b08..b516c3c3f4efe 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -3507,6 +3507,8 @@ Expected 
OpenMPIRBuilder::createReductionFunction(
 return AfterIP.takeError();
   if (!Builder.GetInsertBlock())
 return ReductionFunc;
+
+  Builder.SetInsertPoint(AfterIP->getBlock(), AfterIP->getPoint());
   Builder.CreateStore(Reduced, LHSPtr);
 }
   }
@@ -3751,6 +3753,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy 
OpenMPIRBuilder::createReductionsGPU(
   RI.ReductionGen(Builder.saveIP(), RHSValue, LHSValue, Reduced);
   if (!AfterIP)
 return AfterIP.takeError();
+  Builder.SetInsertPoint(AfterIP->getBlock(), AfterIP->getPoint());
   Builder.CreateStore(Reduced, LHS, false);
 }
   }
diff --git a/mlir/test/Target/LLVMIR/omptarget-multi-block-reduction.mlir 
b/mlir/test/Target/LLVMIR/omptarget-multi-block-reduction.mlir
new file mode 100644
index 0..aaf06d2d0e0c2
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/omptarget-multi-block-reduction.mlir
@@ -0,0 +1,85 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// Verifies that the IR builder can handle reductions with multi-block combiner
+// regions on the GPU.
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<"dlti.alloca_memory_space" = 5 
: ui64, "dlti.global_memory_space" = 1 : ui64>, llvm.target_triple = 
"amdgcn-amd-amdhsa", omp.is_gpu = true, omp.is_target_device = true} {
+  llvm.func @bar() {}
+  llvm.func @baz() {}
+
+  omp.declare_reduction @add_reduction_byref_box_5xf32 : !llvm.ptr alloc {
+%0 = llvm.mlir.constant(1 : i64) : i64
+%1 = llvm.alloca %0 x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 
x array<3 x i64>>)> : (i64) -> !llvm.ptr<5>
+%2 = llvm.addrspacecast %1 : !llvm.ptr<5> to !llvm.ptr
+omp.yield(%2 : !llvm.ptr)
+  } init {
+  ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
+omp.yield(%arg1 : !llvm.ptr)
+  } combiner {
+  ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
+llvm.call @bar() : () -> ()
+llvm.br ^bb3
+
+  ^bb3:  // pred: ^bb1
+llvm.call @baz() : () -> ()
+omp.yield(%arg0 : !llvm.ptr)
+  }
+  llvm.func @foo_() {
+%c1 = llvm.mlir.constant(1 : i64) : i64
+%10 = llvm.alloca %c1 x !llvm.array<5 x f32> {bindc_name = "x"} : (i64) -> 
!llvm.ptr<5>
+%11 = llvm.addrspacecast %10 : !llvm.ptr<5> to !llvm.ptr
+%74 = omp.map.info var_ptr(%11 : !llvm.ptr, !llvm.array<5 x f32>) 
map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "x"}
+omp.target map_entries(%74 -> %arg0 : !llvm.ptr) {
+  %c1_2 = llvm.mlir.constant(1 : i32) : i32
+  %c10 = llvm.mlir.constant(10 : i32) : i32
+  omp.teams reduction(byref @add_reduction_byref_box_5xf32 %arg0 -> %arg2 
: !llvm.ptr) {
+omp.parallel {
+  omp.distribute {
+omp.wsloop {
+  omp.loop_nest (%arg5) : i32 = (%c1_2) to (%c10) inclusive step 
(%c1_2) {
+omp.yield
+  }
+} {omp.composite}
+  } {omp.composite}
+  omp.terminator
+} {omp.composite}
+omp.terminator
+  }
+  omp.terminator
+}
+llvm.return
+  }
+}
+
+// CHECK:  call void @__kmpc_parallel_51({{.*}}, i32 1, i32 -1, i32 -1,
+// CHECK-SAME:   ptr @[[PAR_OUTLINED:.*]], ptr null, ptr %2, i64 1)
+
+// CHECK: define internal void @[[PAR_OUTLINED]]{{.*}} {
+// CHECK:   .omp.reduction.then:
+// CHECK: br label %omp.reduction.nonatomic.body
+
+// CHECK:   omp.reduction.nonatomic.body:
+// CHECK: call void @bar()
+// CHECK: br label %[[BODY_2ND_BB:.*]]
+
+// CHECK:   [[BODY_2ND_BB]]:
+// CHECK: call void @baz()
+// CHECK: br label %[[CONT_BB:.*]]
+
+// CHECK:   [[CONT_BB]]:
+// CHECK: br label %.omp.reduction.done
+// CHECK: }
+
+// CHECK: define internal void @"{{.*}}$reduction$reduction_func"(ptr noundef 
%0, ptr noundef %1) #0 {
+// CHECK: br label %omp.reduction.nonatomic.body
+
+// CHECK:   [[BODY_2ND_BB:.*]]:
+// CHECK: call void @baz()
+// CHECK: br label %omp.region.cont
+
+
+// CHECK: omp.reduction.nonatomic.body:
+// CHECK:   call void @b

[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/159991

>From f49485d0faf49de565a1db8cde342b9ba68a9d6c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy

---
 .../clang/Analysis/Analyses/LifetimeSafety.h  |   9 +-
 clang/lib/Analysis/LifetimeSafety.cpp | 386 +++---
 clang/test/Sema/warn-lifetime-safety.cpp  | 141 +++--
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
 4 files changed, 577 insertions(+), 460 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..2cc3fb3d69eb4 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -55,6 +55,7 @@ class Fact;
 class FactManager;
 class LoanPropagationAnalysis;
 class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
 struct LifetimeFactory;
 
 /// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
OriginID ID) {
 // TODO(opt): Consider using a bitset to represent the set of loans.
 using LoanSet = llvm::ImmutableSet;
 using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
 /// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,9 @@ class LifetimeSafetyAnalysis {
   /// Returns the set of loans an origin holds at a specific program point.
   LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
 
-  /// Returns the set of loans that have expired at a specific program point.
-  std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+  /// TODO:Document.
+  std::vector>
+  getLiveOriginsAtPoint(ProgramPoint PP) const;
 
   /// Finds the OriginID for a given declaration.
   /// Returns a null optional if not found.
@@ -138,7 +141,7 @@ class LifetimeSafetyAnalysis {
   std::unique_ptr Factory;
   std::unique_ptr FactMgr;
   std::unique_ptr LoanPropagation;
-  std::unique_ptr ExpiredLoans;
+  std::unique_ptr LiveOrigins;
 };
 } // namespace internal
 } // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety.cpp
index 4068df31f1147..6381f50fa97f9 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeProfiler.h"
 #include 
 #include 
@@ -875,19 +876,26 @@ class DataflowAnalysis {
 llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
 
 while (const CFGBlock *B = W.dequeue()) {
-  Lattice StateIn = getInState(B);
+  Lattice StateIn = *getInState(B);
   Lattice StateOut = transferBlock(B, StateIn);
   OutStates[B] = StateOut;
-  Visited.set(B->getBlockID());
   for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
 if (!AdjacentB)
   continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
+  OldInState = *In;
+  NewInState = D.join(OldInState, StateOut);
+} else {
+  OldInState = D.getInitialState();
+  SawFirstTime = true;
+  NewInState = StateOut;
+}
 // Enqueue the adjacent block if its in-state has changed or if we have
 // never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+if (SawFirstTime || NewInState != OldInState) {
   InStates[AdjacentB] = NewInState;
   W.enqueueBlock(AdjacentB);
 }
@@ -898,7 +906,12 @@ class DataflowAnalysis {
 protected:
   Lattice getState(ProgramPoint P) const { return PerPointStates.lookup(P); }
 
-  Lattice getInState(const CFGBlock *B) const { return InStates.lookup(B); }
+  const Lattice *getInState(const CFGBlock *B) const {
+auto It = InStates.find(B);
+if (It != InStates.end())
+  return &It->second;
+return nullptr;
+  }
 
   Lattice getOutState(const CFGBlock *B) const { return OutStates.lookup(B); }
 
@@ -997,22 +1010,26 @@ static bool isSubsetOf(const llvm::ImmutableSet &A,
 // instead of the current AVL-tree-based ImmutableMap.
 template 
 static llvm::ImmutableMap
-join(llvm::ImmutableMap A, llvm::ImmutableMap B,
+join(const llvm::ImmutableMap &A, const llvm::ImmutableMap &B,
  typename llvm::ImmutableMap::Factory &F, Joiner JoinValues) {
   if (A.getHeight() < B.getHeight())
-std::swap(A, B);

[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_MAPPER (PR #160169)

2025-09-23 Thread Tom Eccles via llvm-branch-commits

https://github.com/tblah approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/160169
___
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] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_REDUCTION (PR #160192)

2025-09-23 Thread Tom Eccles via llvm-branch-commits


@@ -1559,12 +1559,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
 
   bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
 AddOmpSourceRange(x.source);
-parser::OmpClauseList empty(std::list{});
-auto &maybeClauses{std::get>(x.t)};
-ProcessReductionSpecifier(

tblah wrote:

Where does `ProcessReductionSpecifier` get called now this has been removed?

https://github.com/llvm/llvm-project/pull/160192
___
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] [LV] Mask off possibly aliasing vector lanes (PR #100579)

2025-09-23 Thread Florian Hahn via llvm-branch-commits


@@ -479,7 +479,11 @@ class LoopVectorizationPlanner {
   /// Build VPlans for the specified \p UserVF and \p UserIC if they are
   /// non-zero or all applicable candidate VFs otherwise. If vectorization and
   /// interleaving should be avoided up-front, no plans are generated.
-  void plan(ElementCount UserVF, unsigned UserIC);
+  /// DiffChecks is a list of pointer pairs that should be checked for 
aliasing,

fhahn wrote:

Memory accesses will be lowered to masked VPWidenLoad/StoreRecipe, so should 
hopefully be easy to find in the plan

https://github.com/llvm/llvm-project/pull/100579
___
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] Introduce -fsanitize=alloc-token (PR #156839)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -13,6 +13,7 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
+#include 

zmodem wrote:

not used?

https://github.com/llvm/llvm-project/pull/156839
___
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] Introduce -fsanitize=alloc-token (PR #156839)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -1272,6 +1272,21 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, 
llvm::Value *Bound,
   EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index);
 }
 
+void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, QualType AllocType) {
+  assert(SanOpts.has(SanitizerKind::AllocToken) &&
+ "Only needed with -fsanitize=alloc-token");
+
+  PrintingPolicy Policy(CGM.getContext().getLangOpts());
+  Policy.SuppressTagKeyword = true;
+  Policy.FullyQualifiedName = true;
+  std::string TypeName = AllocType.getCanonicalType().getAsString(Policy);

zmodem wrote:

Use a SmallString (with something like 256 bytes of buffer) to avoid heap 
allocation for typical cases?

https://github.com/llvm/llvm-project/pull/156839
___
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] Introduce -fsanitize=alloc-token (PR #156839)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -2194,6 +2194,8 @@ are listed below.
   protection against stack-based memory corruption errors.
-  ``-fsanitize=realtime``: :doc:`RealtimeSanitizer`,
   a real-time safety checker.
+   -  ``-fsanitize=alloc-token``: :doc:`AllocToken`,
+  allocation token instrumentation (requires compatible allocator).

zmodem wrote:

For someone who hasn't read the doc, this description is probably pretty 
opaque. Could you add a few more words on what this is for, and how it fits 
under the  "Turn on runtime checks" header above?

https://github.com/llvm/llvm-project/pull/156839
___
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] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/159991

>From 37c03435445d85f6fda1b20428ea41285f4ab716 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy

---
 .../clang/Analysis/Analyses/LifetimeSafety.h  |   9 +-
 clang/lib/Analysis/LifetimeSafety.cpp | 392 +++---
 clang/test/Sema/warn-lifetime-safety.cpp  | 141 +++--
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
 4 files changed, 583 insertions(+), 460 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..2cc3fb3d69eb4 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -55,6 +55,7 @@ class Fact;
 class FactManager;
 class LoanPropagationAnalysis;
 class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
 struct LifetimeFactory;
 
 /// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
OriginID ID) {
 // TODO(opt): Consider using a bitset to represent the set of loans.
 using LoanSet = llvm::ImmutableSet;
 using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
 /// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,9 @@ class LifetimeSafetyAnalysis {
   /// Returns the set of loans an origin holds at a specific program point.
   LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
 
-  /// Returns the set of loans that have expired at a specific program point.
-  std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+  /// TODO:Document.
+  std::vector>
+  getLiveOriginsAtPoint(ProgramPoint PP) const;
 
   /// Finds the OriginID for a given declaration.
   /// Returns a null optional if not found.
@@ -138,7 +141,7 @@ class LifetimeSafetyAnalysis {
   std::unique_ptr Factory;
   std::unique_ptr FactMgr;
   std::unique_ptr LoanPropagation;
-  std::unique_ptr ExpiredLoans;
+  std::unique_ptr LiveOrigins;
 };
 } // namespace internal
 } // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety.cpp
index 278f73e8e2112..ca5adfbd1e853 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeProfiler.h"
 #include 
 #include 
@@ -896,19 +897,26 @@ class DataflowAnalysis {
 llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
 
 while (const CFGBlock *B = W.dequeue()) {
-  Lattice StateIn = getInState(B);
+  Lattice StateIn = *getInState(B);
   Lattice StateOut = transferBlock(B, StateIn);
   OutStates[B] = StateOut;
-  Visited.set(B->getBlockID());
   for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
 if (!AdjacentB)
   continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
+  OldInState = *In;
+  NewInState = D.join(OldInState, StateOut);
+} else {
+  OldInState = D.getInitialState();
+  SawFirstTime = true;
+  NewInState = StateOut;
+}
 // Enqueue the adjacent block if its in-state has changed or if we have
 // never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+if (SawFirstTime || NewInState != OldInState) {
   InStates[AdjacentB] = NewInState;
   W.enqueueBlock(AdjacentB);
 }
@@ -919,7 +927,12 @@ class DataflowAnalysis {
 protected:
   Lattice getState(ProgramPoint P) const { return PerPointStates.lookup(P); }
 
-  Lattice getInState(const CFGBlock *B) const { return InStates.lookup(B); }
+  const Lattice *getInState(const CFGBlock *B) const {
+auto It = InStates.find(B);
+if (It != InStates.end())
+  return &It->second;
+return nullptr;
+  }
 
   Lattice getOutState(const CFGBlock *B) const { return OutStates.lookup(B); }
 
@@ -1018,22 +1031,26 @@ static bool isSubsetOf(const llvm::ImmutableSet &A,
 // instead of the current AVL-tree-based ImmutableMap.
 template 
 static llvm::ImmutableMap
-join(llvm::ImmutableMap A, llvm::ImmutableMap B,
+join(const llvm::ImmutableMap &A, const llvm::ImmutableMap &B,
  typename llvm::ImmutableMap::Factory &F, Joiner JoinValues) {
   if (A.getHeight() < B.getHeight())
-std::swap(A, B);

[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/159991

>From 37c03435445d85f6fda1b20428ea41285f4ab716 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy

---
 .../clang/Analysis/Analyses/LifetimeSafety.h  |   9 +-
 clang/lib/Analysis/LifetimeSafety.cpp | 392 +++---
 clang/test/Sema/warn-lifetime-safety.cpp  | 141 +++--
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
 4 files changed, 583 insertions(+), 460 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..2cc3fb3d69eb4 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -55,6 +55,7 @@ class Fact;
 class FactManager;
 class LoanPropagationAnalysis;
 class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
 struct LifetimeFactory;
 
 /// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
OriginID ID) {
 // TODO(opt): Consider using a bitset to represent the set of loans.
 using LoanSet = llvm::ImmutableSet;
 using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
 /// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,9 @@ class LifetimeSafetyAnalysis {
   /// Returns the set of loans an origin holds at a specific program point.
   LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
 
-  /// Returns the set of loans that have expired at a specific program point.
-  std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+  /// TODO:Document.
+  std::vector>
+  getLiveOriginsAtPoint(ProgramPoint PP) const;
 
   /// Finds the OriginID for a given declaration.
   /// Returns a null optional if not found.
@@ -138,7 +141,7 @@ class LifetimeSafetyAnalysis {
   std::unique_ptr Factory;
   std::unique_ptr FactMgr;
   std::unique_ptr LoanPropagation;
-  std::unique_ptr ExpiredLoans;
+  std::unique_ptr LiveOrigins;
 };
 } // namespace internal
 } // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety.cpp
index 278f73e8e2112..ca5adfbd1e853 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeProfiler.h"
 #include 
 #include 
@@ -896,19 +897,26 @@ class DataflowAnalysis {
 llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
 
 while (const CFGBlock *B = W.dequeue()) {
-  Lattice StateIn = getInState(B);
+  Lattice StateIn = *getInState(B);
   Lattice StateOut = transferBlock(B, StateIn);
   OutStates[B] = StateOut;
-  Visited.set(B->getBlockID());
   for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
 if (!AdjacentB)
   continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
+  OldInState = *In;
+  NewInState = D.join(OldInState, StateOut);
+} else {
+  OldInState = D.getInitialState();
+  SawFirstTime = true;
+  NewInState = StateOut;
+}
 // Enqueue the adjacent block if its in-state has changed or if we have
 // never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+if (SawFirstTime || NewInState != OldInState) {
   InStates[AdjacentB] = NewInState;
   W.enqueueBlock(AdjacentB);
 }
@@ -919,7 +927,12 @@ class DataflowAnalysis {
 protected:
   Lattice getState(ProgramPoint P) const { return PerPointStates.lookup(P); }
 
-  Lattice getInState(const CFGBlock *B) const { return InStates.lookup(B); }
+  const Lattice *getInState(const CFGBlock *B) const {
+auto It = InStates.find(B);
+if (It != InStates.end())
+  return &It->second;
+return nullptr;
+  }
 
   Lattice getOutState(const CFGBlock *B) const { return OutStates.lookup(B); }
 
@@ -1018,22 +1031,26 @@ static bool isSubsetOf(const llvm::ImmutableSet &A,
 // instead of the current AVL-tree-based ImmutableMap.
 template 
 static llvm::ImmutableMap
-join(llvm::ImmutableMap A, llvm::ImmutableMap B,
+join(const llvm::ImmutableMap &A, const llvm::ImmutableMap &B,
  typename llvm::ImmutableMap::Factory &F, Joiner JoinValues) {
   if (A.getHeight() < B.getHeight())
-std::swap(A, B);

[llvm-branch-commits] [clang] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/158489

>From 082d8a297d78a7bc9ea386f4493d0d1addb7bcec Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 14 Sep 2025 14:46:45 +
Subject: [PATCH] lifetime-analysis-lifetimebound

---
 .../Analysis/Analyses/LifetimeAnnotations.h   |  35 +++
 .../clang/Analysis/Analyses/LifetimeSafety.h  |  11 +-
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/LifetimeAnnotations.cpp|  73 +
 clang/lib/Analysis/LifetimeSafety.cpp | 191 +
 clang/lib/Sema/CheckExprLifetime.cpp  |  80 +-
 clang/lib/Sema/CheckExprLifetime.h|   2 -
 clang/lib/Sema/SemaAPINotes.cpp   |   4 +-
 .../test/Analysis/LifetimeSafety/benchmark.py |   2 +-
 .../Sema/warn-lifetime-safety-dataflow.cpp| 177 ++--
 clang/test/Sema/warn-lifetime-safety.cpp  | 149 ++
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 257 +-
 12 files changed, 778 insertions(+), 204 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/LifetimeAnnotations.h
 create mode 100644 clang/lib/Analysis/LifetimeAnnotations.cpp

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeAnnotations.h 
b/clang/include/clang/Analysis/Analyses/LifetimeAnnotations.h
new file mode 100644
index 0..dec61ad8b5e56
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/LifetimeAnnotations.h
@@ -0,0 +1,35 @@
+//===- LifetimeAnnotations.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
+//
+//===--===//
+// Helper functions to inspect and infer lifetime annotations.
+//===--===//
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
+
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+namespace lifetimes {
+
+const FunctionDecl *getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl 
*FD);
+
+const CXXMethodDecl *
+getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD);
+
+// Return true if this is an "normal" assignment operator.
+// We assume that a normal assignment operator always returns *this, that is,
+// an lvalue reference that is the same type as the implicit object parameter
+// (or the LHS for a non-member operator$=).
+bool isNormalAssignmentOperator(const FunctionDecl *FD);
+
+bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD);
+
+bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD);
+} // namespace lifetimes
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
\ No newline at end of file
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 7e1bfc903083e..512cb76cd6349 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -75,13 +75,14 @@ template  struct ID {
   }
 };
 
-template 
-inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ID ID) {
-  return OS << ID.Value;
-}
-
 using LoanID = ID;
 using OriginID = ID;
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, LoanID ID) {
+  return OS << ID.Value;
+}
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, OriginID ID) {
+  return OS << ID.Value;
+}
 
 // Using LLVM's immutable collections is efficient for dataflow analysis
 // as it avoids deep copies during state transitions.
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 0523d92480cb3..5a26f3eeea418 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -21,6 +21,7 @@ add_clang_library(clangAnalysis
   FixitUtil.cpp
   IntervalPartition.cpp
   IssueHash.cpp
+  LifetimeAnnotations.cpp
   LifetimeSafety.cpp
   LiveVariables.cpp
   MacroExpansionContext.cpp
diff --git a/clang/lib/Analysis/LifetimeAnnotations.cpp 
b/clang/lib/Analysis/LifetimeAnnotations.cpp
new file mode 100644
index 0..41d5684b2114d
--- /dev/null
+++ b/clang/lib/Analysis/LifetimeAnnotations.cpp
@@ -0,0 +1,73 @@
+#include "clang/Analysis/Analyses/LifetimeAnnotations.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+namespace clang {
+namespace lifetimes {
+
+const FunctionDecl *
+getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD) {
+  return FD != nullptr ? FD->getMostRecentDecl() : nullptr;
+}
+
+const CXXMethodDecl *
+getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD) {
+  

[llvm-branch-commits] [llvm] [AMDGPU][AsmParser] Introduce MC representation for lit() and lit64(). (PR #160316)

2025-09-23 Thread Ivan Kosarev via llvm-branch-commits

https://github.com/kosarev ready_for_review 
https://github.com/llvm/llvm-project/pull/160316
___
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] [AllocToken] Introduce AllocToken instrumentation pass (PR #156838)

2025-09-23 Thread Nikita Popov via llvm-branch-commits


@@ -0,0 +1,469 @@
+//===- AllocToken.cpp - Allocation token instrumentation 
--===//
+//
+// 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
+//
+//===--===//
+//
+// This file implements AllocToken, an instrumentation pass that
+// replaces allocation calls with token-enabled versions.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/AllocToken.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/Analysis.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/xxhash.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace llvm;
+
+#define DEBUG_TYPE "alloc-token"
+
+namespace {
+
+//===--- Constants 
===//
+
+enum class TokenMode : unsigned {
+  /// Incrementally increasing token ID.
+  Increment = 0,
+
+  /// Simple mode that returns a statically-assigned random token ID.
+  Random = 1,
+
+  /// Token ID based on allocated type hash.
+  TypeHash = 2,
+};
+
+//===--- Command-line options 
-===//
+
+cl::opt
+ClMode("alloc-token-mode", cl::Hidden, cl::desc("Token assignment mode"),
+   cl::init(TokenMode::TypeHash),
+   cl::values(clEnumValN(TokenMode::Increment, "increment",
+ "Incrementally increasing token ID"),
+  clEnumValN(TokenMode::Random, "random",
+ "Statically-assigned random token ID"),
+  clEnumValN(TokenMode::TypeHash, "typehash",
+ "Token ID based on allocated type hash")));
+
+cl::opt ClFuncPrefix("alloc-token-prefix",
+  cl::desc("The allocation function prefix"),
+  cl::Hidden, cl::init("__alloc_token_"));
+
+cl::opt ClMaxTokens("alloc-token-max",
+  cl::desc("Maximum number of tokens (0 = no 
max)"),
+  cl::Hidden, cl::init(0));
+
+cl::opt
+ClFastABI("alloc-token-fast-abi",
+  cl::desc("The token ID is encoded in the function name"),
+  cl::Hidden, cl::init(false));
+
+// Instrument libcalls only by default - compatible allocators only need to 
take
+// care of providing standard allocation functions. With extended coverage, 
also
+// instrument non-libcall allocation function calls with !alloc_token
+// metadata.
+cl::opt
+ClExtended("alloc-token-extended",
+   cl::desc("Extend coverage to custom allocation functions"),
+   cl::Hidden, cl::init(false));
+
+// C++ defines ::operator new (and variants) as replaceable (vs. standard
+// library versions), which are nobuiltin, and are therefore not covered by
+// isAllocationFn(). Cover by default, as users of AllocToken are already
+// required to provide token-aware allocation functions (no defaults).
+cl::opt ClCoverReplaceableNew("alloc-token-cover-replaceable-new",
+cl::desc("Cover replaceable operator new"),
+cl::Hidden, cl::init(true));
+
+cl::opt ClFallbackToken(
+"alloc-token-fallback",
+cl::desc("The default fallback token where none could be determined"),
+cl::Hidden, cl::init(0));
+
+//===--- Statistics 
---===//
+
+STATISTIC(NumFunctionsInstrumented, "Functions instrumented");
+STATISTIC(NumAllocationsInstrumented, "Allocations instrumented");
+
+//===--===//
+
+/// Returns the !alloc_token metadata if available.
+///
+/// Expected format is: !{}
+MDNode *getAllocTokenMetadata(const 

[llvm-branch-commits] [llvm] [AllocToken] Introduce AllocToken instrumentation pass (PR #156838)

2025-09-23 Thread Nikita Popov via llvm-branch-commits

https://github.com/nikic commented:

(drive-by comments only)

https://github.com/llvm/llvm-project/pull/156838
___
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] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/158489
___
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] [flang] [flang][OpenMP] Avoid extra newline when unparsing OmpReductionCombiner (PR #160200)

2025-09-23 Thread Krzysztof Parzyszek via llvm-branch-commits

https://github.com/kparzysz updated 
https://github.com/llvm/llvm-project/pull/160200

>From 672c1ad9f0b473f883b12c9a2aff70b7c3de80ac Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek 
Date: Mon, 22 Sep 2025 15:30:42 -0500
Subject: [PATCH] [flang][OpenMP] Avoid extra newline when unparsing
 OmpReductionCombiner

When the combiner contains an AssignmentStmt, the unparser for that will
emit a newline after the assignment. Don't let it do that, unparse the
assignment ourselves.
---
 flang/lib/Parser/unparse.cpp| 13 +++--
 .../test/Parser/OpenMP/declare-reduction-multi.f90  | 12 
 .../Parser/OpenMP/declare-reduction-operator.f90|  6 ++
 .../declare-reduction-unparse-with-symbols.f90  |  2 +-
 .../Parser/OpenMP/declare-reduction-unparse.f90 |  6 ++
 flang/test/Parser/OpenMP/metadirective-dirspec.f90  |  4 ++--
 .../Parser/OpenMP/openmp6-directive-spellings.f90   |  3 +--
 .../Semantics/OpenMP/declare-reduction-modfile.f90  | 12 ++--
 8 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 750f1258be2fc..d4fec14f525aa 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2106,7 +2106,7 @@ class UnparseVisitor {
 Walk(std::get(x.t));
 Put(":");
 Walk(std::get(x.t));
-Walk(":", std::get>(x.t));
+Walk(": ", std::get>(x.t));
   }
   void Unparse(const llvm::omp::Directive &x) {
 unsigned ompVersion{langOpts_.OpenMPVersion};
@@ -2488,7 +2488,16 @@ class UnparseVisitor {
 // Don't let the visitor go to the normal AssignmentStmt Unparse function,
 // it adds an extra newline that we don't want.
 if (const auto *assignment{std::get_if(&x.u)}) {
-  Walk(assignment->t, "=");
+  Walk(assignment->t, " = ");
+} else {
+  Walk(x.u);
+}
+  }
+  void Unparse(const OmpReductionCombiner &x) {
+// Don't let the visitor go to the normal AssignmentStmt Unparse function,
+// it adds an extra newline that we don't want.
+if (const auto *assignment{std::get_if(&x.u)}) {
+  Walk(assignment->t, " = ");
 } else {
   Walk(x.u);
 }
diff --git a/flang/test/Parser/OpenMP/declare-reduction-multi.f90 
b/flang/test/Parser/OpenMP/declare-reduction-multi.f90
index 19266aca9db03..0af3ed6e78571 100644
--- a/flang/test/Parser/OpenMP/declare-reduction-multi.f90
+++ b/flang/test/Parser/OpenMP/declare-reduction-multi.f90
@@ -26,8 +26,7 @@ program omp_examples
   type(tt) :: values(n), sum, prod, big, small
 
   !$omp declare reduction(+:tt:omp_out%r = omp_out%r + omp_in%r) 
initializer(omp_priv%r = 0)
-!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out%r=omp_out%r+omp_in%r
-!CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4)
+!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out%r = omp_out%r+omp_in%r) 
INITIALIZER(omp_priv%r = 0_4)
 
 !PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> 
OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> 
OmpDirectiveSpecification
 !PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
@@ -39,8 +38,7 @@ program omp_examples
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> 
OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4'
 
   !$omp declare reduction(*:tt:omp_out%r = omp_out%r * omp_in%r) 
initializer(omp_priv%r = 1)
-!CHECK-NEXT: !$OMP DECLARE REDUCTION(*:tt: omp_out%r=omp_out%r*omp_in%r
-!CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4)
+!CHECK-NEXT: !$OMP DECLARE REDUCTION(*:tt: omp_out%r = omp_out%r*omp_in%r) 
INITIALIZER(omp_priv%r = 1_4)
 
 !PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> 
OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> 
OmpDirectiveSpecification
 !PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
@@ -52,8 +50,7 @@ program omp_examples
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> 
OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4'
 
   !$omp declare reduction(max:tt:omp_out = mymax(omp_out, omp_in)) 
initializer(omp_priv%r = 0)
-!CHECK-NEXT: !$OMP DECLARE REDUCTION(max:tt: omp_out=mymax(omp_out,omp_in)
-!CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4)
+!CHECK-NEXT: !$OMP DECLARE REDUCTION(max:tt: omp_out = mymax(omp_out,omp_in)) 
INITIALIZER(omp_priv%r = 0_4)
 
 !PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> 
OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> 
OmpDirectiveSpecification
 !PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
@@ -65,8 +62,7 @@ program omp_examples
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> 
OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4'
 
   !$omp declare reduction(min:tt:omp_out%r = min(omp_out%r, omp_in%r)) 
initializer(omp_priv%r = 1)
-!CHECK-NEXT: !$OMP DECLARE REDUCTION(min:tt: omp_out%r=min(omp_out%r,omp_in%r)
-!CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4)
+!CHECK-NEXT: !$OMP DECLARE REDUCTION(min:tt: omp_out%r = 
min(

[llvm-branch-commits] [flang] [llvm] [mlir] [openmp] [Flang] Add standalone tile support (PR #160298)

2025-09-23 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur edited 
https://github.com/llvm/llvm-project/pull/160298
___
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] [AllocToken, Clang] Implement TypeHashPointerSplit mode (PR #156840)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -1272,18 +1272,84 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr 
*E, llvm::Value *Bound,
   EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index);
 }
 
+static bool
+typeContainsPointer(QualType T,
+llvm::SmallPtrSet &VisitedRD,
+bool &IncompleteType) {
+  QualType CanonicalType = T.getCanonicalType();
+  if (CanonicalType->isPointerType())
+return true; // base case
+
+  // Look through typedef chain to check for special types.
+  for (QualType CurrentT = T; const auto *TT = CurrentT->getAs();
+   CurrentT = TT->getDecl()->getUnderlyingType()) {
+const IdentifierInfo *II = TT->getDecl()->getIdentifier();
+if (!II)
+  continue;
+// Special Case: Syntactically uintptr_t is not a pointer; semantically,
+// however, very likely used as such. Therefore, classify uintptr_t as a
+// pointer, too.
+if (II->isStr("uintptr_t"))
+  return true;
+  }
+
+  // The type is an array; check the element type.
+  if (const ArrayType *AT = dyn_cast(CanonicalType))
+return typeContainsPointer(AT->getElementType(), VisitedRD, 
IncompleteType);
+  // The type is a struct, class, or union.
+  if (const RecordDecl *RD = CanonicalType->getAsRecordDecl()) {
+if (!RD->isCompleteDefinition()) {
+  IncompleteType = true;
+  return false;
+}
+if (!VisitedRD.insert(RD).second)
+  return false; // already visited
+// Check all fields.
+for (const FieldDecl *Field : RD->fields()) {
+  if (typeContainsPointer(Field->getType(), VisitedRD, IncompleteType))
+return true;
+}
+// For C++ classes, also check base classes.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
+  // Polymorphic types require a vptr.
+  if (CXXRD->isPolymorphic())
+return true;
+  for (const CXXBaseSpecifier &Base : CXXRD->bases()) {
+if (typeContainsPointer(Base.getType(), VisitedRD, IncompleteType))
+  return true;
+  }
+}
+  }
+  return false;
+}
+
 void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, QualType AllocType) {
   assert(SanOpts.has(SanitizerKind::AllocToken) &&
  "Only needed with -fsanitize=alloc-token");
 
+  llvm::MDBuilder MDB(getLLVMContext());
+
+  // Get unique type name.
   PrintingPolicy Policy(CGM.getContext().getLangOpts());
   Policy.SuppressTagKeyword = true;
   Policy.FullyQualifiedName = true;
   std::string TypeName = AllocType.getCanonicalType().getAsString(Policy);
-  auto *TypeMDS = llvm::MDString::get(CGM.getLLVMContext(), TypeName);
+  auto *TypeNameMD = MDB.createString(TypeName);
+
+  // Check if QualType contains a pointer. Implements a simple DFS to
+  // recursively check if a type contains a pointer type.
+  llvm::SmallPtrSet VisitedRD;
+  bool IncompleteType = false;
+  const bool ContainsPtr =
+  typeContainsPointer(AllocType, VisitedRD, IncompleteType);

zmodem wrote:

This seems potentially slow, as we might walk a lot of big types many times. 
Have you seen any indication of this when testing? Should we be caching? Could 
it be represented directly in the AST?

I'd be curious to hear @ojhunt 's thoughts since it sounds like they have 
something like this already.

https://github.com/llvm/llvm-project/pull/156840
___
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] [AllocToken, Clang] Implement TypeHashPointerSplit mode (PR #156840)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -205,6 +231,26 @@ class TypeHashMode : public ModeBase {
   }
 };
 
+/// Implementation for TokenMode::TypeHashPointerSplit.
+class TypeHashPointerSplitMode : public TypeHashMode {
+public:
+  using TypeHashMode::TypeHashMode;
+
+  uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
+if (MaxTokens == 1)
+  return 0;
+const uint64_t HalfTokens =
+(MaxTokens ? MaxTokens : std::numeric_limits::max()) / 2;
+const auto [N, H] = getHash(CB, ORE);
+if (!N)
+  return H; // fallback token

zmodem wrote:

This means the fallback token could go either in the "contains pointer" bucket 
or not. Maybe that makes sense, but it seems worth commenting on the strategy 
for this case.

https://github.com/llvm/llvm-project/pull/156840
___
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] [AllocToken, Clang] Implement TypeHashPointerSplit mode (PR #156840)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -0,0 +1,177 @@
+// Check -fsanitize=alloc-token TypeHashPointerSplit mode with only 2
+// tokens so we effectively only test the contains-pointer logic.
+//
+// RUN: %clang_cc1-fsanitize=alloc-token -falloc-token-max=2 -triple 
x86_64-linux-gnu -std=c++20 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O -fsanitize=alloc-token -falloc-token-max=2 -triple 
x86_64-linux-gnu -std=c++20 -emit-llvm %s -o - | FileCheck %s
+
+#include "../Analysis/Inputs/system-header-simulator-cxx.h"
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+extern "C" {
+void *malloc(size_t size);
+}
+
+// CHECK-LABEL: @_Z15test_malloc_intv(
+void *test_malloc_int() {
+  // CHECK: call{{.*}} ptr @__alloc_token_malloc(i64 noundef 4, i64 0)

zmodem wrote:

As mentioned in the previous PR, I'd kind of expect to see the metadata nodes 
here, not the rewritten calls.

https://github.com/llvm/llvm-project/pull/156840
___
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] [AllocToken, Clang] Implement TypeHashPointerSplit mode (PR #156840)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -205,6 +231,26 @@ class TypeHashMode : public ModeBase {
   }
 };
 
+/// Implementation for TokenMode::TypeHashPointerSplit.
+class TypeHashPointerSplitMode : public TypeHashMode {
+public:
+  using TypeHashMode::TypeHashMode;
+
+  uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
+if (MaxTokens == 1)
+  return 0;
+const uint64_t HalfTokens =
+(MaxTokens ? MaxTokens : std::numeric_limits::max()) / 2;

zmodem wrote:

Should probably set this based on the target pointer width. As it's written, 
we'll lose the "contains pointer" half in truncation on 32-bit.

https://github.com/llvm/llvm-project/pull/156840
___
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] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_REDUCTION (PR #160192)

2025-09-23 Thread Krzysztof Parzyszek via llvm-branch-commits

https://github.com/kparzysz updated 
https://github.com/llvm/llvm-project/pull/160192

>From d04b0664a612b1060897834160395cfe2a3ca492 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek 
Date: Mon, 22 Sep 2025 14:42:16 -0500
Subject: [PATCH] [flang][OpenMP] Use OmpDirectiveSpecification in
 DECLARE_REDUCTION

---
 flang/include/flang/Parser/parse-tree.h   |   6 +-
 flang/lib/Parser/openmp-parsers.cpp   |   6 +-
 flang/lib/Parser/unparse.cpp  |   7 +-
 flang/lib/Semantics/check-omp-structure.cpp   |  23 ++-
 flang/lib/Semantics/resolve-names.cpp |  22 ++-
 .../Parser/OpenMP/declare-reduction-multi.f90 | 158 ++
 .../OpenMP/declare-reduction-operator.f90 |  38 +++--
 ...declare-reduction-unparse-with-symbols.f90 |   2 +-
 .../OpenMP/declare-reduction-unparse.f90  |  51 --
 .../OpenMP/openmp6-directive-spellings.f90|   9 +-
 .../OpenMP/declare-reduction-modfile.f90  |  12 +-
 11 files changed, 188 insertions(+), 146 deletions(-)

diff --git a/flang/include/flang/Parser/parse-tree.h 
b/flang/include/flang/Parser/parse-tree.h
index 73f8fbdbbb467..2063eccf8b7f4 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4960,11 +4960,9 @@ struct OpenMPDeclareMapperConstruct {
 // 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : 
type-list
 //  : combiner) 
[initializer-clause]
 struct OpenMPDeclareReductionConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
+  WRAPPER_CLASS_BOILERPLATE(
+  OpenMPDeclareReductionConstruct, OmpDirectiveSpecification);
   CharBlock source;
-  std::tuple,
-  std::optional>
-  t;
 };
 
 // 2.8.2 declare-simd -> DECLARE SIMD [(proc-name)] [declare-simd-clause[ [,]
diff --git a/flang/lib/Parser/openmp-parsers.cpp 
b/flang/lib/Parser/openmp-parsers.cpp
index dc638ca9d00fe..57b812665073a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1708,9 +1708,9 @@ TYPE_PARSER(sourced(construct(
 
 // 2.16 Declare Reduction Construct
 TYPE_PARSER(sourced(construct(
-verbatim("DECLARE REDUCTION"_tok) || verbatim("DECLARE_REDUCTION"_tok),
-"(" >> indirect(Parser{}) / ")",
-maybe(Parser{}
+predicated(Parser{},
+IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
+Parser{})))
 
 // declare-target with list
 TYPE_PARSER(sourced(construct(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 01b0e32a1164e..750f1258be2fc 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2495,11 +2495,8 @@ class UnparseVisitor {
   }
   void Unparse(const OpenMPDeclareReductionConstruct &x) {
 BeginOpenMP();
-Word("!$OMP DECLARE REDUCTION ");
-Put("(");
-Walk(std::get>(x.t));
-Put(")");
-Walk(std::get>(x.t));
+Word("!$OMP ");
+Walk(x.v);
 Put("\n");
 EndOpenMP();
   }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp 
b/flang/lib/Semantics/check-omp-structure.cpp
index 17954b5826586..bff5c2498344a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -629,11 +629,6 @@ template  struct 
DirectiveSpellingVisitor {
 checker_(std::get(x.t).source, Directive::OMPD_assumes);
 return false;
   }
-  bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
-checker_(std::get(x.t).source,
-Directive::OMPD_declare_reduction);
-return false;
-  }
   bool Pre(const parser::OpenMPDeclareSimdConstruct &x) {
 checker_(
 std::get(x.t).source, Directive::OMPD_declare_simd);
@@ -1618,9 +1613,21 @@ void OmpStructureChecker::Leave(const 
parser::OpenMPDeclareMapperConstruct &) {
 
 void OmpStructureChecker::Enter(
 const parser::OpenMPDeclareReductionConstruct &x) {
-  const auto &dir{std::get(x.t)};
-  PushContextAndClauseSets(
-  dir.source, llvm::omp::Directive::OMPD_declare_reduction);
+  const parser::OmpDirectiveName &dirName{x.v.DirName()};
+  PushContextAndClauseSets(dirName.source, dirName.v);
+
+  const parser::OmpArgumentList &args{x.v.Arguments()};
+  if (args.v.size() != 1) {
+context_.Say(args.source,
+"DECLARE_REDUCTION directive should have a single argument"_err_en_US);
+return;
+  }
+
+  const parser::OmpArgument &arg{args.v.front()};
+  if (!std::holds_alternative(arg.u)) {
+context_.Say(arg.source,
+"The argument to the DECLARE_REDUCTION directive should be a 
reduction-specifier"_err_en_US);
+  }
 }
 
 void OmpStructureChecker::Leave(
diff --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index 86ada0f8cdc85..3b6140429f9ed 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1559,12 +1559,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
 
   bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
 A

[llvm-branch-commits] [mlir] [mlir][omp] Add omp.tile operation (PR #160292)

2025-09-23 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur updated 
https://github.com/llvm/llvm-project/pull/160292

>From ff4eccb41e2973e1179734dd455f1e797e89d9be Mon Sep 17 00:00:00 2001
From: Michael Kruse 
Date: Tue, 23 Sep 2025 14:45:45 +0200
Subject: [PATCH] Add omp.tile operation

---
 .../mlir/Dialect/OpenMP/OpenMPClauses.td  |  29 ++
 .../mlir/Dialect/OpenMP/OpenMPOpBase.td   |  69 +++-
 mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td |  63 ++-
 mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp  | 387 +++---
 .../OpenMP/OpenMPToLLVMIRTranslation.cpp  |  42 ++
 .../Dialect/OpenMP/cli-canonical_loop.mlir| 127 --
 mlir/test/Dialect/OpenMP/cli-tile.mlir| 138 +++
 .../Dialect/OpenMP/cli-unroll-heuristic.mlir  |  28 +-
 mlir/test/Dialect/OpenMP/invalid-tile.mlir| 119 ++
 .../test/Target/LLVMIR/openmp-cli-tile01.mlir | 101 +
 .../test/Target/LLVMIR/openmp-cli-tile02.mlir | 190 +
 mlir/test/mlir-tblgen/op-format-invalid.td|   2 +-
 .../tools/mlir-tblgen/AttrOrTypeFormatGen.cpp |   1 +
 mlir/tools/mlir-tblgen/FormatGen.cpp  |   2 +-
 mlir/tools/mlir-tblgen/OpFormatGen.cpp|   1 +
 15 files changed, 1157 insertions(+), 142 deletions(-)
 create mode 100644 mlir/test/Dialect/OpenMP/cli-tile.mlir
 create mode 100644 mlir/test/Dialect/OpenMP/invalid-tile.mlir
 create mode 100644 mlir/test/Target/LLVMIR/openmp-cli-tile01.mlir
 create mode 100644 mlir/test/Target/LLVMIR/openmp-cli-tile02.mlir

diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td 
b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index 1eda5e4bc1618..8e43c4284d078 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -995,6 +995,35 @@ class OpenMP_NumTeamsClauseSkip<
 
 def OpenMP_NumTeamsClause : OpenMP_NumTeamsClauseSkip<>;
 
+//===--===//
+//  V5.1: [10.1.2] `sizes` clause
+//===--===//
+
+class OpenMP_SizesClauseSkip<
+bit traits = false, bit arguments = false, bit assemblyFormat = false,
+bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause {
+  let arguments = (ins
+Variadic:$sizes
+  );
+
+  let optAssemblyFormat = [{
+`sizes` `(` $sizes `:` type($sizes) `)`
+  }];
+
+  let description = [{
+The `sizes` clauses defines the size of a grid over a multi-dimensional
+logical iteration space. This grid is used for loop transformations such as
+`tile` and `strip`. The size per dimension can be a variable, but only
+values that are not at least 2 make sense. It is not specified what happens
+when smaller values are used, but should still result in a loop nest that
+executes each logical iteration once.
+  }];
+}
+
+def OpenMP_SizesClause : OpenMP_SizesClauseSkip<>;
+
 
//===--===//
 // V5.2: [10.1.2] `num_threads` clause
 
//===--===//
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td 
b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
index bbcfb87fa03c6..5ad4e4b5b61d1 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
@@ -38,6 +38,44 @@ def OpenMP_MapBoundsType : OpenMP_Type<"MapBounds", 
"map_bounds_ty"> {
   let summary = "Type for representing omp map clause bounds information";
 }
 
+//===-===//
+// OpenMP Canonical Loop Info Type
+//===-===//
+
+def CanonicalLoopInfoType : OpenMP_Type<"CanonicalLoopInfo", "cli"> {
+  let summary = "Type for representing a reference to a canonical loop";
+  let description = [{
+A variable of type CanonicalLoopInfo refers to an OpenMP-compatible
+canonical loop in the same function. Values of this type are not
+available at runtime and therefore cannot be used by the program itself,
+i.e. an opaque type. It is similar to the transform dialect's
+`!transform.interface` type, but instead of implementing an interface
+for each transformation, the OpenMP dialect itself defines possible
+operations on this type.
+
+A value of type CanonicalLoopInfoType (in the following: CLI) value can be
+
+1. created by omp.new_cli.
+2. passed to omp.canonical_loop to associate the loop to that CLI. A CLI
+   can only be associated once.
+3. passed to an omp loop transformation operation that modifies the loop
+   associated with the CLI. The CLI is the "applyee" and the operation is
+   the consumer. A CLI can only be consumed once.
+4. passed to an omp loop transformation operation to associate the cli with
+   a result of that transformation. The CLI is the "generatee" and the
+   operatio

[llvm-branch-commits] [mlir] [mlir][OpenMP] Improve canonloop/iv naming (PR #159773)

2025-09-23 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur updated 
https://github.com/llvm/llvm-project/pull/159773

>From b3919715ebe223b39dd789dcd471a864666d7008 Mon Sep 17 00:00:00 2001
From: Michael Kruse 
Date: Fri, 19 Sep 2025 14:43:48 +0200
Subject: [PATCH 1/2] Improve canonloop/iv naming

---
 mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp  | 237 +-
 .../Dialect/OpenMP/cli-canonical_loop.mlir| 127 --
 .../Dialect/OpenMP/cli-unroll-heuristic.mlir  |  28 +--
 3 files changed, 292 insertions(+), 100 deletions(-)

diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp 
b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 3d70e28ed23ab..cf549a6bb50b4 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -77,6 +77,178 @@ struct LLVMPointerPointerLikeModel
 };
 } // namespace
 
+/// Generate a name of a canonical loop nest of the format
+/// `(_s_r)*` that describes its nesting inside parent
+/// operations (`_r`) and that operation's region (`_s`). The region
+/// number is omitted if the parent operation has just one region. If a loop
+/// nest just consists of canonical loops nested inside each other, also uses
+/// `d` where  is the nesting depth of the loop.
+static std::string generateLoopNestingName(StringRef prefix,
+   CanonicalLoopOp op) {
+  struct Component {
+// An region argument of an operation
+Operation *parentOp;
+size_t regionInOpIdx;
+bool isOnlyRegionInOp;
+bool skipRegion;
+
+// An operation somewhere in a parent region
+Operation *thisOp;
+Region *parentRegion;
+size_t opInRegionIdx;
+bool isOnlyOpInRegion;
+bool skipOp;
+int depth = -1;
+  };
+  SmallVector components;
+
+  // Gather a list of parent regions and operations, and the position within
+  // their parent
+  Operation *o = op.getOperation();
+  while (o) {
+if (o->hasTrait())
+  break;
+
+// Operation within a region
+Region *r = o->getParentRegion();
+if (!r)
+  break;
+
+llvm::ReversePostOrderTraversal 
traversal(&r->getBlocks().front());
+size_t idx = 0;
+bool found = false;
+size_t sequentialIdx = -1;
+bool isOnlyLoop = true;
+for (Block *b : traversal) {
+  for (Operation &op : *b) {
+if (&op == o && !found) {
+  sequentialIdx = idx;
+  found = true;
+}
+if (op.getNumRegions()) {
+  idx += 1;
+  if (idx > 1)
+isOnlyLoop = false;
+}
+if (found && !isOnlyLoop)
+  break;
+  }
+}
+
+Component &comp = components.emplace_back();
+comp.thisOp = o;
+comp.parentRegion = r;
+comp.opInRegionIdx = sequentialIdx;
+comp.isOnlyOpInRegion = isOnlyLoop;
+
+// Region argument of an operation
+Operation *parent = r->getParentOp();
+
+comp.parentOp = parent;
+comp.regionInOpIdx = 0;
+comp.isOnlyRegionInOp = true;
+if (parent && parent->getRegions().size() > 1) {
+  auto getRegionIndex = [](Operation *o, Region *r) {
+for (auto [idx, region] : llvm::enumerate(o->getRegions())) {
+  if (®ion == r)
+return idx;
+}
+llvm_unreachable("Region not child of its parent operation");
+  };
+  comp.regionInOpIdx = getRegionIndex(parent, r);
+  comp.isOnlyRegionInOp = false;
+}
+
+if (!parent)
+  break;
+
+// next parent
+o = parent;
+  }
+
+  // Reorder components from outermost to innermost
+  std::reverse(components.begin(), components.end());
+
+  // Determine whether a component is not needed
+  for (auto &c : components) {
+c.skipRegion = c.isOnlyRegionInOp;
+c.skipOp = c.isOnlyOpInRegion && !isa(c.thisOp);
+  }
+
+  // Find runs of perfect nests and merge them into a single component
+  int curNestRoot = 0;
+  int curNestDepth = 1;
+  auto mergeLoopNest = [&](int innermost) {
+auto outermost = curNestRoot;
+
+// Don't do enything if it does not consist of at least 2 loops
+if (outermost < innermost) {
+  for (auto i : llvm::seq(outermost + 1, innermost)) {
+components[i].skipOp = true;
+  }
+  components[innermost].depth = curNestDepth;
+}
+
+// Start new root
+curNestRoot = innermost + 1;
+curNestDepth = 1;
+  };
+  for (auto &&[i, c] : llvm::enumerate(components)) {
+if (i <= curNestRoot)
+  continue;
+
+// Check whether this region can be included
+if (!c.skipRegion) {
+  mergeLoopNest(i);
+  continue;
+}
+
+if (c.skipOp)
+  continue;
+
+if (!c.isOnlyOpInRegion) {
+  mergeLoopNest(i);
+  continue;
+}
+
+curNestDepth += 1;
+  }
+
+  // Finalize innermost loop nest
+  mergeLoopNest(components.size() - 1);
+
+  // Outermost loop does not need a suffix if it has no sibling
+  for (auto &c : components) {
+if (c.skipOp)
+  continue;
+if (c.isOnlyOpInRegion)
+  c.skipOp = true;
+break;
+  }
+
+  // 

[llvm-branch-commits] [flang] [llvm] [openmp] [Flang] Add standalone tile support (PR #160298)

2025-09-23 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur updated 
https://github.com/llvm/llvm-project/pull/160298

>From bfe9c6b642ebc01f113dbf0a574e424e83f7162a Mon Sep 17 00:00:00 2001
From: Michael Kruse 
Date: Tue, 23 Sep 2025 15:33:52 +0200
Subject: [PATCH 1/2] [flang] Add standalone tile support

---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp|  13 +
 flang/lib/Lower/OpenMP/ClauseProcessor.h  |   2 +
 flang/lib/Lower/OpenMP/OpenMP.cpp | 360 --
 flang/lib/Lower/OpenMP/Utils.cpp  |  23 +-
 flang/lib/Lower/OpenMP/Utils.h|   7 +
 .../lib/Semantics/check-directive-structure.h |   7 +-
 flang/lib/Semantics/check-omp-structure.cpp   |   8 +-
 flang/lib/Semantics/resolve-directives.cpp|  16 +-
 flang/test/Lower/OpenMP/tile01.f90|  58 +++
 flang/test/Lower/OpenMP/tile02.f90|  88 +
 .../loop-transformation-construct02.f90   |   5 +-
 flang/test/Parser/OpenMP/tile-fail.f90|  32 ++
 flang/test/Parser/OpenMP/tile.f90 |  15 +-
 flang/test/Semantics/OpenMP/tile01.f90|  26 ++
 flang/test/Semantics/OpenMP/tile02.f90|  15 +
 flang/test/Semantics/OpenMP/tile03.f90|  15 +
 flang/test/Semantics/OpenMP/tile04.f90|  38 ++
 flang/test/Semantics/OpenMP/tile05.f90|  14 +
 flang/test/Semantics/OpenMP/tile06.f90|  44 +++
 flang/test/Semantics/OpenMP/tile07.f90|  35 ++
 flang/test/Semantics/OpenMP/tile08.f90|  15 +
 llvm/include/llvm/Frontend/OpenMP/OMP.td  |   3 +
 openmp/runtime/test/transform/tile/intfor.f90 |  31 ++
 .../runtime/test/transform/tile/intfor_2d.f90 |  53 +++
 .../transform/tile/intfor_2d_varsizes.F90 |  60 +++
 25 files changed, 841 insertions(+), 142 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/tile01.f90
 create mode 100644 flang/test/Lower/OpenMP/tile02.f90
 create mode 100644 flang/test/Parser/OpenMP/tile-fail.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile01.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile02.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile03.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile04.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile05.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile06.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile07.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile08.f90
 create mode 100644 openmp/runtime/test/transform/tile/intfor.f90
 create mode 100644 openmp/runtime/test/transform/tile/intfor_2d.f90
 create mode 100644 openmp/runtime/test/transform/tile/intfor_2d_varsizes.F90

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp 
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index a96884f5680ba..55eda7e3404c1 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -431,6 +431,19 @@ bool ClauseProcessor::processNumTasks(
   return false;
 }
 
+bool ClauseProcessor::processSizes(StatementContext &stmtCtx,
+   mlir::omp::SizesClauseOps &result) const {
+  if (auto *clause = findUniqueClause()) {
+result.sizes.reserve(clause->v.size());
+for (const ExprTy &vv : clause->v)
+  result.sizes.push_back(fir::getBase(converter.genExprValue(vv, 
stmtCtx)));
+
+return true;
+  }
+
+  return false;
+}
+
 bool ClauseProcessor::processNumTeams(
 lower::StatementContext &stmtCtx,
 mlir::omp::NumTeamsClauseOps &result) const {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h 
b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 324ea3c1047a5..9e352fa574a97 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -66,6 +66,8 @@ class ClauseProcessor {
   mlir::omp::LoopRelatedClauseOps &loopResult,
   mlir::omp::CollapseClauseOps &collapseResult,
   llvm::SmallVectorImpl &iv) const;
+  bool processSizes(StatementContext &stmtCtx,
+mlir::omp::SizesClauseOps &result) const;
   bool processDevice(lower::StatementContext &stmtCtx,
  mlir::omp::DeviceClauseOps &result) const;
   bool processDeviceType(mlir::omp::DeviceTypeClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp 
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 5681be664d450..7812d9fe00be2 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1984,125 +1984,241 @@ genLoopOp(lower::AbstractConverter &converter, 
lower::SymMap &symTable,
   return loopOp;
 }
 
-static mlir::omp::CanonicalLoopOp
-genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap 
&symTable,
-   semantics::SemanticsContext &semaCtx,
-   lower::pft::Evaluation &eval, mlir::Location loc,
-   const ConstructQueue &queue,
-   ConstructQueue::const_iterator item,
-   llvm::ArrayRef ivs,
-   llvm::omp::Directive directive)

[llvm-branch-commits] [AllocToken, Clang] Infer type hints from sizeof expressions and casts (PR #156841)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -1353,6 +1354,92 @@ void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, 
QualType AllocType) {
   CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
 }
 
+/// Infer type from a simple sizeof expression.
+static QualType inferTypeFromSizeofExpr(const Expr *E) {
+  const Expr *Arg = E->IgnoreParenImpCasts();
+  if (const auto *UET = dyn_cast(Arg)) {
+if (UET->getKind() == UETT_SizeOf) {
+  if (UET->isArgumentType())
+return UET->getArgumentTypeInfo()->getType();
+  else
+return UET->getArgumentExpr()->getType();
+}
+  }
+  return QualType();
+}
+
+/// Infer type from an arithmetic expression involving a sizeof.
+static QualType inferTypeFromArithSizeofExpr(const Expr *E) {
+  const Expr *Arg = E->IgnoreParenImpCasts();
+  // The argument is a lone sizeof expression.
+  if (QualType T = inferTypeFromSizeofExpr(Arg); !T.isNull())
+return T;
+  if (const auto *BO = dyn_cast(Arg)) {
+// Argument is an arithmetic expression. Cover common arithmetic patterns
+// involving sizeof.
+switch (BO->getOpcode()) {
+case BO_Add:
+case BO_Div:
+case BO_Mul:
+case BO_Shl:
+case BO_Shr:
+case BO_Sub:
+  if (QualType T = inferTypeFromArithSizeofExpr(BO->getLHS()); !T.isNull())
+return T;
+  if (QualType T = inferTypeFromArithSizeofExpr(BO->getRHS()); !T.isNull())
+return T;
+  break;
+default:
+  break;
+}
+  }
+  return QualType();
+}
+
+/// If the expression E is a reference to a variable, infer the type from a
+/// variable's initializer if it contains a sizeof. Beware, this is a heuristic
+/// and ignores if a variable is later reassigned.

zmodem wrote:

nit: For readability, it would be nice if the comments contained a small 
example of the pattern that's being matched.

https://github.com/llvm/llvm-project/pull/156841
___
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] Add frontend for search (PR #160308)

2025-09-23 Thread Ivan Kosarev via llvm-branch-commits

kosarev 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/160308?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#160308** https://app.graphite.dev/github/pr/llvm/llvm-project/160308?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/160308?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#160307** https://app.graphite.dev/github/pr/llvm/llvm-project/160307?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/160308
___
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] Add frontend for search (PR #160308)

2025-09-23 Thread Ivan Kosarev via llvm-branch-commits

https://github.com/kosarev updated 
https://github.com/llvm/llvm-project/pull/160308

>From 0f530793bdc1c6f364cc1b9238790c21262e6c97 Mon Sep 17 00:00:00 2001
From: Ivan Kosarev 
Date: Tue, 23 Sep 2025 15:17:50 +0100
Subject: [PATCH] Add frontend for search

---
 .../Target/AMDGPU/graphite-demo/frontend.jsx  | 56 +++
 1 file changed, 56 insertions(+)
 create mode 100644 llvm/lib/Target/AMDGPU/graphite-demo/frontend.jsx

diff --git a/llvm/lib/Target/AMDGPU/graphite-demo/frontend.jsx 
b/llvm/lib/Target/AMDGPU/graphite-demo/frontend.jsx
new file mode 100644
index 0..dd6a2a3ba66cc
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/graphite-demo/frontend.jsx
@@ -0,0 +1,56 @@
+import React, { useEffect, useState } from 'react';
+
+const TaskSearch = () => {
+  const [tasks, setTasks] = useState([]);
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(null);
+  const [searchQuery, setSearchQuery] = useState('');
+
+  useEffect(() => {
+setLoading(true);
+fetch(`/search?query=${encodeURIComponent(searchQuery)}`)
+  .then(response => {
+if (!response.ok) {
+  throw new Error('Network response was not ok');
+}
+return response.json();
+  })
+  .then(data => {
+setTasks(data);
+setLoading(false);
+  })
+  .catch(error => {
+setError(error.message);
+setLoading(false);
+  });
+  }, [searchQuery]); // Depend on searchQuery
+
+  if (loading) {
+return Loading...;
+  }
+
+  if (error) {
+return Error: {error};
+  }
+
+  return (
+
+  Task Search
+   setSearchQuery(e.target.value)}
+  />
+  
+{tasks.map(task => (
+  
+{task.description}
+  
+))}
+  
+
+  );
+};
+
+export default TaskSearch;
\ No newline at end of file

___
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] Add user search (PR #160310)

2025-09-23 Thread Ivan Kosarev via llvm-branch-commits

kosarev 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/160310?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#160310** https://app.graphite.dev/github/pr/llvm/llvm-project/160310?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/160310?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#160308** https://app.graphite.dev/github/pr/llvm/llvm-project/160308?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#160307** https://app.graphite.dev/github/pr/llvm/llvm-project/160307?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/160310
___
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] [AllocToken] Introduce AllocToken instrumentation pass (PR #156838)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits

https://github.com/zmodem edited 
https://github.com/llvm/llvm-project/pull/156838
___
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] [AllocToken] Introduce AllocToken instrumentation pass (PR #156838)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -0,0 +1,471 @@
+//===- AllocToken.cpp - Allocation token instrumentation 
--===//
+//
+// 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
+//
+//===--===//
+//
+// This file implements AllocToken, an instrumentation pass that
+// replaces allocation calls with token-enabled versions.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/AllocToken.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/Analysis.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/xxhash.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace llvm;
+
+#define DEBUG_TYPE "alloc-token"
+
+namespace {
+
+//===--- Constants 
===//
+
+enum class TokenMode : unsigned {
+  /// Incrementally increasing token ID.
+  Increment = 0,
+
+  /// Simple mode that returns a statically-assigned random token ID.
+  Random = 1,
+
+  /// Token ID based on allocated type hash.
+  TypeHash = 2,
+};
+
+//===--- Command-line options 
-===//
+
+cl::opt
+ClMode("alloc-token-mode", cl::Hidden, cl::desc("Token assignment mode"),
+   cl::init(TokenMode::TypeHash),
+   cl::values(clEnumValN(TokenMode::Increment, "increment",
+ "Incrementally increasing token ID"),
+  clEnumValN(TokenMode::Random, "random",
+ "Statically-assigned random token ID"),
+  clEnumValN(TokenMode::TypeHash, "typehash",
+ "Token ID based on allocated type hash")));
+
+cl::opt ClFuncPrefix("alloc-token-prefix",
+  cl::desc("The allocation function prefix"),
+  cl::Hidden, cl::init("__alloc_token_"));
+
+cl::opt ClMaxTokens("alloc-token-max",
+  cl::desc("Maximum number of tokens (0 = no 
max)"),
+  cl::Hidden, cl::init(0));
+
+cl::opt
+ClFastABI("alloc-token-fast-abi",
+  cl::desc("The token ID is encoded in the function name"),
+  cl::Hidden, cl::init(false));
+
+// Instrument libcalls only by default - compatible allocators only need to 
take
+// care of providing standard allocation functions. With extended coverage, 
also
+// instrument non-libcall allocation function calls with !alloc_token
+// metadata.
+cl::opt
+ClExtended("alloc-token-extended",
+   cl::desc("Extend coverage to custom allocation functions"),
+   cl::Hidden, cl::init(false));
+
+// C++ defines ::operator new (and variants) as replaceable (vs. standard
+// library versions), which are nobuiltin, and are therefore not covered by
+// isAllocationFn(). Cover by default, as users of AllocToken are already
+// required to provide token-aware allocation functions (no defaults).
+cl::opt ClCoverReplaceableNew("alloc-token-cover-replaceable-new",
+cl::desc("Cover replaceable operator new"),
+cl::Hidden, cl::init(true));
+
+cl::opt ClFallbackToken(
+"alloc-token-fallback",
+cl::desc("The default fallback token where none could be determined"),
+cl::Hidden, cl::init(0));
+
+//===--- Statistics 
---===//
+
+STATISTIC(NumFunctionsInstrumented, "Functions instrumented");
+STATISTIC(NumAllocationsInstrumented, "Allocations instrumented");
+
+//===--===//
+
+/// Returns the !alloc_token metadata if available.
+///
+/// Expected format is: !{}
+MDNode *getAllocTokenMetadata(const 

[llvm-branch-commits] [llvm] [ConstantFolding] Avoid use of isNonIntegralPointerType() (PR #159959)

2025-09-23 Thread Alexander Richardson via llvm-branch-commits

https://github.com/arichardson updated 
https://github.com/llvm/llvm-project/pull/159959

>From 690f3086eda24b46fc5cc6e9093327c675c0ce21 Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Sun, 21 Sep 2025 14:56:22 -0700
Subject: [PATCH 1/2] fix typo in comment

Created using spr 1.3.8-beta.1
---
 .../InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll 
b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll
index 16980b54f93ad..a9eeca1c2fa20 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 5
 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
-;; Check that we do not create new inttoptr intstructions for unstable pointers
+;; Check that we do not create new inttoptr instructions for unstable pointers
 ;; or pointers with external state (even if the values are all constants).
 ;; NOTE: for all but the zero address space, the GEP should only modify the 
low 8 bits of the pointer.
 target datalayout = "p:16:16:16:16-p1:16:16:16:8-pu2:16:16:16:8-pe3:16:16:16:8"

>From d18eb5ed5f5cdd70930669a722b919816506566a Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Sun, 21 Sep 2025 18:23:59 -0700
Subject: [PATCH 2/2] spelling

Created using spr 1.3.8-beta.1
---
 .../InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll   | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git 
a/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll 
b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll
index a9eeca1c2fa20..da413df013571 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll
@@ -2,7 +2,8 @@
 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
 ;; Check that we do not create new inttoptr instructions for unstable pointers
 ;; or pointers with external state (even if the values are all constants).
-;; NOTE: for all but the zero address space, the GEP should only modify the 
low 8 bits of the pointer.
+;; NOTE: for all but the zero address space, the GEP should only modify the
+;; low 8 bits of the pointer.
 target datalayout = "p:16:16:16:16-p1:16:16:16:8-pu2:16:16:16:8-pe3:16:16:16:8"
 
 define ptr @test_null_base_normal() {
@@ -22,7 +23,7 @@ define ptr @test_inttoptr_base_normal() {
 }
 
 ;; Transformation is fine for non-integral address space, but we can only 
change
-;; the index bits (i8 -2 == i16 254)
+;; the index bits: (i8 -2 == i16 254)
 define ptr addrspace(1) @test_null_base_nonintegral() {
 ; CHECK-LABEL: define ptr addrspace(1) @test_null_base_nonintegral() {
 ; CHECK-NEXT:ret ptr addrspace(1) inttoptr (i16 254 to ptr addrspace(1))

___
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] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)

2025-09-23 Thread via llvm-branch-commits

https://github.com/joaosaffran updated 
https://github.com/llvm/llvm-project/pull/160210

>From 6b191d041990ad667d86b6b07eeed7c802e3fe45 Mon Sep 17 00:00:00 2001
From: Joao Saffran 
Date: Mon, 22 Sep 2025 15:31:47 -0700
Subject: [PATCH 1/2] adding metadata static sampler flags

---
 clang/test/CodeGenHLSL/RootSignature.hlsl |  4 +-
 .../Frontend/HLSL/RootSignatureMetadata.cpp   | 14 +-
 ...gnature-StaticSamplers-Invalid-AddressU.ll |  2 +-
 ...gnature-StaticSamplers-Invalid-AddressV.ll |  2 +-
 ...gnature-StaticSamplers-Invalid-AddressW.ll |  2 +-
 ...ture-StaticSamplers-Invalid-BorderColor.ll |  2 +-
 ...e-StaticSamplers-Invalid-ComparisonFunc.ll |  2 +-
 ...Signature-StaticSamplers-Invalid-Filter.ll |  2 +-
 ...re-StaticSamplers-Invalid-MaxAnisotropy.ll |  2 +-
 ...Signature-StaticSamplers-Invalid-MaxLod.ll |  2 +-
 ...Signature-StaticSamplers-Invalid-MinLod.ll |  2 +-
 ...ature-StaticSamplers-Invalid-MinLopBias.ll |  2 +-
 ...re-StaticSamplers-Invalid-RegisterSpace.ll |  2 +-
 ...e-StaticSamplers-Invalid-ShaderRegister.ll |  2 +-
 ...StaticSamplers-Invalid-ShaderVisibility.ll |  2 +-
 .../RootSignature-StaticSamplers.ll   |  2 +-
 .../RootSignature-StaticSamplers_V3.ll| 43 +++
 .../rootsignature-validation-fail-sampler.ll  |  2 +-
 ...re-validation-fail-static-sampler-range.ll |  4 +-
 19 files changed, 75 insertions(+), 20 deletions(-)
 create mode 100644 
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll

diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl 
b/clang/test/CodeGenHLSL/RootSignature.hlsl
index bc40bdd79ce59..bbab6a73a3658 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -82,8 +82,8 @@ void RootDescriptorsEntry() {}
 // checking minLOD, maxLOD
 // CHECK-SAME: float -1.28e+02, float 1.28e+02,
 
-// checking register, space and visibility
-// CHECK-SAME: i32 42, i32 0, i32 0}
+// checking register, space, visibility and flags
+// CHECK-SAME: i32 42, i32 0, i32 0, i32 0}
 
 #define SampleStaticSampler \
   "StaticSampler(s42, " \
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp 
b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..5ddf129265648 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const 
StaticSampler &Sampler) {
   ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
   ConstantAsMetadata::get(
   Builder.getInt32(to_underlying(Sampler.Visibility))),
+  ConstantAsMetadata::get(Builder.getInt32(0)),
   };
   return MDNode::get(Ctx, Operands);
 }
@@ -411,7 +412,7 @@ Error 
MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
 
 Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
  MDNode *StaticSamplerNode) {
-  if (StaticSamplerNode->getNumOperands() != 14)
+  if (StaticSamplerNode->getNumOperands() != 15)
 return make_error("Static Sampler");
 
   mcdxbc::StaticSampler Sampler;
@@ -495,6 +496,17 @@ Error 
MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
 return Error(std::move(E));
   Sampler.ShaderVisibility = *Visibility;
 
+  if (RSD.Version < 3) {
+RSD.StaticSamplers.push_back(Sampler);
+return Error::success();
+  }
+  assert(RSD.Version >= 3);
+
+  if (std::optional Val = extractMdIntValue(StaticSamplerNode, 14))
+Sampler.Flags = *Val;
+  else
+return make_error("Static Sampler Flags");
+
   RSD.StaticSamplers.push_back(Sampler);
   return Error::success();
 }
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
 
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
index 288dea00b6e55..b043ea1418df6 100644
--- 
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
+++ 
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
@@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" 
"hlsl.shader"="compute" }
 !dx.rootsignatures = !{!2} ; list of function/root signature pairs
 !2 = !{ ptr @main, !3, i32 2 } ; function, root signature
 !3 = !{ !5 } ; list of root signature elements
-!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float 
1.28e+02, i32 42, i32 0, i32 0 }
+!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float 
1.28e+02, i32 42, i32 0, i32 0, i32 0 }
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
 
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
index e9abcf966..8219ffdd679d2 100644
--- 
a/llvm/test/CodeGen/D

[llvm-branch-commits] [llvm] [AMDGPU] Add test to whole-wave-functions.ll. NFC (PR #160361)

2025-09-23 Thread Stanislav Mekhanoshin via llvm-branch-commits

rampitec 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/160361?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#160361** https://app.graphite.dev/github/pr/llvm/llvm-project/160361?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/160361?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#160353** https://app.graphite.dev/github/pr/llvm/llvm-project/160353?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/160361
___
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] [AllocToken, Clang] Implement TypeHashPointerSplit mode (PR #156840)

2025-09-23 Thread Hans Wennborg via llvm-branch-commits


@@ -1272,18 +1272,84 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr 
*E, llvm::Value *Bound,
   EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index);
 }
 
+static bool
+typeContainsPointer(QualType T,
+llvm::SmallPtrSet &VisitedRD,
+bool &IncompleteType) {
+  QualType CanonicalType = T.getCanonicalType();
+  if (CanonicalType->isPointerType())
+return true; // base case
+
+  // Look through typedef chain to check for special types.
+  for (QualType CurrentT = T; const auto *TT = CurrentT->getAs();
+   CurrentT = TT->getDecl()->getUnderlyingType()) {
+const IdentifierInfo *II = TT->getDecl()->getIdentifier();
+if (!II)
+  continue;
+// Special Case: Syntactically uintptr_t is not a pointer; semantically,
+// however, very likely used as such. Therefore, classify uintptr_t as a
+// pointer, too.
+if (II->isStr("uintptr_t"))
+  return true;
+  }
+
+  // The type is an array; check the element type.
+  if (const ArrayType *AT = dyn_cast(CanonicalType))
+return typeContainsPointer(AT->getElementType(), VisitedRD, 
IncompleteType);
+  // The type is a struct, class, or union.
+  if (const RecordDecl *RD = CanonicalType->getAsRecordDecl()) {
+if (!RD->isCompleteDefinition()) {
+  IncompleteType = true;
+  return false;
+}
+if (!VisitedRD.insert(RD).second)
+  return false; // already visited
+// Check all fields.
+for (const FieldDecl *Field : RD->fields()) {
+  if (typeContainsPointer(Field->getType(), VisitedRD, IncompleteType))
+return true;
+}
+// For C++ classes, also check base classes.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
+  // Polymorphic types require a vptr.
+  if (CXXRD->isPolymorphic())

zmodem wrote:

`isDynamicClass()` will also check for virtual base classes.

https://github.com/llvm/llvm-project/pull/156840
___
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] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)

2025-09-23 Thread via llvm-branch-commits

https://github.com/joaosaffran updated 
https://github.com/llvm/llvm-project/pull/160210

>From 6b191d041990ad667d86b6b07eeed7c802e3fe45 Mon Sep 17 00:00:00 2001
From: Joao Saffran 
Date: Mon, 22 Sep 2025 15:31:47 -0700
Subject: [PATCH 1/3] adding metadata static sampler flags

---
 clang/test/CodeGenHLSL/RootSignature.hlsl |  4 +-
 .../Frontend/HLSL/RootSignatureMetadata.cpp   | 14 +-
 ...gnature-StaticSamplers-Invalid-AddressU.ll |  2 +-
 ...gnature-StaticSamplers-Invalid-AddressV.ll |  2 +-
 ...gnature-StaticSamplers-Invalid-AddressW.ll |  2 +-
 ...ture-StaticSamplers-Invalid-BorderColor.ll |  2 +-
 ...e-StaticSamplers-Invalid-ComparisonFunc.ll |  2 +-
 ...Signature-StaticSamplers-Invalid-Filter.ll |  2 +-
 ...re-StaticSamplers-Invalid-MaxAnisotropy.ll |  2 +-
 ...Signature-StaticSamplers-Invalid-MaxLod.ll |  2 +-
 ...Signature-StaticSamplers-Invalid-MinLod.ll |  2 +-
 ...ature-StaticSamplers-Invalid-MinLopBias.ll |  2 +-
 ...re-StaticSamplers-Invalid-RegisterSpace.ll |  2 +-
 ...e-StaticSamplers-Invalid-ShaderRegister.ll |  2 +-
 ...StaticSamplers-Invalid-ShaderVisibility.ll |  2 +-
 .../RootSignature-StaticSamplers.ll   |  2 +-
 .../RootSignature-StaticSamplers_V3.ll| 43 +++
 .../rootsignature-validation-fail-sampler.ll  |  2 +-
 ...re-validation-fail-static-sampler-range.ll |  4 +-
 19 files changed, 75 insertions(+), 20 deletions(-)
 create mode 100644 
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll

diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl 
b/clang/test/CodeGenHLSL/RootSignature.hlsl
index bc40bdd79ce59..bbab6a73a3658 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -82,8 +82,8 @@ void RootDescriptorsEntry() {}
 // checking minLOD, maxLOD
 // CHECK-SAME: float -1.28e+02, float 1.28e+02,
 
-// checking register, space and visibility
-// CHECK-SAME: i32 42, i32 0, i32 0}
+// checking register, space, visibility and flags
+// CHECK-SAME: i32 42, i32 0, i32 0, i32 0}
 
 #define SampleStaticSampler \
   "StaticSampler(s42, " \
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp 
b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..5ddf129265648 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const 
StaticSampler &Sampler) {
   ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
   ConstantAsMetadata::get(
   Builder.getInt32(to_underlying(Sampler.Visibility))),
+  ConstantAsMetadata::get(Builder.getInt32(0)),
   };
   return MDNode::get(Ctx, Operands);
 }
@@ -411,7 +412,7 @@ Error 
MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
 
 Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
  MDNode *StaticSamplerNode) {
-  if (StaticSamplerNode->getNumOperands() != 14)
+  if (StaticSamplerNode->getNumOperands() != 15)
 return make_error("Static Sampler");
 
   mcdxbc::StaticSampler Sampler;
@@ -495,6 +496,17 @@ Error 
MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
 return Error(std::move(E));
   Sampler.ShaderVisibility = *Visibility;
 
+  if (RSD.Version < 3) {
+RSD.StaticSamplers.push_back(Sampler);
+return Error::success();
+  }
+  assert(RSD.Version >= 3);
+
+  if (std::optional Val = extractMdIntValue(StaticSamplerNode, 14))
+Sampler.Flags = *Val;
+  else
+return make_error("Static Sampler Flags");
+
   RSD.StaticSamplers.push_back(Sampler);
   return Error::success();
 }
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
 
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
index 288dea00b6e55..b043ea1418df6 100644
--- 
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
+++ 
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
@@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" 
"hlsl.shader"="compute" }
 !dx.rootsignatures = !{!2} ; list of function/root signature pairs
 !2 = !{ ptr @main, !3, i32 2 } ; function, root signature
 !3 = !{ !5 } ; list of root signature elements
-!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float 
1.28e+02, i32 42, i32 0, i32 0 }
+!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float 
1.28e+02, i32 42, i32 0, i32 0, i32 0 }
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
 
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
index e9abcf966..8219ffdd679d2 100644
--- 
a/llvm/test/CodeGen/D

[llvm-branch-commits] [llvm] release/21.x: [SCEV] Don't perform implication checks with many predicates (#158652) (PR #158798)

2025-09-23 Thread via llvm-branch-commits

github-actions[bot] wrote:

@nikic (or anyone else). If you would like to add a note about this fix in the 
release notes (completely optional). Please reply to this comment with a one or 
two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/158798
___
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] [lldb] 6007a4d - [vscode-lldb] Restart server when lldb-dap binary has changed (#159797)

2025-09-23 Thread via llvm-branch-commits

Author: Roy Shi
Date: 2025-09-23T07:44:50-07:00
New Revision: 6007a4dbed2d8867c75bd571e1eb38e10ae14a27

URL: 
https://github.com/llvm/llvm-project/commit/6007a4dbed2d8867c75bd571e1eb38e10ae14a27
DIFF: 
https://github.com/llvm/llvm-project/commit/6007a4dbed2d8867c75bd571e1eb38e10ae14a27.diff

LOG: [vscode-lldb] Restart server when lldb-dap binary has changed (#159797)

# Motiviation

This helps the development of the lldb-dap binary. For example, when
testing a locally built lldb-dap binary, one probably wants to restart
the server after each build in order to use the latest binary. Not doing
so leads to confusion like "why the new lldb-dap isn't doing what I just
changed?".

This patch adds dependency to the `chokidar` package. The reason is that
we need something to detect changes to the `lldb-dap` binary file and
`chokidar` appears to be the most reliable package to do so. An
alternative solution which doesn't require adding dependencies is
discussed below (solution 1).

# Two different solutions considered

Solution 1: Restart server when lldb-dap binary's modification time
changes. https://github.com/llvm/llvm-project/pull/159481 implements
solution 1.

Solution 2: Restart server when lldb-dap binary has changed (as detected
by a file system watcher). This patch implements solution 2 (using
`chokidar`).

# This patch (solution 2)

If the lldb-dap binary has changed, the next time the user start a debug
session, a dialog box will show up and prompt the user to restart the
server. Depend on what has changed, the dialog box will show different
content (see below)

* When both the lldb-dap binary and the arguments have changed:
https://github.com/user-attachments/assets/6580e05f-05c3-4d80-8c1a-9c3abf279218";
/>

* When only the lldb-dap binary has changed:
https://github.com/user-attachments/assets/933b8987-9c21-44f3-ad68-57b8eeb58525";
/>

* When only the arguments have changed (existing):
https://github.com/user-attachments/assets/c0e6771c-ad32-4fb8-b5df-b34cce48ed1a";
/>

Added: 


Modified: 
lldb/tools/lldb-dap/package-lock.json
lldb/tools/lldb-dap/package.json
lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts

Removed: 




diff  --git a/lldb/tools/lldb-dap/package-lock.json 
b/lldb/tools/lldb-dap/package-lock.json
index f3ae6b76be6d0..826f29f70106c 100644
--- a/lldb/tools/lldb-dap/package-lock.json
+++ b/lldb/tools/lldb-dap/package-lock.json
@@ -8,6 +8,9 @@
   "name": "lldb-dap",
   "version": "0.2.16",
   "license": "Apache 2.0 License with LLVM exceptions",
+  "dependencies": {
+"chokidar": "^4.0.3"
+  },
   "devDependencies": {
 "@types/node": "^18.19.41",
 "@types/tabulator-tables": "^6.2.10",
@@ -1301,6 +1304,21 @@
 "url": "https://github.com/sponsors/fb55";
   }
 },
+"node_modules/chokidar": {
+  "version": "4.0.3",
+  "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz";,
+  "integrity": 
"sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+  "license": "MIT",
+  "dependencies": {
+"readdirp": "^4.0.1"
+  },
+  "engines": {
+"node": ">= 14.16.0"
+  },
+  "funding": {
+"url": "https://paulmillr.com/funding/";
+  }
+},
 "node_modules/chownr": {
   "version": "1.1.4",
   "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz";,
@@ -2746,6 +2764,19 @@
 "node": ">= 6"
   }
 },
+"node_modules/readdirp": {
+  "version": "4.1.2",
+  "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz";,
+  "integrity": 
"sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+  "license": "MIT",
+  "engines": {
+"node": ">= 14.18.0"
+  },
+  "funding": {
+"type": "individual",
+"url": "https://paulmillr.com/funding/";
+  }
+},
 "node_modules/safe-buffer": {
   "version": "5.2.1",
   "resolved": 
"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz";,

diff  --git a/lldb/tools/lldb-dap/package.json 
b/lldb/tools/lldb-dap/package.json
index 6566ba3bdee13..3892535853f56 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -27,6 +27,9 @@
   "categories": [
 "Debuggers"
   ],
+  "dependencies": {
+"chokidar": "^4.0.3"
+  },
   "devDependencies": {
 "@types/node": "^18.19.41",
 "@types/tabulator-tables": "^6.2.10",

diff  --git a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts 
b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
index 280a11d807f6a..4e348965930d9 100644
--- a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
+++ b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
@@ -1,4 +1,6 @@
+import { FSWatcher, watch as chokidarWatch } from 'chokidar';
 import * as child_process from "node:child_process";
+

[llvm-branch-commits] [llvm] [SimplifyCFG] Avoid using isNonIntegralPointerType() (PR #159890)

2025-09-23 Thread Alexander Richardson via llvm-branch-commits

https://github.com/arichardson updated 
https://github.com/llvm/llvm-project/pull/159890

>From 318e921e83ca607732637bcfa1994e525928759e Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Fri, 19 Sep 2025 18:42:03 -0700
Subject: [PATCH 1/3] remove todo comment

Created using spr 1.3.8-beta.1
---
 llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll 
b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
index 0f50e0a95e8c1..6adde1388d8cd 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 
-switch-range-to-icmp < %s | FileCheck %s
-target datalayout="p:40:64:64:32"
+target datalayout="p:40:64:64:32-pe200:64:64:64:32"
 
 declare void @foo1()
 
@@ -33,8 +33,6 @@ F:  ; preds = %0
   ret void
 }
 
-; We need to use finer-grained DataLayout properties for non-integral pointers
-; FIXME: Should be using a switch here
 define void @test1_ptr(ptr %V) {
 ; CHECK-LABEL: @test1_ptr(
 ; CHECK-NEXT:[[MAGICPTR:%.*]] = ptrtoint ptr [[V:%.*]] to i40

>From 67f0cd53bcc901b4bdabcb920e3609183522b48a Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Fri, 19 Sep 2025 18:46:08 -0700
Subject: [PATCH 2/3] add test for as200

Created using spr 1.3.8-beta.1
---
 .../SimplifyCFG/switch_create-custom-dl.ll| 28 +++
 1 file changed, 28 insertions(+)

diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll 
b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
index 6adde1388d8cd..3d11cfe525e45 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
@@ -89,6 +89,34 @@ F:  ; preds = %0
   ret void
 }
 
+; TODO: Should we allow the transformation for pointers with external state?
+define void @test1_ptr_external_state(ptr addrspace(200) %V) {
+; CHECK-LABEL: @test1_ptr_external_state(
+; CHECK-NEXT:[[C1:%.*]] = icmp eq ptr addrspace(200) [[V:%.*]], inttoptr 
(i32 4 to ptr addrspace(200))
+; CHECK-NEXT:[[C2:%.*]] = icmp eq ptr addrspace(200) [[V]], inttoptr (i32 
17 to ptr addrspace(200))
+; CHECK-NEXT:[[CN:%.*]] = or i1 [[C1]], [[C2]]
+; CHECK-NEXT:br i1 [[CN]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:   common.ret:
+; CHECK-NEXT:ret void
+; CHECK:   T:
+; CHECK-NEXT:call void @foo1()
+; CHECK-NEXT:br label [[COMMON_RET:%.*]]
+; CHECK:   F:
+; CHECK-NEXT:call void @foo2()
+; CHECK-NEXT:br label [[COMMON_RET]]
+;
+  %C1 = icmp eq ptr addrspace(200) %V, inttoptr (i32 4 to ptr addrspace(200))
+  %C2 = icmp eq ptr addrspace(200) %V, inttoptr (i32 17 to ptr addrspace(200))
+  %CN = or i1 %C1, %C2;  [#uses=1]
+  br i1 %CN, label %T, label %F
+T:  ; preds = %0
+  call void @foo1( )
+  ret void
+F:  ; preds = %0
+  call void @foo2( )
+  ret void
+}
+
 define void @test2(i32 %V) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:switch i32 [[V:%.*]], label [[T:%.*]] [

>From 636de5001165bcfad13e4c62c190331fc967d81e Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Fri, 19 Sep 2025 23:10:33 -0700
Subject: [PATCH 3/3] clarify comment

Created using spr 1.3.8-beta.1
---
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp 
b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 3699c18966016..68480dc571cf3 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -541,8 +541,8 @@ static ConstantInt *getConstantInt(Value *V, const 
DataLayout &DL) {
   if (isa(V))
 return ConstantInt::get(IntPtrTy, 0);
 
-  // IntToPtr const int, we can look through this unless the semantics of
-  // inttoptr for this address space aren't a simple (truncating) bitcast.
+  // IntToPtr const int, we can look through this if the semantics of
+  // inttoptr for this address space are a simple (truncating) bitcast.
   if (ConstantExpr *CE = dyn_cast(V))
 if (CE->getOpcode() == Instruction::IntToPtr)
   if (ConstantInt *CI = dyn_cast(CE->getOperand(0))) {

___
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] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/159991

>From 1fea50f712f1cd7fec1ddc6dfa59bb185cb96b58 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy

---
 .../clang/Analysis/Analyses/LifetimeSafety.h  |   9 +-
 clang/lib/Analysis/LifetimeSafety.cpp | 429 ---
 clang/test/Sema/warn-lifetime-safety.cpp  | 141 +++--
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
 4 files changed, 602 insertions(+), 478 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..2cc3fb3d69eb4 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -55,6 +55,7 @@ class Fact;
 class FactManager;
 class LoanPropagationAnalysis;
 class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
 struct LifetimeFactory;
 
 /// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
OriginID ID) {
 // TODO(opt): Consider using a bitset to represent the set of loans.
 using LoanSet = llvm::ImmutableSet;
 using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
 /// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,9 @@ class LifetimeSafetyAnalysis {
   /// Returns the set of loans an origin holds at a specific program point.
   LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
 
-  /// Returns the set of loans that have expired at a specific program point.
-  std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+  /// TODO:Document.
+  std::vector>
+  getLiveOriginsAtPoint(ProgramPoint PP) const;
 
   /// Finds the OriginID for a given declaration.
   /// Returns a null optional if not found.
@@ -138,7 +141,7 @@ class LifetimeSafetyAnalysis {
   std::unique_ptr Factory;
   std::unique_ptr FactMgr;
   std::unique_ptr LoanPropagation;
-  std::unique_ptr ExpiredLoans;
+  std::unique_ptr LiveOrigins;
 };
 } // namespace internal
 } // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety.cpp
index 14fb945382e65..f4539752d3f3f 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeProfiler.h"
 #include 
 #include 
@@ -873,19 +874,26 @@ class DataflowAnalysis {
 llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
 
 while (const CFGBlock *B = W.dequeue()) {
-  Lattice StateIn = getInState(B);
+  Lattice StateIn = *getInState(B);
   Lattice StateOut = transferBlock(B, StateIn);
   OutStates[B] = StateOut;
-  Visited.set(B->getBlockID());
   for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
 if (!AdjacentB)
   continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
+  OldInState = *In;
+  NewInState = D.join(OldInState, StateOut);
+} else {
+  OldInState = D.getInitialState();
+  SawFirstTime = true;
+  NewInState = StateOut;
+}
 // Enqueue the adjacent block if its in-state has changed or if we have
 // never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+if (SawFirstTime || NewInState != OldInState) {
   InStates[AdjacentB] = NewInState;
   W.enqueueBlock(AdjacentB);
 }
@@ -896,7 +904,12 @@ class DataflowAnalysis {
 protected:
   Lattice getState(ProgramPoint P) const { return PerPointStates.lookup(P); }
 
-  Lattice getInState(const CFGBlock *B) const { return InStates.lookup(B); }
+  const Lattice *getInState(const CFGBlock *B) const {
+auto It = InStates.find(B);
+if (It != InStates.end())
+  return &It->second;
+return nullptr;
+  }
 
   Lattice getOutState(const CFGBlock *B) const { return OutStates.lookup(B); }
 
@@ -972,42 +985,36 @@ static llvm::ImmutableSet join(llvm::ImmutableSet A,
   return A;
 }
 
-/// Checks if set A is a subset of set B.
-template 
-static bool isSubsetOf(const llvm::ImmutableSet &A,
-   const llvm::ImmutableSet &B) {
-  // Empty set is a subset of all sets.
-  if (A.isEmpty())
-return true;
-
-  for (const T &Elem : A)
-if (!B.contains(Elem))
-  return false

[llvm-branch-commits] [clang] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits


@@ -624,34 +668,68 @@ class FactGenerator : public 
ConstStmtVisitor {
 if (CCE->getNumArgs() != 1)
   return;
 if (hasOrigin(CCE->getArg(0)))
-  addAssignOriginFact(*CCE, *CCE->getArg(0));
+  addOriginFlowFact(*CCE, *CCE->getArg(0));
 else
   // This could be a new borrow.
   handleFunctionCall(CCE, CCE->getConstructor(),
- {CCE->getArgs(), CCE->getNumArgs()});
+ {CCE->getArgs(), CCE->getNumArgs()},
+ /*IsGslConstruction=*/true);
+  }
+  static const FunctionDecl *
+  getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD) {
+return FD != nullptr ? FD->getMostRecentDecl() : nullptr;
   }
 
+  static const CXXMethodDecl *
+  getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD) {
+const FunctionDecl *FD = CMD;
+return cast_if_present(
+getDeclWithMergedLifetimeBoundAttrs(FD));
+  }
+  static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {

usx95 wrote:

Oops. I had this in mind and missed to factorise this. Done now.

https://github.com/llvm/llvm-project/pull/158489
___
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] RegAllocGreedy: Check if copied lanes are live in trySplitAroundHintReg (PR #160424)

2025-09-23 Thread Matt Arsenault via llvm-branch-commits

arsenm 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/160424?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#160424** https://app.graphite.dev/github/pr/llvm/llvm-project/160424?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/160424?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#160294** https://app.graphite.dev/github/pr/llvm/llvm-project/160294?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/160424
___
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] port 5b4819e to release (PR #159209)

2025-09-23 Thread David Blaikie via llvm-branch-commits

https://github.com/dwblaikie updated 
https://github.com/llvm/llvm-project/pull/159209

>From 0c9d972fae57b4af2712632d829ed042381ab9ab Mon Sep 17 00:00:00 2001
From: David Blaikie 
Date: Tue, 16 Sep 2025 22:42:55 +
Subject: [PATCH] Port 5b4819e to release/21.x

Fix for the port of 665e875 to release/21.x in PR156664
---
 clang/test/CodeGenCXX/debug-info-structured-binding.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp 
b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
index 4a4a4d8bdfaad..8032ce85c9e25 100644
--- a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
@@ -10,7 +10,7 @@
 // CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg 
![[Y1_DEBUG_LOC:[0-9]+]]
 // CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg 
![[Y2_DEBUG_LOC:[0-9]+]]
 // CHECK: load ptr, ptr %z2, {{.*}}!dbg ![[Z2_DEBUG_LOC:[0-9]+]]
-// CHECK: getelementptr inbounds [2 x i32], ptr {{.*}}, i64 0, i64 1, !dbg 
![[A2_DEBUG_LOC:[0-9]+]]
+// CHECK: getelementptr inbounds [2 x i32], ptr {{.*}}, i{{64|32}} 0, 
i{{64|32}} 1, !dbg ![[A2_DEBUG_LOC:[0-9]+]]
 // CHECK: getelementptr inbounds nuw { i32, i32 }, ptr {{.*}}, i32 0, i32 1, 
!dbg ![[C2_DEBUG_LOC:[0-9]+]]
 // CHECK: extractelement <2 x i32> {{.*}}, i32 1, !dbg ![[V2_DEBUG_LOC:[0-9]+]]
 // CHECK: ![[VAR_0]] = !DILocalVariable(name: "a"

___
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] [LifetimeSafety] Implement support for lifetimebound attribute (PR #158489)

2025-09-23 Thread Gábor Horváth via llvm-branch-commits

https://github.com/Xazax-hun approved this pull request.


https://github.com/llvm/llvm-project/pull/158489
___
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] 0240295 - Revert "[DebugInfo][DwarfDebug] Separate creation and population of abstract …"

2025-09-23 Thread via llvm-branch-commits

Author: Vladislav Dzhidzhoev
Date: 2025-09-23T19:36:33+02:00
New Revision: 0240295c21020e869f92c162ce80785f13dac358

URL: 
https://github.com/llvm/llvm-project/commit/0240295c21020e869f92c162ce80785f13dac358
DIFF: 
https://github.com/llvm/llvm-project/commit/0240295c21020e869f92c162ce80785f13dac358.diff

LOG: Revert "[DebugInfo][DwarfDebug] Separate creation and population of 
abstract …"

This reverts commit 432b58915ad7257c432a403efe194e5033a53ab0.

Added: 


Modified: 
llvm/include/llvm/CodeGen/DebugHandlerBase.h
llvm/include/llvm/CodeGen/LexicalScopes.h
llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
llvm/lib/CodeGen/LexicalScopes.cpp
llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
llvm/lib/CodeGen/LiveDebugVariables.cpp
llvm/test/CodeGen/X86/dbg-distringtype-uint.ll
llvm/unittests/CodeGen/InstrRefLDVTest.cpp
llvm/unittests/CodeGen/LexicalScopesTest.cpp
llvm/unittests/CodeGen/MFCommon.inc

Removed: 
llvm/test/DebugInfo/AArch64/debug-types.ll
llvm/test/DebugInfo/AArch64/populate-abstract-sp-once.ll
llvm/test/DebugInfo/Generic/inlined-static-var.ll



diff  --git a/llvm/include/llvm/CodeGen/DebugHandlerBase.h 
b/llvm/include/llvm/CodeGen/DebugHandlerBase.h
index fee4bb116bb87..2849497f9a43e 100644
--- a/llvm/include/llvm/CodeGen/DebugHandlerBase.h
+++ b/llvm/include/llvm/CodeGen/DebugHandlerBase.h
@@ -144,8 +144,6 @@ class DebugHandlerBase : public AsmPrinterHandler {
   static bool isUnsignedDIType(const DIType *Ty);
 
   const InstructionOrdering &getInstOrdering() const { return InstOrdering; }
-
-  const LexicalScopes &getLexicalScopes() const { return LScopes; }
 };
 
 } // namespace llvm

diff  --git a/llvm/include/llvm/CodeGen/LexicalScopes.h 
b/llvm/include/llvm/CodeGen/LexicalScopes.h
index 993df54c05ad5..4172e90b4c1b9 100644
--- a/llvm/include/llvm/CodeGen/LexicalScopes.h
+++ b/llvm/include/llvm/CodeGen/LexicalScopes.h
@@ -141,18 +141,12 @@ class LexicalScopes {
 public:
   LexicalScopes() = default;
 
-  /// Scan module to build subprogram-to-function map.
-  LLVM_ABI void initialize(const Module &);
-
   /// Scan machine function and constuct lexical scope nest, resets
   /// the instance if necessary.
-  LLVM_ABI void scanFunction(const MachineFunction &);
-
-  /// Reset the instance so that it's prepared for another module.
-  LLVM_ABI void resetModule();
+  LLVM_ABI void initialize(const MachineFunction &);
 
-  /// Reset the instance so that it's prepared for another function.
-  LLVM_ABI void resetFunction();
+  /// Release memory.
+  LLVM_ABI void reset();
 
   /// Return true if there is any lexical scope information available.
   bool empty() { return CurrentFnLexicalScope == nullptr; }
@@ -202,11 +196,6 @@ class LexicalScopes {
   /// Find or create an abstract lexical scope.
   LLVM_ABI LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope);
 
-  /// Get function to which the given subprogram is attached, if exists.
-  const Function *getFunction(const DISubprogram *SP) const {
-return FunctionMap.lookup(SP);
-  }
-
 private:
   /// Find lexical scope for the given Scope/IA. If not available
   /// then create new lexical scope.
@@ -236,9 +225,6 @@ class LexicalScopes {
 
   const MachineFunction *MF = nullptr;
 
-  /// Mapping between DISubprograms and IR functions.
-  DenseMap FunctionMap;
-
   /// Tracks the scopes in the current function.
   // Use an unordered_map to ensure value pointer validity over insertion.
   std::unordered_map LexicalScopeMap;

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index d98d18035ac6d..0f3ff985974ce 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -105,8 +105,6 @@ DebugHandlerBase::~DebugHandlerBase() = default;
 void DebugHandlerBase::beginModule(Module *M) {
   if (M->debug_compile_units().empty())
 Asm = nullptr;
-  else
-LScopes.initialize(*M);
 }
 
 // Each LexicalScope has first instruction and last instruction to mark
@@ -271,7 +269,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction 
*MF) {
 
   // Grab the lexical scopes for the function, if we don't have any of those
   // then we're not going to be able to do anything.
-  LScopes.scanFunction(*MF);
+  LScopes.initialize(*MF);
   if (LScopes.empty()) {
 beginFunctionImpl(MF);
 return;

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 7ce014e9fac9a..67f526fe91

[llvm-branch-commits] [clang] release/21.x: [RISCV] Reduce RISCV code generation build time (PR #158164)

2025-09-23 Thread Fabrice de Gans via llvm-branch-commits

Steelskin wrote:

@tstellar If we're all good, can you land it, please?

https://github.com/llvm/llvm-project/pull/158164
___
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] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)

2025-09-23 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141665

>From 63bb5f84ce94b89acd3125969147fc3c3031a9ed Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
 helpers

Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()

This patch is NFC aside from minor debug output changes.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 67 +--
 .../AArch64/gs-pauth-debug-output.s   | 14 ++--
 2 files changed, 38 insertions(+), 43 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 192b1da27759e..cfc0bc2cfc0da 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
   TrackedRegisters(ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
-  RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+  RegToIndexMapping[Reg] = MappedIndex;
   }
 
   ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
 
 SafeToDerefRegs &= StateIn.SafeToDerefRegs;
 TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
-  for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -224,11 +224,9 @@ struct SrcState {
 static void printInstsShort(raw_ostream &OS,
 ArrayRef Insts) {
   OS << "Insts: ";
-  for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+  for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
 OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
-  OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
 OS << ")";
   }
 }
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 // Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 return Regs;
@@ -868,9 +868,9 @@ struct DstState {
   return (*this = StateIn);
 
 CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
-  for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -1036,8 +1036,7 @@ class DstSafetyAnalysis {
 
 // ... an address can be updated in a safe manner, or
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
-  MCPhysReg DstReg, SrcReg;
-  std::tie(DstReg, SrcReg) = *DstAndSrc;
+  auto [DstReg, SrcReg] = *DstAndSrc;
   // Note that *all* registers containing the derived values must be safe,
   // both source and destination ones. No temporaries are supported at now.
   if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1077,7 +1076,7 @@ class DstSafetyAnalysis {
 // If this instruction terminates the program immediately, no
 // authentication oracles are possible past this point.
 if (BC.MIB->isTrap(Point)) {
-  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
   DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
   Next.CannotEscapeUnchecked.set();
   return Next;
@@ -1255,7 +1254,7 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis,
   // starting to analyze Inst.
   

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)

2025-09-23 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138884

>From bc28368e0940ff440cdb5556a70f768ee6e32f2e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
 tables

As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.

This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).

For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
 bolt/include/bolt/Core/MCInstUtils.h  |   9 +
 bolt/include/bolt/Core/MCPlusBuilder.h|  14 +
 bolt/lib/Core/MCInstUtils.cpp |  20 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  10 +
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  73 ++
 .../AArch64/gs-pauth-jump-table.s | 703 ++
 6 files changed, 829 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 21e6489057d01..545bdd13c9180 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -142,6 +142,15 @@ class MCInstReference {
 return nullptr;
   }
 
+  /// Returns the only preceding instruction, or std::nullopt if multiple or no
+  /// predecessors are possible.
+  ///
+  /// If CFG information is available, basic block boundary can be crossed,
+  /// provided there is exactly one predecessor. If CFG is not available, the
+  /// preceding instruction in the offset order is returned, unless this is the
+  /// first instruction of the function.
+  std::optional getSinglePredecessor();
+
   raw_ostream &print(raw_ostream &OS) const;
 };
 
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index ae04891e791f9..f13e41c75c2ac 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
 #ifndef BOLT_CORE_MCPLUSBUILDER_H
 #define BOLT_CORE_MCPLUSBUILDER_H
 
+#include "bolt/Core/MCInstUtils.h"
 #include "bolt/Core/MCPlus.h"
 #include "bolt/Core/Relocation.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -711,6 +712,19 @@ class MCPlusBuilder {
 return std::nullopt;
   }
 
+  /// Tests if BranchInst corresponds to an instruction sequence which is known
+  /// to be a safe dispatch via jump table.
+  ///
+  /// The target can decide which instruction sequences to consider "safe" from
+  /// the Pointer Authentication point of view, such as any jump table dispatch
+  /// sequence without function calls inside, any sequence which is contiguous,
+  /// or only some specific well-known sequences.
+  virtual bool
+  isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isTerminator(const MCInst &Inst) const;
 
   virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 3cdb9673d4dc0..39bc96f087f8e 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -54,3 +54,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
   OS << ">";
   return OS;
 }
+
+std::optional MCInstReference::getSinglePredecessor() {
+  if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+  return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+  return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+  }
+
+  const RefInBF &Ref = getRefInBF();
+  if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+  return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 5d884e2d37354..3a6c3e3d925cf 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1370,6 +1370,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC, 
const BinaryFunction &BF,
 return std::nullopt;
   }
 
+  if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)

2025-09-23 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138884

>From bc28368e0940ff440cdb5556a70f768ee6e32f2e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
 tables

As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.

This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).

For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
 bolt/include/bolt/Core/MCInstUtils.h  |   9 +
 bolt/include/bolt/Core/MCPlusBuilder.h|  14 +
 bolt/lib/Core/MCInstUtils.cpp |  20 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  10 +
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  73 ++
 .../AArch64/gs-pauth-jump-table.s | 703 ++
 6 files changed, 829 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 21e6489057d01..545bdd13c9180 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -142,6 +142,15 @@ class MCInstReference {
 return nullptr;
   }
 
+  /// Returns the only preceding instruction, or std::nullopt if multiple or no
+  /// predecessors are possible.
+  ///
+  /// If CFG information is available, basic block boundary can be crossed,
+  /// provided there is exactly one predecessor. If CFG is not available, the
+  /// preceding instruction in the offset order is returned, unless this is the
+  /// first instruction of the function.
+  std::optional getSinglePredecessor();
+
   raw_ostream &print(raw_ostream &OS) const;
 };
 
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index ae04891e791f9..f13e41c75c2ac 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
 #ifndef BOLT_CORE_MCPLUSBUILDER_H
 #define BOLT_CORE_MCPLUSBUILDER_H
 
+#include "bolt/Core/MCInstUtils.h"
 #include "bolt/Core/MCPlus.h"
 #include "bolt/Core/Relocation.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -711,6 +712,19 @@ class MCPlusBuilder {
 return std::nullopt;
   }
 
+  /// Tests if BranchInst corresponds to an instruction sequence which is known
+  /// to be a safe dispatch via jump table.
+  ///
+  /// The target can decide which instruction sequences to consider "safe" from
+  /// the Pointer Authentication point of view, such as any jump table dispatch
+  /// sequence without function calls inside, any sequence which is contiguous,
+  /// or only some specific well-known sequences.
+  virtual bool
+  isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isTerminator(const MCInst &Inst) const;
 
   virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 3cdb9673d4dc0..39bc96f087f8e 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -54,3 +54,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
   OS << ">";
   return OS;
 }
+
+std::optional MCInstReference::getSinglePredecessor() {
+  if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+  return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+  return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+  }
+
+  const RefInBF &Ref = getRefInBF();
+  if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+  return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 5d884e2d37354..3a6c3e3d925cf 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1370,6 +1370,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC, 
const BinaryFunction &BF,
 return std::nullopt;
   }
 
+  if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-09-23 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 85c52e988a046ed31c176431da967f657cf112ff Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-jump-table.s |   6 +-
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 8 files changed, 318 insertions(+), 227 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 3a6c3e3d925cf..4fc0bf2ae54a9 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -364,6 +370,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -386,18 +420,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailur

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-09-23 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 85c52e988a046ed31c176431da967f657cf112ff Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-jump-table.s |   6 +-
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 8 files changed, 318 insertions(+), 227 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 3a6c3e3d925cf..4fc0bf2ae54a9 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -364,6 +370,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -386,18 +420,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailur

[llvm-branch-commits] [clang] 77a3b0e - [RISCV] Refactor RVV builtin code generation for reduce compilation time [NFC] (#154906)

2025-09-23 Thread Tom Stellard via llvm-branch-commits

Author: Kito Cheng
Date: 2025-09-22T18:05:55-07:00
New Revision: 77a3b0eda3610cdda11a9f2bdeda18dc4e49bc95

URL: 
https://github.com/llvm/llvm-project/commit/77a3b0eda3610cdda11a9f2bdeda18dc4e49bc95
DIFF: 
https://github.com/llvm/llvm-project/commit/77a3b0eda3610cdda11a9f2bdeda18dc4e49bc95.diff

LOG: [RISCV] Refactor RVV builtin code generation for reduce compilation time 
[NFC] (#154906)

Extract ManualCodegen blocks from riscv_vector.td to dedicated helper
functions in RISCV.cpp to improve compilation times and code
organization.

This refactoring:
- Reduces riscv_vector_builtin_cg.inc from ~70,000 lines to ~30,000
lines
- Extracts lots of ManualCodegen blocks into helper functions in
RISCV.cpp
- Moves complex code generation logic from TableGen to C++
- Marks extracted functions with LLVM_ATTRIBUTE_NOINLINE to prevent
excessive inlining in EmitRISCVBuiltinExpr's large switch statement,
which would cause compilation time to increase significantly

Performance Impact on AMD Ryzen 9 3950X 16-Core with SSD (Release build)
with GCC 11:

Before: real 1m4.560s, user 0m0.529s, sys 0m0.175s
After:  real 0m22.577s, user 0m0.498s, sys 0m0.152s

Which reduced around 65% of compilation time.

During this refactoring, I also found few more opportunities to optimize
and simplify the code generation logic, but I think leave to next PR
since it already change a lot of code.

Fix #88368

Added: 


Modified: 
clang/include/clang/Basic/riscv_vector.td
clang/lib/CodeGen/TargetBuiltins/RISCV.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/riscv_vector.td 
b/clang/include/clang/Basic/riscv_vector.td
index c1de2bfe4243d..cc5ab38f8f960 100644
--- a/clang/include/clang/Basic/riscv_vector.td
+++ b/clang/include/clang/Basic/riscv_vector.td
@@ -56,34 +56,8 @@ multiclass RVVVLEFFBuiltin types> {
   SupportOverloading = false,
   UnMaskedPolicyScheme = HasPassthruOperand,
   ManualCodegen = [{
-  {
-if (IsMasked) {
-  // Move mask to right before vl.
-  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
-  if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
-Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
-  Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
-  IntrinsicTypes = {ResultType, Ops[4]->getType(), Ops[2]->getType()};
-} else {
-  if (PolicyAttrs & RVV_VTA)
-Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
-  IntrinsicTypes = {ResultType, Ops[3]->getType(), Ops[1]->getType()};
-}
-Value *NewVL = Ops[2];
-Ops.erase(Ops.begin() + 2);
-llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
-llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
-llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
-// Store new_vl.
-clang::CharUnits Align;
-if (IsMasked)
-  Align = 
CGM.getNaturalPointeeTypeAlignment(E->getArg(E->getNumArgs()-2)->getType());
-else
-  Align = CGM.getNaturalPointeeTypeAlignment(E->getArg(1)->getType());
-llvm::Value *Val = Builder.CreateExtractValue(LoadValue, {1});
-Builder.CreateStore(Val, Address(NewVL, Val->getType(), Align));
-return V;
-  }
+return emitRVVVLEFFBuiltin(this, E, ReturnValue, ResultType, ID, Ops,
+   PolicyAttrs, IsMasked, SegInstSEW);
   }] in {
 foreach type = types in {
   def : RVVBuiltin<"v", "vPCePz", type>;
@@ -139,17 +113,8 @@ multiclass RVVIndexedLoad {
 let HasMaskedOffOperand = false,
 MaskedPolicyScheme = NonePolicy,
 ManualCodegen = [{
-  if (IsMasked) {
-// Builtin: (mask, ptr, value, vl). Intrinsic: (value, ptr, mask, vl)
-std::swap(Ops[0], Ops[2]);
-  } else {
-// Builtin: (ptr, value, vl). Intrinsic: (value, ptr, vl)
-std::swap(Ops[0], Ops[1]);
-  }
-  if (IsMasked)
-IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), 
Ops[3]->getType()};
-  else
-IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), 
Ops[2]->getType()};
+  return emitRVVVSEMaskBuiltin(this, E, ReturnValue, ResultType, ID, Ops,
+   PolicyAttrs, IsMasked, SegInstSEW);
 }] in {
   class RVVVSEMaskBuiltin : RVVBuiltin<"m", "0PUem", "c"> {
 let Name = "vsm_v";
@@ -177,17 +142,8 @@ multiclass RVVVSSEBuiltin types> {
   HasMaskedOffOperand = false,
   MaskedPolicyScheme = NonePolicy,
   ManualCodegen = [{
-if (IsMasked) {
-  // Builtin: (mask, ptr, stride, value, vl). Intrinsic: (value, ptr, 
stride, mask, vl)
-  std::swap(Ops[0], Ops[3]);
-} else {
-  // Builtin: (ptr, stride, value, vl). Intrinsic: (value, ptr, 
stride, vl)
-  std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begi

[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_VARIANT (PR #160371)

2025-09-23 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-flang-openmp

Author: Krzysztof Parzyszek (kparzysz)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/160371.diff


9 Files Affected:

- (modified) flang/include/flang/Parser/openmp-utils.h (+1-3) 
- (modified) flang/include/flang/Parser/parse-tree.h (+6-2) 
- (modified) flang/lib/Parser/openmp-parsers.cpp (+3-2) 
- (modified) flang/lib/Parser/unparse.cpp (+2-6) 
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+44-8) 
- (modified) flang/lib/Semantics/resolve-names.cpp (+7-18) 
- (modified) flang/test/Parser/OpenMP/declare-variant.f90 (+44-29) 
- (modified) flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 (+5-4) 
- (modified) flang/test/Semantics/OpenMP/declare-variant.f90 (+4-2) 


``diff
diff --git a/flang/include/flang/Parser/openmp-utils.h 
b/flang/include/flang/Parser/openmp-utils.h
index 34eb6ac3436bc..64be9714f6cc2 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -38,7 +38,6 @@ struct ConstructId {
 static constexpr llvm::omp::Directive id{Id}; \
   }
 
-MAKE_CONSTR_ID(OmpDeclareVariantDirective, D::OMPD_declare_variant);
 MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
 MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
 MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
@@ -92,8 +91,7 @@ struct DirectiveNameScope {
 } else if constexpr (TupleTrait) {
   if constexpr (std::is_base_of_v) {
 return std::get(x.t).DirName();
-  } else if constexpr (std::is_same_v ||
-  std::is_same_v ||
+  } else if constexpr (std::is_same_v ||
   std::is_same_v ||
   std::is_same_v ||
   std::is_same_v ||
diff --git a/flang/include/flang/Parser/parse-tree.h 
b/flang/include/flang/Parser/parse-tree.h
index 4808a5b844a6f..de65088c01eae 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4933,10 +4933,14 @@ struct OpenMPSectionsConstruct {
   t;
 };
 
+// Ref: [4.5:58-60], [5.0:58-60], [5.1:63-68], [5.2:197-198], [6.0:334-336]
+//
+// declare-variant-directive ->
+//DECLARE_VARIANT([base-name:]variant-name) // since 4.5
 struct OmpDeclareVariantDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
+  WRAPPER_CLASS_BOILERPLATE(
+  OmpDeclareVariantDirective, OmpDirectiveSpecification);
   CharBlock source;
-  std::tuple, Name, OmpClauseList> t;
 };
 
 // 2.10.6 declare-target -> DECLARE TARGET (extended-list) |
diff --git a/flang/lib/Parser/openmp-parsers.cpp 
b/flang/lib/Parser/openmp-parsers.cpp
index 3b32e1a4a67b1..6ec6eb4038933 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1763,8 +1763,9 @@ TYPE_PARSER(construct(
 
 // OpenMP 5.2: 7.5.4 Declare Variant directive
 TYPE_PARSER(sourced(construct(
-verbatim("DECLARE VARIANT"_tok) || verbatim("DECLARE_VARIANT"_tok),
-"(" >> maybe(name / ":"), name / ")", Parser{})))
+predicated(Parser{},
+IsDirective(llvm::omp::Directive::OMPD_declare_variant)) >=
+Parser{})))
 
 // 2.16 Declare Reduction Construct
 TYPE_PARSER(sourced(construct(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1b3eef0eefba3..fc81cfb7a3818 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2539,12 +2539,8 @@ class UnparseVisitor {
   }
   void Unparse(const OmpDeclareVariantDirective &x) {
 BeginOpenMP();
-Word("!$OMP DECLARE VARIANT ");
-Put("(");
-Walk(std::get>(x.t), ":");
-Walk(std::get(x.t));
-Put(")");
-Walk(std::get(x.t));
+Word("!$OMP ");
+Walk(x.v);
 Put("\n");
 EndOpenMP();
   }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp 
b/flang/lib/Semantics/check-omp-structure.cpp
index e9bd34d449461..f10858ac1356d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -634,11 +634,6 @@ template  struct 
DirectiveSpellingVisitor {
 std::get(x.t).source, 
Directive::OMPD_declare_target);
 return false;
   }
-  bool Pre(const parser::OmpDeclareVariantDirective &x) {
-checker_(std::get(x.t).source,
-Directive::OMPD_declare_variant);
-return false;
-  }
   bool Pre(const parser::OpenMPGroupprivate &x) {
 checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
 return false;
@@ -1370,9 +1365,50 @@ void OmpStructureChecker::Leave(const 
parser::OpenMPDeclareSimdConstruct &) {
 }
 
 void OmpStructureChecker::Enter(const parser::OmpDeclareVariantDirective &x) {
-  const auto &dir{std::get(x.t)};
-  PushContextAndClauseSets(
-  dir.source, llvm::omp::Directive::OMPD_declare_variant);
+  const parser::OmpDirectiveName &dirName{x.v.DirName()};
+  PushContextAndClauseSets(dirName.source, dirName.v);
+
+  const parser::OmpArgumentList &args{x.v.Arguments()};
+  if (args.v.size() != 1) {
+context_.Say(args.so

[llvm-branch-commits] [clang] f14551d - [RISCV] Reduce ManualCodeGen for RVV intrinsics with rounding mode. NFC

2025-09-23 Thread Tom Stellard via llvm-branch-commits

Author: Craig Topper
Date: 2025-09-22T18:05:55-07:00
New Revision: f14551dbc4e8b698f59a5757446d5af12880547f

URL: 
https://github.com/llvm/llvm-project/commit/f14551dbc4e8b698f59a5757446d5af12880547f
DIFF: 
https://github.com/llvm/llvm-project/commit/f14551dbc4e8b698f59a5757446d5af12880547f.diff

LOG: [RISCV] Reduce ManualCodeGen for RVV intrinsics with rounding mode. NFC

Operate directly on the existing Ops vector instead of copying to
a new vector. This is similar to what the autogenerated codegen
does for other intrinsics.

Added: 


Modified: 
clang/include/clang/Basic/riscv_vector.td

Removed: 




diff  --git a/clang/include/clang/Basic/riscv_vector.td 
b/clang/include/clang/Basic/riscv_vector.td
index 0297a7afe0911..c1de2bfe4243d 100644
--- a/clang/include/clang/Basic/riscv_vector.td
+++ b/clang/include/clang/Basic/riscv_vector.td
@@ -1316,33 +1316,21 @@ let ManualCodegen = [{
 // Unmasked: (passthru, op0, op1, round_mode, vl)
 // Masked:   (passthru, vector_in, vector_in/scalar_in, mask, vxrm, vl, 
policy)
 
-SmallVector Operands;
 bool HasMaskedOff = !(
 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
 (!IsMasked && PolicyAttrs & RVV_VTA));
-unsigned Offset = IsMasked ?
-(HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
-
-if (!HasMaskedOff)
-  Operands.push_back(llvm::PoisonValue::get(ResultType));
-else
-  Operands.push_back(Ops[IsMasked ? 1 : 0]);
-
-Operands.push_back(Ops[Offset]); // op0
-Operands.push_back(Ops[Offset + 1]); // op1
 
 if (IsMasked)
-  Operands.push_back(Ops[0]); // mask
+  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
 
-Operands.push_back(Ops[Offset + 2]); // vxrm
-Operands.push_back(Ops[Offset + 3]); // vl
+if (!HasMaskedOff)
+  Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
 
 if (IsMasked)
-  Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+  Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
 
-IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(), 
Ops.back()->getType()};
-llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
-return Builder.CreateCall(F, Operands, "");
+IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()};
+break;
   }
 }] in {
   // 12.2. Vector Single-Width Averaging Add and Subtract
@@ -1365,34 +1353,22 @@ let ManualCodegen = [{
 // Unmasked: (passthru, op0, op1, round_mode, vl)
 // Masked:   (passthru, vector_in, vector_in/scalar_in, mask, vxrm, vl, 
policy)
 
-SmallVector Operands;
 bool HasMaskedOff = !(
 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
 (!IsMasked && PolicyAttrs & RVV_VTA));
-unsigned Offset = IsMasked ?
-(HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
-
-if (!HasMaskedOff)
-  Operands.push_back(llvm::PoisonValue::get(ResultType));
-else
-  Operands.push_back(Ops[IsMasked ? 1 : 0]);
-
-Operands.push_back(Ops[Offset]); // op0
-Operands.push_back(Ops[Offset + 1]); // op1
 
 if (IsMasked)
-  Operands.push_back(Ops[0]); // mask
+  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
 
-Operands.push_back(Ops[Offset + 2]); // vxrm
-Operands.push_back(Ops[Offset + 3]); // vl
+if (!HasMaskedOff)
+  Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
 
 if (IsMasked)
-  Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+  Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
 
-IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[Offset + 
1]->getType(),
+IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType(),
   Ops.back()->getType()};
-llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
-return Builder.CreateCall(F, Operands, "");
+break;
   }
 }] in {
   // 12.5. Vector Narrowing Fixed-Point Clip Instructions
@@ -1420,7 +1396,6 @@ let ManualCodegen = [{
 // Unmasked: (passthru, op0, op1, round_mode, vl)
 // Masked:   (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, 
policy)
 
-SmallVector Operands;
 bool HasMaskedOff = !(
 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
 (!IsMasked && PolicyAttrs & RVV_VTA));
@@ -1428,35 +1403,20 @@ let ManualCodegen = [{
   (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
   (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
 
-unsigned Offset = IsMasked ?
-(HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
-
-if (!HasMaskedOff)
-  Operands.push_back(llvm::PoisonValue::get(ResultType));
-else
-  Operands.push_back(Ops[IsMasked ? 1 : 0]);
-
-Operands.push_back(Ops[Offset]); // op0
-Operands.push_back(Ops[Offset + 1]); // op1

[llvm-branch-commits] [clang] release/21.x: [RISCV] Reduce RISCV code generation build time (PR #158164)

2025-09-23 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar closed 
https://github.com/llvm/llvm-project/pull/158164
___
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] release/21.x: [RISCV] Reduce RISCV code generation build time (PR #158164)

2025-09-23 Thread via llvm-branch-commits

github-actions[bot] wrote:

@Steelskin (or anyone else). If you would like to add a note about this fix in 
the release notes (completely optional). Please reply to this comment with a 
one or two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/158164
___
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] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_VARIANT (PR #160371)

2025-09-23 Thread Krzysztof Parzyszek via llvm-branch-commits

https://github.com/kparzysz updated 
https://github.com/llvm/llvm-project/pull/160371

>From 38cf6a6c6291845ec4899ae9faf357b9a633 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek 
Date: Tue, 23 Sep 2025 13:40:10 -0500
Subject: [PATCH 1/2] [flang][OpenMP] Use OmpDirectiveSpecification in
 DECLARE_VARIANT

---
 flang/include/flang/Parser/openmp-utils.h |  4 +-
 flang/include/flang/Parser/parse-tree.h   |  8 +-
 flang/lib/Parser/openmp-parsers.cpp   |  5 +-
 flang/lib/Parser/unparse.cpp  |  8 +-
 flang/lib/Semantics/check-omp-structure.cpp   | 52 +++--
 flang/lib/Semantics/resolve-names.cpp | 25 ++-
 flang/test/Parser/OpenMP/declare-variant.f90  | 73 +++
 .../OpenMP/openmp6-directive-spellings.f90|  9 ++-
 .../test/Semantics/OpenMP/declare-variant.f90 |  6 +-
 9 files changed, 116 insertions(+), 74 deletions(-)

diff --git a/flang/include/flang/Parser/openmp-utils.h 
b/flang/include/flang/Parser/openmp-utils.h
index 34eb6ac3436bc..64be9714f6cc2 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -38,7 +38,6 @@ struct ConstructId {
 static constexpr llvm::omp::Directive id{Id}; \
   }
 
-MAKE_CONSTR_ID(OmpDeclareVariantDirective, D::OMPD_declare_variant);
 MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
 MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
 MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
@@ -92,8 +91,7 @@ struct DirectiveNameScope {
 } else if constexpr (TupleTrait) {
   if constexpr (std::is_base_of_v) {
 return std::get(x.t).DirName();
-  } else if constexpr (std::is_same_v ||
-  std::is_same_v ||
+  } else if constexpr (std::is_same_v ||
   std::is_same_v ||
   std::is_same_v ||
   std::is_same_v ||
diff --git a/flang/include/flang/Parser/parse-tree.h 
b/flang/include/flang/Parser/parse-tree.h
index 4808a5b844a6f..de65088c01eae 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4933,10 +4933,14 @@ struct OpenMPSectionsConstruct {
   t;
 };
 
+// Ref: [4.5:58-60], [5.0:58-60], [5.1:63-68], [5.2:197-198], [6.0:334-336]
+//
+// declare-variant-directive ->
+//DECLARE_VARIANT([base-name:]variant-name) // since 4.5
 struct OmpDeclareVariantDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
+  WRAPPER_CLASS_BOILERPLATE(
+  OmpDeclareVariantDirective, OmpDirectiveSpecification);
   CharBlock source;
-  std::tuple, Name, OmpClauseList> t;
 };
 
 // 2.10.6 declare-target -> DECLARE TARGET (extended-list) |
diff --git a/flang/lib/Parser/openmp-parsers.cpp 
b/flang/lib/Parser/openmp-parsers.cpp
index 3b32e1a4a67b1..6ec6eb4038933 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1763,8 +1763,9 @@ TYPE_PARSER(construct(
 
 // OpenMP 5.2: 7.5.4 Declare Variant directive
 TYPE_PARSER(sourced(construct(
-verbatim("DECLARE VARIANT"_tok) || verbatim("DECLARE_VARIANT"_tok),
-"(" >> maybe(name / ":"), name / ")", Parser{})))
+predicated(Parser{},
+IsDirective(llvm::omp::Directive::OMPD_declare_variant)) >=
+Parser{})))
 
 // 2.16 Declare Reduction Construct
 TYPE_PARSER(sourced(construct(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1b3eef0eefba3..fc81cfb7a3818 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2539,12 +2539,8 @@ class UnparseVisitor {
   }
   void Unparse(const OmpDeclareVariantDirective &x) {
 BeginOpenMP();
-Word("!$OMP DECLARE VARIANT ");
-Put("(");
-Walk(std::get>(x.t), ":");
-Walk(std::get(x.t));
-Put(")");
-Walk(std::get(x.t));
+Word("!$OMP ");
+Walk(x.v);
 Put("\n");
 EndOpenMP();
   }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp 
b/flang/lib/Semantics/check-omp-structure.cpp
index e9bd34d449461..f10858ac1356d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -634,11 +634,6 @@ template  struct 
DirectiveSpellingVisitor {
 std::get(x.t).source, 
Directive::OMPD_declare_target);
 return false;
   }
-  bool Pre(const parser::OmpDeclareVariantDirective &x) {
-checker_(std::get(x.t).source,
-Directive::OMPD_declare_variant);
-return false;
-  }
   bool Pre(const parser::OpenMPGroupprivate &x) {
 checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
 return false;
@@ -1370,9 +1365,50 @@ void OmpStructureChecker::Leave(const 
parser::OpenMPDeclareSimdConstruct &) {
 }
 
 void OmpStructureChecker::Enter(const parser::OmpDeclareVariantDirective &x) {
-  const auto &dir{std::get(x.t)};
-  PushContextAndClauseSets(
-  dir.source, llvm::omp::Directive::OMPD_declare_variant);
+  const parser::OmpDirectiveName &dirName{x.v.DirName()};
+  PushContextAndClauseSets(dirName.source, dirName.v);

[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)

2025-09-23 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/159991

>From 56856961f02009003fd863b38424b8d02d39aa85 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy

---
 .../clang/Analysis/Analyses/LifetimeSafety.h  |  18 +-
 clang/lib/Analysis/LifetimeSafety.cpp | 465 +---
 clang/test/Sema/warn-lifetime-safety.cpp  | 138 +++--
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
 4 files changed, 642 insertions(+), 480 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..6d3e3f61446e0 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -29,7 +29,7 @@
 namespace clang::lifetimes {
 
 /// Enum to track the confidence level of a potential error.
-enum class Confidence {
+enum class Confidence : uint8_t {
   None,
   Maybe,   // Reported as a potential error (-Wlifetime-safety-strict)
   Definite // Reported as a definite error (-Wlifetime-safety-permissive)
@@ -55,6 +55,7 @@ class Fact;
 class FactManager;
 class LoanPropagationAnalysis;
 class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
 struct LifetimeFactory;
 
 /// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
OriginID ID) {
 // TODO(opt): Consider using a bitset to represent the set of loans.
 using LoanSet = llvm::ImmutableSet;
 using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
 /// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,16 @@ class LifetimeSafetyAnalysis {
   /// Returns the set of loans an origin holds at a specific program point.
   LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
 
-  /// Returns the set of loans that have expired at a specific program point.
-  std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+  /// Returns the set of origins that are live at a specific program point,
+  /// along with the confidence level of their liveness.
+  ///
+  /// An origin is considered live if there are potential future uses of that
+  /// origin after the given program point. The confidence level indicates
+  /// whether the origin is definitely live (Definite) due to being domintated
+  /// by a set of uses or only possibly live (Maybe) only on some but not all
+  /// control flow paths.
+  std::vector>
+  getLiveOriginsAtPoint(ProgramPoint PP) const;
 
   /// Finds the OriginID for a given declaration.
   /// Returns a null optional if not found.
@@ -138,7 +148,7 @@ class LifetimeSafetyAnalysis {
   std::unique_ptr Factory;
   std::unique_ptr FactMgr;
   std::unique_ptr LoanPropagation;
-  std::unique_ptr ExpiredLoans;
+  std::unique_ptr LiveOrigins;
 };
 } // namespace internal
 } // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety.cpp
index 14fb945382e65..4978c4fbffaec 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeProfiler.h"
 #include 
 #include 
@@ -873,19 +874,26 @@ class DataflowAnalysis {
 llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
 
 while (const CFGBlock *B = W.dequeue()) {
-  Lattice StateIn = getInState(B);
+  Lattice StateIn = *getInState(B);
   Lattice StateOut = transferBlock(B, StateIn);
   OutStates[B] = StateOut;
-  Visited.set(B->getBlockID());
   for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
 if (!AdjacentB)
   continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
+  OldInState = *In;
+  NewInState = D.join(OldInState, StateOut);
+} else {
+  OldInState = D.getInitialState();
+  SawFirstTime = true;
+  NewInState = StateOut;
+}
 // Enqueue the adjacent block if its in-state has changed or if we have
 // never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+if (SawFirstTime || NewInState != OldInState) {
   InStates[AdjacentB] = NewInState;
   W.enqueueBlock(AdjacentB);
 }
@@ -896,7 +904,12 @@ class DataflowAnalysis {
 protected:
   Lattice getState(ProgramPoint P)