[llvm-branch-commits] [llvm] [AMDGPU] Add structural stall heuristic to scheduling strategies (PR #169617)

2025-12-02 Thread Austin Kerbow via llvm-branch-commits

https://github.com/kerbowa ready_for_review 
https://github.com/llvm/llvm-project/pull/169617
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU] Add structural stall heuristic to scheduling strategies (PR #169617)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-amdgpu

Author: Austin Kerbow (kerbowa)


Changes

Implements a structural stall heuristic that considers both resource
hazards and latency constraints when selecting instructions from the
pending queue.

- Add getStructuralStallCycles() to GCNSchedStrategy that computes the
number of cycles an instruction must wait due to:
  - Resource conflicts on unbuffered resources (from the SchedModel)
  - Sequence-dependent hazards (from GCNHazardRecognizer)

- Add getHazardWaitStates() to GCNHazardRecognizer that returns the number
of wait states until all hazards for an instruction are resolved,
providing cycle-accurate hazard information for scheduling heuristics.

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


7 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp (+72) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.h (+3) 
- (modified) llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp (+4) 
- (modified) llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h (+6) 
- (modified) llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp (+35) 
- (modified) llvm/lib/Target/AMDGPU/GCNSchedStrategy.h (+6-2) 
- (modified) llvm/test/CodeGen/AMDGPU/ml-sched-effective-stall.mir (+5-3) 


``diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp
index 8c68223c0a492..08cf930de3178 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp
@@ -13,6 +13,10 @@
 
 #include "AMDGPUMLSchedStrategy.h"
 
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "machine-scheduler"
+
 using namespace llvm;
 
 AMDGPUMLSchedStrategy::AMDGPUMLSchedStrategy(const MachineSchedContext *C)
@@ -130,6 +134,74 @@ bool AMDGPUMLSchedStrategy::tryCandidate(SchedCandidate 
&Cand,
   return false;
 }
 
+bool AMDGPUMLSchedStrategy::tryPendingCandidate(SchedCandidate &Cand,
+SchedCandidate &TryCand,
+SchedBoundary *Zone) const {
+  // Initialize the candidate if needed.
+  if (!Cand.isValid()) {
+TryCand.Reason = NodeOrder;
+return true;
+  }
+
+  // Bias PhysReg Defs and copies to their uses and defined respectively.
+  if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
+ biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
+return TryCand.Reason != NoCand;
+
+  // Avoid exceeding the target's limit.
+  if (DAG->isTrackingPressure() &&
+  tryPressure(TryCand.RPDelta.Excess, Cand.RPDelta.Excess, TryCand, Cand,
+  RegExcess, TRI, DAG->MF))
+return TryCand.Reason != NoCand;
+
+  // Avoid increasing the max critical pressure in the scheduled region.
+  if (DAG->isTrackingPressure() &&
+  tryPressure(TryCand.RPDelta.CriticalMax, Cand.RPDelta.CriticalMax,
+  TryCand, Cand, RegCritical, TRI, DAG->MF))
+return TryCand.Reason != NoCand;
+
+  bool SameBoundary = Zone != nullptr;
+  if (SameBoundary) {
+// Compare effective stall cycles between candidates.
+// Effective stall = max(structural stall, latency stall)
+// - Structural stalls: resource/hazard constraints (HW not ready)
+// - Latency stalls: data dependency constraints (operands not ready)
+//
+// This allows picking a pending instruction with structural stalls over
+// an available instruction with higher latency stalls (e.g., scheduling
+// a WMMA while waiting for a memory load result).
+unsigned TryStructStall = getStructuralStallCycles(*Zone, TryCand.SU);
+unsigned TryLatencyStall = Zone->getLatencyStallCycles(TryCand.SU);
+unsigned TryEffectiveStall = std::max(TryStructStall, TryLatencyStall);
+
+unsigned CandStructStall = getStructuralStallCycles(*Zone, Cand.SU);
+unsigned CandLatencyStall = Zone->getLatencyStallCycles(Cand.SU);
+unsigned CandEffectiveStall = std::max(CandStructStall, CandLatencyStall);
+
+LLVM_DEBUG(if (TryEffectiveStall || CandEffectiveStall) {
+  dbgs() << "Effective stalls: try=" << TryEffectiveStall
+ << " (struct=" << TryStructStall << ", lat=" << TryLatencyStall
+ << ") cand=" << CandEffectiveStall
+ << " (struct=" << CandStructStall << ", lat=" << CandLatencyStall
+ << ")\n";
+});
+
+if (tryLess(TryEffectiveStall, CandEffectiveStall, TryCand, Cand, Stall))
+  return TryCand.Reason != NoCand;
+
+TryCand.initResourceDelta(DAG, SchedModel);
+if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
+TryCand, Cand, ResourceReduce))
+  return TryCand.Reason != NoCand;
+if (tryGreater(TryCand.ResDelta.DemandedResources,
+   Cand.ResDelta.DemandedResources, TryCand, Cand,
+   ResourceDemand))
+  return TryCand.Reason != NoCand;
+  }
+
+  return false;
+}
+
 AMDGPUMLPostSchedStrategy::AM

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 5: Iterating Expansion Statements) (PR #169684)

2025-12-02 Thread via llvm-branch-commits

Sirraide wrote:

Update, I think I have figured out the lambda situation at this point (as in 
building the lambda and evaluating it works for simple examples); now I just 
need to test it thoroughly.

https://github.com/llvm/llvm-project/pull/169684
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/170329

>From 05d4afa766293ae1279ca0fad66b816d868553f3 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 24 Nov 2025 13:48:45 -0500
Subject: [PATCH] StackProtector: Use LibcallLoweringInfo analysis

---
 llvm/lib/CodeGen/StackProtector.cpp   | 82 +--
 .../NVPTX/no-stack-protector-libcall-error.ll |  2 +-
 .../X86/stack-protector-atomicrmw-xchg.ll |  4 +-
 .../cross-dso-cfi-stack-chk-fail.ll   |  2 +-
 .../StackProtector/missing-analysis.ll|  7 ++
 .../StackProtector/stack-chk-fail-alias.ll|  2 +-
 6 files changed, 67 insertions(+), 32 deletions(-)
 create mode 100644 llvm/test/Transforms/StackProtector/missing-analysis.ll

diff --git a/llvm/lib/CodeGen/StackProtector.cpp 
b/llvm/lib/CodeGen/StackProtector.cpp
index 5fd5d6cce23df..d56ef00ac7d08 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -69,13 +69,15 @@ static cl::opt 
DisableCheckNoReturn("disable-check-noreturn-call",
 ///  - The prologue code loads and stores the stack guard onto the stack.
 ///  - The epilogue checks the value stored in the prologue against the 
original
 ///value. It calls __stack_chk_fail if they differ.
-static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
-  DomTreeUpdater *DTU, bool &HasPrologue,
-  bool &HasIRCheck);
+static bool InsertStackProtectors(const TargetLowering &TLI,
+  const LibcallLoweringInfo &Libcalls,
+  Function *F, DomTreeUpdater *DTU,
+  bool &HasPrologue, bool &HasIRCheck);
 
 /// CreateFailBB - Create a basic block to jump to when the stack protector
 /// check fails.
-static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
+static BasicBlock *CreateFailBB(Function *F,
+const LibcallLoweringInfo &Libcalls);
 
 bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
   return HasPrologue && !HasIRCheck && isa(BB.getTerminator());
@@ -131,8 +133,23 @@ PreservedAnalyses StackProtectorPass::run(Function &F,
   return PreservedAnalyses::all();
   }
 
+  auto &MAMProxy = FAM.getResult(F);
+  const LibcallLoweringModuleAnalysisResult *LibcallLowering =
+  MAMProxy.getCachedResult(*F.getParent());
+
+  if (!LibcallLowering) {
+F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
+ "' analysis required");
+return PreservedAnalyses::all();
+  }
+
+  const TargetSubtargetInfo *STI = TM->getSubtargetImpl(F);
+  const TargetLowering *TLI = STI->getTargetLowering();
+  const LibcallLoweringInfo &Libcalls =
+  LibcallLowering->getLibcallLowering(*STI);
+
   ++NumFunProtected;
-  bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,
+  bool Changed = InsertStackProtectors(*TLI, Libcalls, &F, DT ? &DTU : nullptr,
Info.HasPrologue, Info.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DT ||
@@ -156,6 +173,7 @@ StackProtector::StackProtector() : FunctionPass(ID) {
 
 INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE,
   "Insert stack protectors", false, true)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
@@ -164,6 +182,7 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
 FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }
 
 void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired();
   AU.addRequired();
   AU.addPreserved();
 }
@@ -190,9 +209,16 @@ bool StackProtector::runOnFunction(Function &Fn) {
   return false;
   }
 
+  const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(Fn);
+  const LibcallLoweringInfo &Libcalls =
+  getAnalysis().getLibcallLowering(*M,
+   *Subtarget);
+
+  const TargetLowering *TLI = Subtarget->getTargetLowering();
+
   ++NumFunProtected;
   bool Changed =
-  InsertStackProtectors(TM, F, DTU ? &*DTU : nullptr,
+  InsertStackProtectors(*TLI, Libcalls, F, DTU ? &*DTU : nullptr,
 LayoutInfo.HasPrologue, LayoutInfo.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DTU ||
@@ -519,10 +545,10 @@ bool SSPLayoutAnalysis::requiresStackProtector(Function 
*F,
 
 /// Create a stack guard loading and populate whether SelectionDAG SSP is
 /// supported.
-static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
+static Value *getStackGuard(const TargetLoweringBase &TLI, Module *M,
 IRBuilder<> &B,
 bool *SupportsSelectionDAGSP = nullptr) {
-  Value *Guard = TLI->getIRSt

[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/170328

>From 49b0899068bb9ad83cda0de4fdcbed480a4d1fb3 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 24 Nov 2025 18:15:49 -0500
Subject: [PATCH 1/2] GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.
---
 .../llvm/CodeGen/GlobalISel/Legalizer.h   |  11 +-
 .../llvm/CodeGen/GlobalISel/LegalizerHelper.h |  73 +
 llvm/lib/CodeGen/GlobalISel/Legalizer.cpp |  24 +--
 .../CodeGen/GlobalISel/LegalizerHelper.cpp| 149 +-
 llvm/lib/Target/ARM/ARMLegalizerInfo.cpp  |  18 +--
 .../CodeGen/GlobalISel/GISelMITest.h  |   4 +
 .../GlobalISel/LegalizerHelperTest.cpp|  63 
 .../CodeGen/GlobalISel/LegalizerTest.cpp  |   6 +-
 8 files changed, 183 insertions(+), 165 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h 
b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
+class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult
-  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
-  ArrayRef AuxObservers,
-  LostDebugLocObserver &LocObserver,
-  MachineIRBuilder &MIRBuilder, GISelValueTracking 
*VT);
+  static MFResult legalizeMachineFunction(
+  MachineFunction &MF, const LegalizerInfo &LI,
+  ArrayRef AuxObservers,
+  LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+  const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h 
b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-  GISelValueTracking *VT;
+
+  // FIXME: Should probably make Libcalls mandatory
+  const LibcallLoweringInfo *Libcalls = nullptr;
+  GISelValueTracking *VT = nullptr;
 
 public:
   enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
+  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-   MachineIRBuilder &B);
+   MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer, MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr,
GISelValueTracking *VT = nullptr);
 
   /// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
   /// def by inserting a G_BITCAST from \p CastTy
   LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
 
+  // Useful for libcalls where all operands have the same type.
+  LLVM_ABI LegalizeResult
+  simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
+Type *OpType, LostDebugLocObserver &LocObserver) const;
+
+  LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
+Type *FromType,
+LostDebugLocObserver &LocObserver,
+bool IsSigned = false) const;
+
+  /// Helper function that creates a libcall to the given \p Name using the
+  /// given calling convention \p CC.
+  LLVM_ABI Le

[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/170329

>From 05d4afa766293ae1279ca0fad66b816d868553f3 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 24 Nov 2025 13:48:45 -0500
Subject: [PATCH] StackProtector: Use LibcallLoweringInfo analysis

---
 llvm/lib/CodeGen/StackProtector.cpp   | 82 +--
 .../NVPTX/no-stack-protector-libcall-error.ll |  2 +-
 .../X86/stack-protector-atomicrmw-xchg.ll |  4 +-
 .../cross-dso-cfi-stack-chk-fail.ll   |  2 +-
 .../StackProtector/missing-analysis.ll|  7 ++
 .../StackProtector/stack-chk-fail-alias.ll|  2 +-
 6 files changed, 67 insertions(+), 32 deletions(-)
 create mode 100644 llvm/test/Transforms/StackProtector/missing-analysis.ll

diff --git a/llvm/lib/CodeGen/StackProtector.cpp 
b/llvm/lib/CodeGen/StackProtector.cpp
index 5fd5d6cce23df..d56ef00ac7d08 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -69,13 +69,15 @@ static cl::opt 
DisableCheckNoReturn("disable-check-noreturn-call",
 ///  - The prologue code loads and stores the stack guard onto the stack.
 ///  - The epilogue checks the value stored in the prologue against the 
original
 ///value. It calls __stack_chk_fail if they differ.
-static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
-  DomTreeUpdater *DTU, bool &HasPrologue,
-  bool &HasIRCheck);
+static bool InsertStackProtectors(const TargetLowering &TLI,
+  const LibcallLoweringInfo &Libcalls,
+  Function *F, DomTreeUpdater *DTU,
+  bool &HasPrologue, bool &HasIRCheck);
 
 /// CreateFailBB - Create a basic block to jump to when the stack protector
 /// check fails.
-static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
+static BasicBlock *CreateFailBB(Function *F,
+const LibcallLoweringInfo &Libcalls);
 
 bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
   return HasPrologue && !HasIRCheck && isa(BB.getTerminator());
@@ -131,8 +133,23 @@ PreservedAnalyses StackProtectorPass::run(Function &F,
   return PreservedAnalyses::all();
   }
 
+  auto &MAMProxy = FAM.getResult(F);
+  const LibcallLoweringModuleAnalysisResult *LibcallLowering =
+  MAMProxy.getCachedResult(*F.getParent());
+
+  if (!LibcallLowering) {
+F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
+ "' analysis required");
+return PreservedAnalyses::all();
+  }
+
+  const TargetSubtargetInfo *STI = TM->getSubtargetImpl(F);
+  const TargetLowering *TLI = STI->getTargetLowering();
+  const LibcallLoweringInfo &Libcalls =
+  LibcallLowering->getLibcallLowering(*STI);
+
   ++NumFunProtected;
-  bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,
+  bool Changed = InsertStackProtectors(*TLI, Libcalls, &F, DT ? &DTU : nullptr,
Info.HasPrologue, Info.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DT ||
@@ -156,6 +173,7 @@ StackProtector::StackProtector() : FunctionPass(ID) {
 
 INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE,
   "Insert stack protectors", false, true)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
@@ -164,6 +182,7 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
 FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }
 
 void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired();
   AU.addRequired();
   AU.addPreserved();
 }
@@ -190,9 +209,16 @@ bool StackProtector::runOnFunction(Function &Fn) {
   return false;
   }
 
+  const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(Fn);
+  const LibcallLoweringInfo &Libcalls =
+  getAnalysis().getLibcallLowering(*M,
+   *Subtarget);
+
+  const TargetLowering *TLI = Subtarget->getTargetLowering();
+
   ++NumFunProtected;
   bool Changed =
-  InsertStackProtectors(TM, F, DTU ? &*DTU : nullptr,
+  InsertStackProtectors(*TLI, Libcalls, F, DTU ? &*DTU : nullptr,
 LayoutInfo.HasPrologue, LayoutInfo.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DTU ||
@@ -519,10 +545,10 @@ bool SSPLayoutAnalysis::requiresStackProtector(Function 
*F,
 
 /// Create a stack guard loading and populate whether SelectionDAG SSP is
 /// supported.
-static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
+static Value *getStackGuard(const TargetLoweringBase &TLI, Module *M,
 IRBuilder<> &B,
 bool *SupportsSelectionDAGSP = nullptr) {
-  Value *Guard = TLI->getIRSt

[llvm-branch-commits] [clang] dereference_operator (PR #170006)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

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

>From a3842ac95cb27c2303ab5ebbe40e80c4a55f5fc5 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sat, 29 Nov 2025 15:49:00 +
Subject: [PATCH] dereference_operator

---
 .../LifetimeSafety/FactsGenerator.cpp |  4 
 .../Sema/warn-lifetime-safety-dataflow.cpp|  3 +++
 clang/test/Sema/warn-lifetime-safety.cpp  | 22 +--
 3 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index f8f213c2b2db8..96a1d69ad611d 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -217,6 +217,10 @@ void FactsGenerator::VisitUnaryOperator(const 
UnaryOperator *UO) {
 // origin of this UnaryOperator expression.
 killAndFlowOrigin(*UO, *SubExpr);
   }
+  if (UO->getOpcode() == UO_Deref) {
+const Expr *SubExpr = UO->getSubExpr();
+killAndFlowOrigin(*UO, *SubExpr);
+  }
 }
 
 void FactsGenerator::VisitReturnStmt(const ReturnStmt *RS) {
diff --git a/clang/test/Sema/warn-lifetime-safety-dataflow.cpp 
b/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
index 6d5711deba1cf..d1b3d17fcdd24 100644
--- a/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
@@ -152,6 +152,9 @@ void pointer_indirection() {
 // CHECK-NEXT:   Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
 // CHECK-NEXT:   Src:  [[O_PP_INNER]] (Decl: pp, Type : int *)
 // CHECK:   OriginFlow:
+// CHECK-NEXT:   Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
+// CHECK-NEXT:   Src:  {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
+// CHECK:   OriginFlow:
 // CHECK-NEXT:   Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
 // CHECK-NEXT:   Src:  {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
 // CHECK:   OriginFlow:
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index e62c3b69b040b..f22c73cfeb784 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -596,10 +596,10 @@ const int* return_pointer_to_parameter_via_reference(int 
a, int b, bool cond) {
 const int* d = &c;
 return d; // expected-note 2 {{returned here}}
 }
-// FIXME: Dereference of a pointer does not track the reference.
+
 const int& return_pointer_to_parameter_via_reference_1(int a) {
-const int* d = &a;
-return *d;
+const int* d = &a; // expected-warning {{address of stack memory is 
returned later}}
+return *d;// expected-note {{returned here}}
 }
 
 const int& get_ref_to_local() {
@@ -1118,24 +1118,24 @@ struct MyObjStorage {
   const MyObj *end() const { return objs + 1; }
 };
 
-// FIXME: Detect use-after-scope. Dereference pointer does not propagate the 
origins.
 void range_based_for_use_after_scope() {
   View v;
   {
 MyObjStorage s;
-for (const MyObj &o : s) {
+for (const MyObj &o : s) { // expected-warning {{object whose reference is 
captured does not live long enough}}
   v = o;
 }
-  }
-  v.use();
+  } // expected-note {{destroyed here}}
+  v.use(); // expected-note {{later used here}}
 }
-// FIXME: Detect use-after-return. Dereference pointer does not propagate the 
origins.
+
 View range_based_for_use_after_return() {
   MyObjStorage s;
-  for (const MyObj &o : s) {
-return o;
+  for (const MyObj &o : s) { // expected-warning {{address of stack memory is 
returned later}}
+return o;  // expected-note {{returned here}}
   }
-  return *s.begin();
+  return *s.begin();  // expected-warning {{address of stack memory is 
returned later}}
+  // expected-note@-1 {{returned here}}
 }
 
 void range_based_for_not_reference() {

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] std_move false positive (PR #170007)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

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

>From 00be6fa3eaa4f7f68b34438d5b2295f0b0ad8f59 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sat, 29 Nov 2025 16:43:06 +
Subject: [PATCH] std_move false positive

---
 .../Analyses/LifetimeSafety/FactsGenerator.h   |  2 ++
 .../lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 14 ++
 2 files changed, 16 insertions(+)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index 5b5626020e772..2c7a9bbbc9e2f 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -101,6 +101,8 @@ class FactsGenerator : public 
ConstStmtVisitor {
   // corresponding to the left-hand side is updated to be a "write", thereby
   // exempting it from the check.
   llvm::DenseMap UseFacts;
+
+  llvm::DenseSet MovedDecls;
 };
 
 } // namespace clang::lifetimes::internal
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 96a1d69ad611d..8fb9cd04b2a42 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -162,9 +162,21 @@ void FactsGenerator::VisitCXXMemberCallExpr(const 
CXXMemberCallExpr *MCE) {
   }
 }
 
+static bool isStdMove(const FunctionDecl *FD) {
+  return FD && FD->isInStdNamespace() && FD->getIdentifier() &&
+ FD->getName() == "move";
+}
+
 void FactsGenerator::VisitCallExpr(const CallExpr *CE) {
   handleFunctionCall(CE, CE->getDirectCallee(),
  {CE->getArgs(), CE->getNumArgs()});
+  // Remember accessPath which moved using std::move.
+  // TODO: If there is need, this could flow-sensitive
+  if (isStdMove(CE->getDirectCallee()))
+if (CE->getNumArgs() == 1)
+  if (auto *DRE =
+  dyn_cast(CE->getArg(0)->IgnoreParenImpCasts()))
+MovedDecls.insert(DRE->getDecl());
 }
 
 void FactsGenerator::VisitCXXNullPtrLiteralExpr(
@@ -340,6 +352,8 @@ void FactsGenerator::handleLifetimeEnds(const 
CFGLifetimeEnds &LifetimeEnds) {
   // Iterate through all loans to see if any expire.
   for (const auto &Loan : FactMgr.getLoanMgr().getLoans()) {
 const AccessPath &LoanPath = Loan.Path;
+if (MovedDecls.contains(LoanPath.D))
+  continue;
 // Check if the loan is for a stack variable and if that variable
 // is the one being destructed.
 if (LoanPath.D == LifetimeEndsVD)

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] dereference_operator (PR #170006)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

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

>From a3842ac95cb27c2303ab5ebbe40e80c4a55f5fc5 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sat, 29 Nov 2025 15:49:00 +
Subject: [PATCH] dereference_operator

---
 .../LifetimeSafety/FactsGenerator.cpp |  4 
 .../Sema/warn-lifetime-safety-dataflow.cpp|  3 +++
 clang/test/Sema/warn-lifetime-safety.cpp  | 22 +--
 3 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index f8f213c2b2db8..96a1d69ad611d 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -217,6 +217,10 @@ void FactsGenerator::VisitUnaryOperator(const 
UnaryOperator *UO) {
 // origin of this UnaryOperator expression.
 killAndFlowOrigin(*UO, *SubExpr);
   }
+  if (UO->getOpcode() == UO_Deref) {
+const Expr *SubExpr = UO->getSubExpr();
+killAndFlowOrigin(*UO, *SubExpr);
+  }
 }
 
 void FactsGenerator::VisitReturnStmt(const ReturnStmt *RS) {
diff --git a/clang/test/Sema/warn-lifetime-safety-dataflow.cpp 
b/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
index 6d5711deba1cf..d1b3d17fcdd24 100644
--- a/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
@@ -152,6 +152,9 @@ void pointer_indirection() {
 // CHECK-NEXT:   Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
 // CHECK-NEXT:   Src:  [[O_PP_INNER]] (Decl: pp, Type : int *)
 // CHECK:   OriginFlow:
+// CHECK-NEXT:   Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
+// CHECK-NEXT:   Src:  {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
+// CHECK:   OriginFlow:
 // CHECK-NEXT:   Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
 // CHECK-NEXT:   Src:  {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
 // CHECK:   OriginFlow:
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index e62c3b69b040b..f22c73cfeb784 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -596,10 +596,10 @@ const int* return_pointer_to_parameter_via_reference(int 
a, int b, bool cond) {
 const int* d = &c;
 return d; // expected-note 2 {{returned here}}
 }
-// FIXME: Dereference of a pointer does not track the reference.
+
 const int& return_pointer_to_parameter_via_reference_1(int a) {
-const int* d = &a;
-return *d;
+const int* d = &a; // expected-warning {{address of stack memory is 
returned later}}
+return *d;// expected-note {{returned here}}
 }
 
 const int& get_ref_to_local() {
@@ -1118,24 +1118,24 @@ struct MyObjStorage {
   const MyObj *end() const { return objs + 1; }
 };
 
-// FIXME: Detect use-after-scope. Dereference pointer does not propagate the 
origins.
 void range_based_for_use_after_scope() {
   View v;
   {
 MyObjStorage s;
-for (const MyObj &o : s) {
+for (const MyObj &o : s) { // expected-warning {{object whose reference is 
captured does not live long enough}}
   v = o;
 }
-  }
-  v.use();
+  } // expected-note {{destroyed here}}
+  v.use(); // expected-note {{later used here}}
 }
-// FIXME: Detect use-after-return. Dereference pointer does not propagate the 
origins.
+
 View range_based_for_use_after_return() {
   MyObjStorage s;
-  for (const MyObj &o : s) {
-return o;
+  for (const MyObj &o : s) { // expected-warning {{address of stack memory is 
returned later}}
+return o;  // expected-note {{returned here}}
   }
-  return *s.begin();
+  return *s.begin();  // expected-warning {{address of stack memory is 
returned later}}
+  // expected-note@-1 {{returned here}}
 }
 
 void range_based_for_not_reference() {

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/170328

>From 49b0899068bb9ad83cda0de4fdcbed480a4d1fb3 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 24 Nov 2025 18:15:49 -0500
Subject: [PATCH 1/2] GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.
---
 .../llvm/CodeGen/GlobalISel/Legalizer.h   |  11 +-
 .../llvm/CodeGen/GlobalISel/LegalizerHelper.h |  73 +
 llvm/lib/CodeGen/GlobalISel/Legalizer.cpp |  24 +--
 .../CodeGen/GlobalISel/LegalizerHelper.cpp| 149 +-
 llvm/lib/Target/ARM/ARMLegalizerInfo.cpp  |  18 +--
 .../CodeGen/GlobalISel/GISelMITest.h  |   4 +
 .../GlobalISel/LegalizerHelperTest.cpp|  63 
 .../CodeGen/GlobalISel/LegalizerTest.cpp  |   6 +-
 8 files changed, 183 insertions(+), 165 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h 
b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
+class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult
-  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
-  ArrayRef AuxObservers,
-  LostDebugLocObserver &LocObserver,
-  MachineIRBuilder &MIRBuilder, GISelValueTracking 
*VT);
+  static MFResult legalizeMachineFunction(
+  MachineFunction &MF, const LegalizerInfo &LI,
+  ArrayRef AuxObservers,
+  LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+  const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h 
b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-  GISelValueTracking *VT;
+
+  // FIXME: Should probably make Libcalls mandatory
+  const LibcallLoweringInfo *Libcalls = nullptr;
+  GISelValueTracking *VT = nullptr;
 
 public:
   enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
+  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-   MachineIRBuilder &B);
+   MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer, MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr,
GISelValueTracking *VT = nullptr);
 
   /// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
   /// def by inserting a G_BITCAST from \p CastTy
   LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
 
+  // Useful for libcalls where all operands have the same type.
+  LLVM_ABI LegalizeResult
+  simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
+Type *OpType, LostDebugLocObserver &LocObserver) const;
+
+  LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
+Type *FromType,
+LostDebugLocObserver &LocObserver,
+bool IsSigned = false) const;
+
+  /// Helper function that creates a libcall to the given \p Name using the
+  /// given calling convention \p CC.
+  LLVM_ABI Le

[llvm-branch-commits] [clang] Implicit lifetimebound for std namespace (PR #170005)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

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

>From f19ea1b365d2881bb6e1b4cda13e13beaa44fa1d Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sat, 29 Nov 2025 15:07:40 +
Subject: [PATCH] Implicit lifetimebound for std namespace

---
 .../LifetimeSafety/LifetimeAnnotations.h  |  4 +
 .../LifetimeSafety/FactsGenerator.cpp |  3 +-
 .../LifetimeSafety/LifetimeAnnotations.cpp| 82 +++
 clang/lib/Sema/CheckExprLifetime.cpp  | 64 +--
 4 files changed, 90 insertions(+), 63 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h
index 1a16fb82f9a84..65ff03d48094d 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h
@@ -38,6 +38,10 @@ bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl 
*CMD);
 /// method or because it's a normal assignment operator.
 bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD);
 
+bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee);
+
+bool shouldTrackFirstArgument(const FunctionDecl *FD);
+
 // Tells whether the type is annotated with [[gsl::Pointer]].
 bool isGslPointerType(QualType QT);
 // Tells whether the type is annotated with [[gsl::Owner]].
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index af613255a43be..f8f213c2b2db8 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -387,7 +387,8 @@ void FactsGenerator::handleFunctionCall(const Expr *Call,
 Method && Method->isInstance()) {
   if (I == 0)
 // For the 'this' argument, the attribute is on the method itself.
-return implicitObjectParamIsLifetimeBound(Method);
+return implicitObjectParamIsLifetimeBound(Method) ||
+   shouldTrackImplicitObjectArg(Method);
   if ((I - 1) < Method->getNumParams())
 // For explicit arguments, find the corresponding parameter
 // declaration.
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp 
b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
index 54e343fc2ee5e..860aa5373a32c 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
@@ -71,6 +71,88 @@ bool implicitObjectParamIsLifetimeBound(const FunctionDecl 
*FD) {
   return isNormalAssignmentOperator(FD);
 }
 
+// Decl::isInStdNamespace will return false for iterators in some STL
+// implementations due to them being defined in a namespace outside of the std
+// namespace.
+static bool isInStlNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  if (!DC)
+return false;
+  if (const auto *ND = dyn_cast(DC))
+if (const IdentifierInfo *II = ND->getIdentifier()) {
+  StringRef Name = II->getName();
+  if (Name.size() >= 2 && Name.front() == '_' &&
+  (Name[1] == '_' || isUppercase(Name[1])))
+return true;
+}
+
+  return DC->isStdNamespace();
+}
+
+static bool isPointerLikeType(QualType QT) {
+  return isGslPointerType(QT) || QT->isPointerType() || QT->isNullPtrType();
+}
+
+bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
+  if (auto *Conv = dyn_cast_or_null(Callee))
+if (isGslPointerType(Conv->getConversionType()) &&
+Callee->getParent()->hasAttr())
+  return true;
+  if (!isInStlNamespace(Callee->getParent()))
+return false;
+  if (!isGslPointerType(Callee->getFunctionObjectParameterType()) &&
+  !isGslOwnerType(Callee->getFunctionObjectParameterType()))
+return false;
+  if (isPointerLikeType(Callee->getReturnType())) {
+if (!Callee->getIdentifier())
+  return false;
+return llvm::StringSwitch(Callee->getName())
+.Cases({"begin", "rbegin", "cbegin", "crbegin"}, true)
+.Cases({"end", "rend", "cend", "crend"}, true)
+.Cases({"c_str", "data", "get"}, true)
+// Map and set types.
+.Cases({"find", "equal_range", "lower_bound", "upper_bound"}, true)
+.Default(false);
+  }
+  if (Callee->getReturnType()->isReferenceType()) {
+if (!Callee->getIdentifier()) {
+  auto OO = Callee->getOverloadedOperator();
+  if (!Callee->getParent()->hasAttr())
+return false;
+  return OO == OverloadedOperatorKind::OO_Subscript ||
+ OO == OverloadedOperatorKind::OO_Star;
+}
+return llvm::StringSwitch(Callee->getName())
+.Cases({"front", "back", "at", "top", "value"}, true)
+.Default(false);
+  }
+  return false;
+}
+
+bool shouldTrackFirstArgument(const FunctionDecl *FD) {
+  if (!FD->getIdentifier() || FD->getNumParams() != 1)
+return false;
+  const auto *RD = FD->get

[llvm-branch-commits] [clang] Implicit lifetimebound for std namespace (PR #170005)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

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

>From f19ea1b365d2881bb6e1b4cda13e13beaa44fa1d Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sat, 29 Nov 2025 15:07:40 +
Subject: [PATCH] Implicit lifetimebound for std namespace

---
 .../LifetimeSafety/LifetimeAnnotations.h  |  4 +
 .../LifetimeSafety/FactsGenerator.cpp |  3 +-
 .../LifetimeSafety/LifetimeAnnotations.cpp| 82 +++
 clang/lib/Sema/CheckExprLifetime.cpp  | 64 +--
 4 files changed, 90 insertions(+), 63 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h
index 1a16fb82f9a84..65ff03d48094d 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h
@@ -38,6 +38,10 @@ bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl 
*CMD);
 /// method or because it's a normal assignment operator.
 bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD);
 
+bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee);
+
+bool shouldTrackFirstArgument(const FunctionDecl *FD);
+
 // Tells whether the type is annotated with [[gsl::Pointer]].
 bool isGslPointerType(QualType QT);
 // Tells whether the type is annotated with [[gsl::Owner]].
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index af613255a43be..f8f213c2b2db8 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -387,7 +387,8 @@ void FactsGenerator::handleFunctionCall(const Expr *Call,
 Method && Method->isInstance()) {
   if (I == 0)
 // For the 'this' argument, the attribute is on the method itself.
-return implicitObjectParamIsLifetimeBound(Method);
+return implicitObjectParamIsLifetimeBound(Method) ||
+   shouldTrackImplicitObjectArg(Method);
   if ((I - 1) < Method->getNumParams())
 // For explicit arguments, find the corresponding parameter
 // declaration.
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp 
b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
index 54e343fc2ee5e..860aa5373a32c 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
@@ -71,6 +71,88 @@ bool implicitObjectParamIsLifetimeBound(const FunctionDecl 
*FD) {
   return isNormalAssignmentOperator(FD);
 }
 
+// Decl::isInStdNamespace will return false for iterators in some STL
+// implementations due to them being defined in a namespace outside of the std
+// namespace.
+static bool isInStlNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  if (!DC)
+return false;
+  if (const auto *ND = dyn_cast(DC))
+if (const IdentifierInfo *II = ND->getIdentifier()) {
+  StringRef Name = II->getName();
+  if (Name.size() >= 2 && Name.front() == '_' &&
+  (Name[1] == '_' || isUppercase(Name[1])))
+return true;
+}
+
+  return DC->isStdNamespace();
+}
+
+static bool isPointerLikeType(QualType QT) {
+  return isGslPointerType(QT) || QT->isPointerType() || QT->isNullPtrType();
+}
+
+bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
+  if (auto *Conv = dyn_cast_or_null(Callee))
+if (isGslPointerType(Conv->getConversionType()) &&
+Callee->getParent()->hasAttr())
+  return true;
+  if (!isInStlNamespace(Callee->getParent()))
+return false;
+  if (!isGslPointerType(Callee->getFunctionObjectParameterType()) &&
+  !isGslOwnerType(Callee->getFunctionObjectParameterType()))
+return false;
+  if (isPointerLikeType(Callee->getReturnType())) {
+if (!Callee->getIdentifier())
+  return false;
+return llvm::StringSwitch(Callee->getName())
+.Cases({"begin", "rbegin", "cbegin", "crbegin"}, true)
+.Cases({"end", "rend", "cend", "crend"}, true)
+.Cases({"c_str", "data", "get"}, true)
+// Map and set types.
+.Cases({"find", "equal_range", "lower_bound", "upper_bound"}, true)
+.Default(false);
+  }
+  if (Callee->getReturnType()->isReferenceType()) {
+if (!Callee->getIdentifier()) {
+  auto OO = Callee->getOverloadedOperator();
+  if (!Callee->getParent()->hasAttr())
+return false;
+  return OO == OverloadedOperatorKind::OO_Subscript ||
+ OO == OverloadedOperatorKind::OO_Star;
+}
+return llvm::StringSwitch(Callee->getName())
+.Cases({"front", "back", "at", "top", "value"}, true)
+.Default(false);
+  }
+  return false;
+}
+
+bool shouldTrackFirstArgument(const FunctionDecl *FD) {
+  if (!FD->getIdentifier() || FD->getNumParams() != 1)
+return false;
+  const auto *RD = FD->get

[llvm-branch-commits] [clang] std_move false positive (PR #170007)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

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

>From 00be6fa3eaa4f7f68b34438d5b2295f0b0ad8f59 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sat, 29 Nov 2025 16:43:06 +
Subject: [PATCH] std_move false positive

---
 .../Analyses/LifetimeSafety/FactsGenerator.h   |  2 ++
 .../lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 14 ++
 2 files changed, 16 insertions(+)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index 5b5626020e772..2c7a9bbbc9e2f 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -101,6 +101,8 @@ class FactsGenerator : public 
ConstStmtVisitor {
   // corresponding to the left-hand side is updated to be a "write", thereby
   // exempting it from the check.
   llvm::DenseMap UseFacts;
+
+  llvm::DenseSet MovedDecls;
 };
 
 } // namespace clang::lifetimes::internal
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 96a1d69ad611d..8fb9cd04b2a42 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -162,9 +162,21 @@ void FactsGenerator::VisitCXXMemberCallExpr(const 
CXXMemberCallExpr *MCE) {
   }
 }
 
+static bool isStdMove(const FunctionDecl *FD) {
+  return FD && FD->isInStdNamespace() && FD->getIdentifier() &&
+ FD->getName() == "move";
+}
+
 void FactsGenerator::VisitCallExpr(const CallExpr *CE) {
   handleFunctionCall(CE, CE->getDirectCallee(),
  {CE->getArgs(), CE->getNumArgs()});
+  // Remember accessPath which moved using std::move.
+  // TODO: If there is need, this could flow-sensitive
+  if (isStdMove(CE->getDirectCallee()))
+if (CE->getNumArgs() == 1)
+  if (auto *DRE =
+  dyn_cast(CE->getArg(0)->IgnoreParenImpCasts()))
+MovedDecls.insert(DRE->getDecl());
 }
 
 void FactsGenerator::VisitCXXNullPtrLiteralExpr(
@@ -340,6 +352,8 @@ void FactsGenerator::handleLifetimeEnds(const 
CFGLifetimeEnds &LifetimeEnds) {
   // Iterate through all loans to see if any expire.
   for (const auto &Loan : FactMgr.getLoanMgr().getLoans()) {
 const AccessPath &LoanPath = Loan.Path;
+if (MovedDecls.contains(LoanPath.D))
+  continue;
 // Check if the loan is for a stack variable and if that variable
 // is the one being destructed.
 if (LoanPath.D == LifetimeEndsVD)

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/2] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/2] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/3] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/3] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/3] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/4] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/4] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/4] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 10: Expansion Limit) (PR #169689)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169689

>From 8e22321c5540419bde23f07f64164cf6685d0f64 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:41:45 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 10)

---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Basic/LangOptions.def |  1 +
 clang/include/clang/Options/Options.td|  4 ++
 clang/lib/Driver/ToolChains/Clang.cpp |  1 +
 clang/lib/Sema/SemaExpand.cpp | 18 +
 .../SemaCXX/cxx2c-expansion-stmts-limit.cpp   | 68 +++
 .../SemaCXX/cxx2c-fexpansion-statements.cpp   |  9 +++
 7 files changed, 105 insertions(+)
 create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-limit.cpp
 create mode 100644 clang/test/SemaCXX/cxx2c-fexpansion-statements.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bf6d017e845fc..7b0e9be0484b9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -167,6 +167,10 @@ def note_constexpr_assert_failed : Note<
   "assertion failed during evaluation of constant expression">;
 def err_expansion_size_expr_not_ice : Error<
   "expansion size is not a constant expression">;
+def err_expansion_too_big : Error<
+  "expansion size %0 exceeds maximum configured size %1">;
+def note_use_fexpansion_limit : Note<
+  "use -fexpansion-limit=N to adjust this limit">;
 
 // Semantic analysis of constant literals.
 def ext_predef_outside_function : Warning<
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 40fc66ea12e34..315cb4dc5e1cf 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -377,6 +377,7 @@ LANGOPT(ConstexprCallDepth, 32, 512, Benign,
 "maximum constexpr call depth")
 LANGOPT(ConstexprStepLimit, 32, 1048576, Benign,
 "maximum constexpr evaluation steps")
+LANGOPT(MaxTemplateForExpansions, 32, 256, Benign, "maximum template for 
expansions")
 LANGOPT(EnableNewConstInterp, 1, 0, Benign,
 "enable the experimental new constant interpreter")
 LANGOPT(BracketDepth, 32, 256, Benign,
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 0e88656c5e1bc..86867b4814eeb 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -2054,6 +2054,10 @@ def fconstexpr_steps_EQ : Joined<["-"], 
"fconstexpr-steps=">, Group,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Set the maximum number of steps in constexpr function evaluation 
(0 = no limit)">,
   MarshallingInfoInt, "1048576">;
+def fexpansion_limit_EQ : Joined<["-"], "fexpansion-limit=">, Group,
+  Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Set the maximum number of times a single expansion statement may 
be expanded (0 = no limit)">,
+  MarshallingInfoInt, "256">;
 def fexperimental_new_constant_interpreter : Flag<["-"], 
"fexperimental-new-constant-interpreter">, Group,
   HelpText<"Enable the experimental new constant interpreter">,
   Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c5d40c9825fab..649d4c3e4ca97 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6358,6 +6358,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   Args.AddLastArg(CmdArgs, options::OPT_foperator_arrow_depth_EQ);
   Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_depth_EQ);
   Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_steps_EQ);
+  Args.AddLastArg(CmdArgs, options::OPT_fexpansion_limit_EQ);
 
   Args.AddLastArg(CmdArgs, options::OPT_fexperimental_library);
 
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 532797c68b534..cb284cf08a03b 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -44,6 +44,18 @@ struct IterableExpansionStmtData {
 };
 } // namespace
 
+static bool CheckExpansionSize(Sema &S, uint64_t NumInstantiations,
+   SourceLocation Loc) {
+  unsigned Max = S.LangOpts.MaxTemplateForExpansions;
+  if (Max != 0 && NumInstantiations > Max) {
+S.Diag(Loc, diag::err_expansion_too_big) << NumInstantiations << Max;
+S.Diag(Loc, diag::note_use_fexpansion_limit);
+return true;
+  }
+
+  return false;
+}
+
 // Build a 'DeclRefExpr' designating the template parameter '__N'.
 static DeclRefExpr *BuildIndexDRE(Sema &S, CXXExpansionStmtDecl *ESD) {
   return S.BuildDeclRefExpr(ESD->getIndexTemplateParm(),
@@ -216,6 +228,9 @@ static StmtResult BuildDestructuringCXXExpansionStmt(
 return StmtError();
   }
 
+  if (CheckExpansionSize(S, *Arity, ColonLoc))
+return StmtError();
+
   QualType AutoRRef = S.Context.getAutoRRefDeductType();

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169688

>From 0a945e66ca01c3a5f9d8914cfb6c7f0459a866b3 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +
 clang/include/clang/Sema/ScopeInfo.h  |   6 +-
 clang/include/clang/Sema/Sema.h   |   3 +-
 clang/lib/Parse/ParseStmt.cpp |  11 +-
 clang/lib/Sema/SemaLookup.cpp |  47 +--
 clang/lib/Sema/SemaStmt.cpp   |  30 -
 .../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
 7 files changed, 205 insertions(+), 15 deletions(-)
 create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d91e1526ae47f..bf6d017e845fc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3708,6 +3708,12 @@ def err_expansion_stmt_incomplete : Error<
   "cannot expand expression of incomplete type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+  "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion 
statement">;
+def note_enclosing_switch_statement_here : Note<
+  "switch statement is here">;
+def err_expansion_stmt_label : Error<
+  "labels are not allowed in expansion statements">;
 
 def err_attribute_patchable_function_entry_invalid_section
 : Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h 
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
 public:
   /// A SwitchStmt, along with a flag indicating if its list of case statements
   /// is incomplete (because we dropped an invalid one while parsing).
-  using SwitchInfo = llvm::PointerIntPair;
+  struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+  };
 
   /// SwitchStack - This is the current set of active switch statements in the
   /// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 268c81351e744..c90ddf91a663b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9530,7 +9530,8 @@ class Sema final : public SemaBase {
   /// of an __label__ label name, otherwise it is a normal label definition
   /// or use.
   LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc = 
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
 
   /// Perform a name lookup for a label with the specified name; this does not
   /// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes 
&Attrs,
   // identifier ':' statement
   SourceLocation ColonLoc = ConsumeToken();
 
-  LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
-  IdentTok.getLocation());
+  LabelDecl *LD = Actions.LookupOrCreateLabel(
+  IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+  /*ForLabelStmt=*/true);
 
   // Read label attributes, if present.
   StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes 
&Attrs,
 
   DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
 
+  // If a label cannot appear here, just return the underlying statement.
+  if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+  }
+
   Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
   Attrs.clear();
 
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II, 
SourceLocation Loc) {
 }
 
 LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
   if (GnuLabelLoc.isValid()) {
 /

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 13fb7c82109cb09d60cbc7f49fd6b85171f51b9e Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3c3589e0ae22a..d91e1526ae47f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3700,6 +3700,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6685f891be77b..268c81351e744 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15714,6 +15714,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index c4bc38bf1e465..532797c68b534 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -191,6 +191,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -339,8 +385,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, E

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 11: Final Touches and Tests) (PR #169690)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169690

>From f78d11e73a37f28b9d28bbff8836dd662028c1b2 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 18:03:57 +0100
Subject: [PATCH 1/2] [Clang] [C++26] Expansion Statements (Part 11)

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticCommonKinds.td  |   4 -
 clang/test/AST/ast-dump-expansion-stmt.cpp|  49 +
 clang/test/AST/ast-print-expansion-stmts.cpp  | 104 ++
 clang/www/cxx_status.html |   2 +-
 5 files changed, 156 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-expansion-stmt.cpp
 create mode 100644 clang/test/AST/ast-print-expansion-stmts.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 51f07256c5d9f..14f31c0ee5a2b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -187,6 +187,8 @@ C++2c Feature Support
   At this timem, references to constexpr and decomposition of *tuple-like* 
types are not supported
   (only arrays and aggregates are).
 
+- Implemented `P1306R5 `_ Expansion Statements.
+
 C++23 Feature Support
 ^
 
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 0b9225980e826..6e50e225a8cc1 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -22,10 +22,6 @@ def select_constexpr_spec_kind : TextSubstitution<
 def fatal_too_many_errors
   : Error<"too many errors emitted, stopping now">, DefaultFatal;
 
-// TODO: Remove this.
-def err_expansion_statements_todo : Error<
-  "TODO (expansion statements)">;
-
 def warn_stack_exhausted : Warning<
   "stack nearly exhausted; compilation time may suffer, and "
   "crashes due to stack overflow are likely">,
diff --git a/clang/test/AST/ast-dump-expansion-stmt.cpp 
b/clang/test/AST/ast-dump-expansion-stmt.cpp
new file mode 100644
index 0..146157e2c13e6
--- /dev/null
+++ b/clang/test/AST/ast-dump-expansion-stmt.cpp
@@ -0,0 +1,49 @@
+// Test without serialization:
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-unknown-unknown -ast-dump %s
+//
+// Test with serialization:
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -triple x86_64-unknown-unknown 
-include-pch %t -ast-dump-all /dev/null \
+// RUN: | sed -e "s/ //" -e "s/ imported//"
+
+template 
+struct Array {
+  T data[size]{};
+  constexpr const T* begin() const { return data; }
+  constexpr const T* end() const { return data + size; }
+};
+
+void foo(int);
+
+template 
+void test(T t) {
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXEnumeratingExpansionStmtPattern
+  // CHECK:CXXExpansionStmtInstantiation
+  template for (auto x : {1, 2, 3}) {
+foo(x);
+  }
+
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXIteratingExpansionStmtPattern
+  // CHECK:CXXExpansionStmtInstantiation
+  static constexpr Array a;
+  template for (auto x : a) {
+foo(x);
+  }
+
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXDestructuringExpansionStmtPattern
+  // CHECK:CXXExpansionStmtInstantiation
+  int arr[3]{1, 2, 3};
+  template for (auto x : arr) {
+foo(x);
+  }
+
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXDependentExpansionStmtPattern
+  // CHECK-NOT:CXXExpansionStmtInstantiation
+  template for (auto x : t) {
+foo(x);
+  }
+}
diff --git a/clang/test/AST/ast-print-expansion-stmts.cpp 
b/clang/test/AST/ast-print-expansion-stmts.cpp
new file mode 100644
index 0..bb9f79c6644c0
--- /dev/null
+++ b/clang/test/AST/ast-print-expansion-stmts.cpp
@@ -0,0 +1,104 @@
+// Without serialization:
+// RUN: %clang_cc1 -std=c++26 -ast-print %s | FileCheck %s
+//
+// With serialization:
+// RUN: %clang_cc1 -std=c++26 -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -include-pch %t -ast-print  /dev/null | 
FileCheck %s
+
+template 
+struct Array {
+  T data[size]{};
+  constexpr const T* begin() const { return data; }
+  constexpr const T* end() const { return data + size; }
+};
+
+// CHECK: void foo(int);
+void foo(int);
+
+// CHECK: template  void test(T t) {
+template 
+void test(T t) {
+  // Enumerating expansion statement.
+  //
+  // CHECK:  template for (auto x : { 1, 2, 3 }) {
+  // CHECK-NEXT: foo(x);
+  // CHECK-NEXT: }
+  template for (auto x : {1, 2, 3}) {
+foo(x);
+  }
+
+  // Iterating expansion statement.
+  //
+  // CHECK:  static constexpr Array a;
+  // CHECK-NEXT: template for (auto x : a) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  static constexpr Array a;
+  template for (auto x : a) {
+foo(x);
+  }
+
+  // Destructuring expansion statement.
+  //
+  // CHECK:  int arr[3]{1, 2, 3};
+  // CHECK-NEXT: template for (auto x : arr

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169688

>From 0a945e66ca01c3a5f9d8914cfb6c7f0459a866b3 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +
 clang/include/clang/Sema/ScopeInfo.h  |   6 +-
 clang/include/clang/Sema/Sema.h   |   3 +-
 clang/lib/Parse/ParseStmt.cpp |  11 +-
 clang/lib/Sema/SemaLookup.cpp |  47 +--
 clang/lib/Sema/SemaStmt.cpp   |  30 -
 .../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
 7 files changed, 205 insertions(+), 15 deletions(-)
 create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d91e1526ae47f..bf6d017e845fc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3708,6 +3708,12 @@ def err_expansion_stmt_incomplete : Error<
   "cannot expand expression of incomplete type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+  "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion 
statement">;
+def note_enclosing_switch_statement_here : Note<
+  "switch statement is here">;
+def err_expansion_stmt_label : Error<
+  "labels are not allowed in expansion statements">;
 
 def err_attribute_patchable_function_entry_invalid_section
 : Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h 
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
 public:
   /// A SwitchStmt, along with a flag indicating if its list of case statements
   /// is incomplete (because we dropped an invalid one while parsing).
-  using SwitchInfo = llvm::PointerIntPair;
+  struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+  };
 
   /// SwitchStack - This is the current set of active switch statements in the
   /// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 268c81351e744..c90ddf91a663b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9530,7 +9530,8 @@ class Sema final : public SemaBase {
   /// of an __label__ label name, otherwise it is a normal label definition
   /// or use.
   LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc = 
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
 
   /// Perform a name lookup for a label with the specified name; this does not
   /// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes 
&Attrs,
   // identifier ':' statement
   SourceLocation ColonLoc = ConsumeToken();
 
-  LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
-  IdentTok.getLocation());
+  LabelDecl *LD = Actions.LookupOrCreateLabel(
+  IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+  /*ForLabelStmt=*/true);
 
   // Read label attributes, if present.
   StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes 
&Attrs,
 
   DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
 
+  // If a label cannot appear here, just return the underlying statement.
+  if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+  }
+
   Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
   Attrs.clear();
 
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II, 
SourceLocation Loc) {
 }
 
 LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
   if (GnuLabelLoc.isValid()) {
 /

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 7: Constexpr support and tests) (PR #169686)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169686

>From c16e3888704a883b13e19aa1f9e84fe2c4471429 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:09:56 +0100
Subject: [PATCH 1/5] [Clang] [C++26] Expansion Statements (Part 7)

---
 clang/lib/AST/ExprConstant.cpp   |   40 +
 clang/lib/Sema/SemaDeclCXX.cpp   |3 +
 clang/test/SemaCXX/cxx2c-expansion-stmts.cpp | 1042 ++
 3 files changed, 1085 insertions(+)
 create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts.cpp

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d93f87a27e68d..2de1641f6b46a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6037,6 +6037,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, 
EvalInfo &Info,
   const VarDecl *VD = dyn_cast_or_null(D);
   if (VD && !CheckLocalVariableDeclaration(Info, VD))
 return ESR_Failed;
+
+  if (const auto *ESD = dyn_cast(D)) {
+assert(ESD->getInstantiations() && "not expanded?");
+return EvaluateStmt(Result, Info, ESD->getInstantiations(), Case);
+  }
+
   // Each declaration initialization is its own full-expression.
   FullExpressionRAII Scope(Info);
   if (!EvaluateDecl(Info, D, /*EvaluateConditionDecl=*/true) &&
@@ -6309,6 +6315,40 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, 
EvalInfo &Info,
 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
   }
 
+  case Stmt::CXXExpansionStmtInstantiationClass: {
+BlockScopeRAII Scope(Info);
+const auto *Expansion = cast(S);
+for (const Stmt *Shared : Expansion->getSharedStmts()) {
+  EvalStmtResult ESR = EvaluateStmt(Result, Info, Shared);
+  if (ESR != ESR_Succeeded) {
+if (ESR != ESR_Failed && !Scope.destroy())
+  return ESR_Failed;
+return ESR;
+  }
+}
+
+// No need to push an extra scope for these since they're already
+// CompoundStmts.
+EvalStmtResult ESR = ESR_Succeeded;
+for (const Stmt *Instantiation : Expansion->getInstantiations()) {
+  ESR = EvaluateStmt(Result, Info, Instantiation);
+  if (ESR == ESR_Failed ||
+  ShouldPropagateBreakContinue(Info, Expansion, &Scope, ESR))
+return ESR;
+  if (ESR != ESR_Continue) {
+// Succeeded here actually means we encountered a 'break'.
+assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
+break;
+  }
+}
+
+// Map Continue back to Succeeded if we fell off the end of the loop.
+if (ESR == ESR_Continue)
+  ESR = ESR_Succeeded;
+
+return Scope.destroy() ? ESR : ESR_Failed;
+  }
+
   case Stmt::SwitchStmtClass:
 return EvaluateSwitch(Result, Info, cast(S));
 
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8030aac3d8771..e398710ace63b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2027,6 +2027,9 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
   //   - using-enum-declaration
   continue;
 
+case Decl::CXXExpansionStmt:
+  continue;
+
 case Decl::Typedef:
 case Decl::TypeAlias: {
   //   - typedef declarations and alias-declarations that do not define
diff --git a/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp 
b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
new file mode 100644
index 0..71ce71c4f69fe
--- /dev/null
+++ b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
@@ -0,0 +1,1042 @@
+// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -fdeclspec -fblocks -verify
+namespace std {
+template 
+struct initializer_list {
+  const T* a;
+  const T* b;
+  initializer_list(T* a, T* b): a{a}, b{b} {}
+};
+}
+
+struct S {
+  int x;
+  constexpr S(int x) : x{x} {}
+};
+
+void g(int); // #g
+template  constexpr int tg() { return n; }
+
+void f1() {
+  template for (auto x : {}) static_assert(false, "discarded");
+  template for (constexpr auto x : {}) static_assert(false, "discarded");
+  template for (auto x : {1}) g(x);
+  template for (auto x : {1, 2, 3}) g(x);
+  template for (constexpr auto x : {1}) g(x);
+  template for (constexpr auto x : {1, 2, 3}) g(x);
+  template for (constexpr auto x : {1}) tg();
+  template for (constexpr auto x : {1, 2, 3})
+static_assert(tg());
+
+  template for (int x : {1, 2, 3}) g(x);
+  template for (S x : {1, 2, 3}) g(x.x);
+  template for (constexpr S x : {1, 2, 3}) tg();
+
+  template for (int x : {"1", S(1), {1, 2}}) { // expected-error {{cannot 
initialize a variable of type 'int' with an lvalue of type 'const char[2]'}} \
+  expected-error {{no viable 
conversion from 'S' to 'int'}} \
+  expected-error {{excess 
elements in scalar initializer}} \
+  expected-note 3 {{in 
instantiation of expansion statement requested

[llvm-branch-commits] [clang] [Clang] [NFC] Expansion Statements (Part 4: for-range refactor) (PR #169683)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169683

>From d0c4da5350c179af92776fc8f4035bfb889c89d0 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 16:11:59 +0100
Subject: [PATCH 1/4] [Clang] [C++26] Expansion Statements (Part 4)

---
 clang/include/clang/Sema/Sema.h |  34 +++
 clang/lib/Sema/SemaStmt.cpp | 503 ++--
 2 files changed, 313 insertions(+), 224 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4d25143cffaf4..1101ee9e10778 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11066,6 +11066,37 @@ class Sema final : public SemaBase {
   BuildForRangeKind Kind,
   ArrayRef LifetimeExtendTemps = {});
 
+  /// Set the type of a for-range declaration whose for-range or expansion
+  /// initialiser is dependent.
+  void ActOnDependentForRangeInitializer(VarDecl *LoopVar,
+ BuildForRangeKind BFRK);
+
+  /// Holds the 'begin' and 'end' variables of a range-based for loop or
+  /// expansion statement; begin-expr and end-expr are also provided; the
+  /// latter are used in some diagnostics.
+  struct ForRangeBeginEndInfo {
+VarDecl *BeginVar = nullptr;
+VarDecl *EndVar = nullptr;
+Expr *BeginExpr = nullptr;
+Expr *EndExpr = nullptr;
+bool isValid() const { return BeginVar != nullptr && EndVar != nullptr; }
+  };
+
+  /// Determine begin-expr and end-expr and build variable declarations for
+  /// them as per [stmt.ranged].
+  ForRangeBeginEndInfo BuildCXXForRangeBeginEndVars(
+  Scope *S, VarDecl *RangeVar, SourceLocation ColonLoc,
+  SourceLocation CoawaitLoc,
+  ArrayRef LifetimeExtendTemps,
+  BuildForRangeKind Kind, bool ForExpansionStmt,
+  StmtResult *RebuildResult = nullptr,
+  llvm::function_ref RebuildWithDereference = {});
+
+  /// Build the range variable of a range-based for loop or iterating
+  /// expansion statement and return its DeclStmt.
+  StmtResult BuildCXXForRangeRangeVar(Scope *S, Expr *Range,
+  bool ForExpansionStmt);
+
   /// FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
   /// This is a separate step from ActOnCXXForRangeStmt because analysis of the
   /// body cannot be performed until after the type of the range variable is
@@ -11207,6 +11238,9 @@ class Sema final : public SemaBase {
SourceLocation Loc,
unsigned NumParams);
 
+  void ApplyForRangeOrExpansionStatementLifetimeExtension(
+  VarDecl *RangeVar, ArrayRef Temporaries);
+
 private:
   /// Check whether the given statement can have musttail applied to it,
   /// issuing a diagnostic and returning false if not.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 655fa31bbf5c7..47c8f9ab6725c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2409,8 +2409,13 @@ void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,
 }
 
 /// Build a variable declaration for a for-range statement.
-VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,
-  QualType Type, StringRef Name) {
+VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
+  StringRef Name, bool ForExpansionStmt) {
+  // Making the variable constexpr doesn't automatically add 'const' to the
+  // type, so do that now.
+  if (ForExpansionStmt && !Type->isReferenceType())
+Type = Type.withConst();
+
   DeclContext *DC = SemaRef.CurContext;
   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
@@ -2418,9 +2423,11 @@ VarDecl *BuildForRangeVarDecl(Sema &SemaRef, 
SourceLocation Loc,
   TInfo, SC_None);
   Decl->setImplicit();
   Decl->setCXXForRangeImplicitVar(true);
+  if (ForExpansionStmt)
+// CWG 3044: Do not make the variable 'static'.
+Decl->setConstexpr(true);
   return Decl;
 }
-
 }
 
 static bool ObjCEnumerationCollection(Expr *Collection) {
@@ -2428,6 +2435,25 @@ static bool ObjCEnumerationCollection(Expr *Collection) {
   && Collection->getType()->getAs() != nullptr;
 }
 
+StmtResult Sema::BuildCXXForRangeRangeVar(Scope *S, Expr *Range,
+  bool ForExpansionStmt) {
+  // Divide by 2, since the variables are in the inner scope (loop body).
+  const auto DepthStr = std::to_string(S->getDepth() / 2);
+  SourceLocation RangeLoc = Range->getBeginLoc();
+  VarDecl *RangeVar =
+  BuildForRangeVarDecl(*this, RangeLoc, Context.getAutoRRefDeductType(),
+   std::string("__range") + DepthStr, 
ForExpansionStmt);
+  if (FinishForRangeVarDecl(*this, RangeVar, Range, RangeLoc,
+diag::err_for_r

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 7: Constexpr support and tests) (PR #169686)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169686

>From c16e3888704a883b13e19aa1f9e84fe2c4471429 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:09:56 +0100
Subject: [PATCH 1/5] [Clang] [C++26] Expansion Statements (Part 7)

---
 clang/lib/AST/ExprConstant.cpp   |   40 +
 clang/lib/Sema/SemaDeclCXX.cpp   |3 +
 clang/test/SemaCXX/cxx2c-expansion-stmts.cpp | 1042 ++
 3 files changed, 1085 insertions(+)
 create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts.cpp

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d93f87a27e68d..2de1641f6b46a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6037,6 +6037,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, 
EvalInfo &Info,
   const VarDecl *VD = dyn_cast_or_null(D);
   if (VD && !CheckLocalVariableDeclaration(Info, VD))
 return ESR_Failed;
+
+  if (const auto *ESD = dyn_cast(D)) {
+assert(ESD->getInstantiations() && "not expanded?");
+return EvaluateStmt(Result, Info, ESD->getInstantiations(), Case);
+  }
+
   // Each declaration initialization is its own full-expression.
   FullExpressionRAII Scope(Info);
   if (!EvaluateDecl(Info, D, /*EvaluateConditionDecl=*/true) &&
@@ -6309,6 +6315,40 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, 
EvalInfo &Info,
 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
   }
 
+  case Stmt::CXXExpansionStmtInstantiationClass: {
+BlockScopeRAII Scope(Info);
+const auto *Expansion = cast(S);
+for (const Stmt *Shared : Expansion->getSharedStmts()) {
+  EvalStmtResult ESR = EvaluateStmt(Result, Info, Shared);
+  if (ESR != ESR_Succeeded) {
+if (ESR != ESR_Failed && !Scope.destroy())
+  return ESR_Failed;
+return ESR;
+  }
+}
+
+// No need to push an extra scope for these since they're already
+// CompoundStmts.
+EvalStmtResult ESR = ESR_Succeeded;
+for (const Stmt *Instantiation : Expansion->getInstantiations()) {
+  ESR = EvaluateStmt(Result, Info, Instantiation);
+  if (ESR == ESR_Failed ||
+  ShouldPropagateBreakContinue(Info, Expansion, &Scope, ESR))
+return ESR;
+  if (ESR != ESR_Continue) {
+// Succeeded here actually means we encountered a 'break'.
+assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
+break;
+  }
+}
+
+// Map Continue back to Succeeded if we fell off the end of the loop.
+if (ESR == ESR_Continue)
+  ESR = ESR_Succeeded;
+
+return Scope.destroy() ? ESR : ESR_Failed;
+  }
+
   case Stmt::SwitchStmtClass:
 return EvaluateSwitch(Result, Info, cast(S));
 
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8030aac3d8771..e398710ace63b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2027,6 +2027,9 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
   //   - using-enum-declaration
   continue;
 
+case Decl::CXXExpansionStmt:
+  continue;
+
 case Decl::Typedef:
 case Decl::TypeAlias: {
   //   - typedef declarations and alias-declarations that do not define
diff --git a/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp 
b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
new file mode 100644
index 0..71ce71c4f69fe
--- /dev/null
+++ b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
@@ -0,0 +1,1042 @@
+// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -fdeclspec -fblocks -verify
+namespace std {
+template 
+struct initializer_list {
+  const T* a;
+  const T* b;
+  initializer_list(T* a, T* b): a{a}, b{b} {}
+};
+}
+
+struct S {
+  int x;
+  constexpr S(int x) : x{x} {}
+};
+
+void g(int); // #g
+template  constexpr int tg() { return n; }
+
+void f1() {
+  template for (auto x : {}) static_assert(false, "discarded");
+  template for (constexpr auto x : {}) static_assert(false, "discarded");
+  template for (auto x : {1}) g(x);
+  template for (auto x : {1, 2, 3}) g(x);
+  template for (constexpr auto x : {1}) g(x);
+  template for (constexpr auto x : {1, 2, 3}) g(x);
+  template for (constexpr auto x : {1}) tg();
+  template for (constexpr auto x : {1, 2, 3})
+static_assert(tg());
+
+  template for (int x : {1, 2, 3}) g(x);
+  template for (S x : {1, 2, 3}) g(x.x);
+  template for (constexpr S x : {1, 2, 3}) tg();
+
+  template for (int x : {"1", S(1), {1, 2}}) { // expected-error {{cannot 
initialize a variable of type 'int' with an lvalue of type 'const char[2]'}} \
+  expected-error {{no viable 
conversion from 'S' to 'int'}} \
+  expected-error {{excess 
elements in scalar initializer}} \
+  expected-note 3 {{in 
instantiation of expansion statement requested

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 01/13] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 02/13] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 03/13] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 5: Iterating Expansion Statements) (PR #169684)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169684

>From b2c2312092fa345789c207634a50c143058ac7f0 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 16:18:02 +0100
Subject: [PATCH 1/7] [Clang] [C++26] Expansion Statements (Part 5)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/Sema/Sema.h   |   6 +
 clang/lib/Sema/SemaExpand.cpp | 246 +-
 clang/lib/Sema/SemaStmt.cpp   |  13 +-
 clang/lib/Sema/TreeTransform.h|  50 +++-
 5 files changed, 316 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d4783c1c9677d..96292d0a4e306 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -165,6 +165,10 @@ def err_ice_too_large : Error<
 def err_expr_not_string_literal : Error<"expression is not a string literal">;
 def note_constexpr_assert_failed : Note<
   "assertion failed during evaluation of constant expression">;
+def err_expansion_size_expr_not_ice : Error<
+  "expansion size is not a constant expression">;
+def err_expansion_size_negative : Error<
+  "expansion size must not be negative (was %0)">;
 
 // Semantic analysis of constant literals.
 def ext_predef_outside_function : Warning<
@@ -3698,6 +3702,9 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_lambda : Error<
+  "cannot expand lambda closure type">;
+
 def err_attribute_patchable_function_entry_invalid_section
 : Error<"section argument to 'patchable_function_entry' attribute is not "
 "valid for this target: %0">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fc98f9326da17..6685f891be77b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15704,6 +15704,12 @@ class Sema final : public SemaBase {
  SourceLocation ColonLoc,
  SourceLocation RParenLoc);
 
+  StmtResult BuildNonEnumeratingCXXExpansionStmtPattern(
+  CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVarStmt,
+  Expr *ExpansionInitializer, SourceLocation LParenLoc,
+  SourceLocation ColonLoc, SourceLocation RParenLoc,
+  ArrayRef LifetimeExtendTemps = {});
+
   ExprResult
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index f1cd2baa9ae39..8e46a45304aa7 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -24,6 +24,25 @@
 using namespace clang;
 using namespace sema;
 
+namespace {
+struct IterableExpansionStmtData {
+  enum class State {
+NotIterable,
+Error,
+Ok,
+  };
+
+  DeclStmt *RangeDecl = nullptr;
+  DeclStmt *BeginDecl = nullptr;
+  DeclStmt *EndDecl = nullptr;
+  Expr *Initializer = nullptr;
+  State TheState = State::NotIterable;
+
+  bool isIterable() const { return TheState == State::Ok; }
+  bool hasError() { return TheState == State::Error; }
+};
+} // namespace
+
 // Build a 'DeclRefExpr' designating the template parameter '__N'.
 static DeclRefExpr *BuildIndexDRE(Sema &S, CXXExpansionStmtDecl *ESD) {
   return S.BuildDeclRefExpr(ESD->getIndexTemplateParm(),
@@ -42,6 +61,118 @@ static bool FinaliseExpansionVar(Sema &S, VarDecl 
*ExpansionVar,
   return ExpansionVar->isInvalidDecl();
 }
 
+static IterableExpansionStmtData
+TryBuildIterableExpansionStmtInitializer(Sema &S, Expr *ExpansionInitializer,
+ Expr *Index, SourceLocation ColonLoc,
+ bool VarIsConstexpr) {
+  IterableExpansionStmtData Data;
+
+  // C++26 [stmt.expand]p3: An expression is expansion-iterable if it does not
+  // have array type [...]
+  QualType Ty = ExpansionInitializer->getType().getNonReferenceType();
+  if (Ty->isArrayType())
+return Data;
+
+  // Lookup member and ADL 'begin()'/'end()'. Only check if they exist; even if
+  // they're deleted, inaccessible, etc., this is still an iterating expansion
+  // statement, albeit an ill-formed one.
+  DeclarationNameInfo BeginName(&S.PP.getIdentifierTable().get("begin"),
+ColonLoc);
+  DeclarationNameInfo EndName(&S.PP.getIdentifierTable().get("end"), ColonLoc);
+
+  // Try member lookup first.
+  bool FoundBeginEnd = false;
+  if (auto *Record = Ty->getAsCXXRecordDecl()) {
+LookupResult BeginLR(S, BeginName, Sema::LookupMemberName);
+LookupResult EndLR(S, EndName, Sema::LookupMemberName);
+FoundBeginEnd = S.LookupQualifiedName(BeginLR, Record) &&
+S.LookupQualifiedName

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 5: Iterating Expansion Statements) (PR #169684)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169684

>From b2c2312092fa345789c207634a50c143058ac7f0 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 16:18:02 +0100
Subject: [PATCH 1/7] [Clang] [C++26] Expansion Statements (Part 5)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/Sema/Sema.h   |   6 +
 clang/lib/Sema/SemaExpand.cpp | 246 +-
 clang/lib/Sema/SemaStmt.cpp   |  13 +-
 clang/lib/Sema/TreeTransform.h|  50 +++-
 5 files changed, 316 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d4783c1c9677d..96292d0a4e306 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -165,6 +165,10 @@ def err_ice_too_large : Error<
 def err_expr_not_string_literal : Error<"expression is not a string literal">;
 def note_constexpr_assert_failed : Note<
   "assertion failed during evaluation of constant expression">;
+def err_expansion_size_expr_not_ice : Error<
+  "expansion size is not a constant expression">;
+def err_expansion_size_negative : Error<
+  "expansion size must not be negative (was %0)">;
 
 // Semantic analysis of constant literals.
 def ext_predef_outside_function : Warning<
@@ -3698,6 +3702,9 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_lambda : Error<
+  "cannot expand lambda closure type">;
+
 def err_attribute_patchable_function_entry_invalid_section
 : Error<"section argument to 'patchable_function_entry' attribute is not "
 "valid for this target: %0">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fc98f9326da17..6685f891be77b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15704,6 +15704,12 @@ class Sema final : public SemaBase {
  SourceLocation ColonLoc,
  SourceLocation RParenLoc);
 
+  StmtResult BuildNonEnumeratingCXXExpansionStmtPattern(
+  CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVarStmt,
+  Expr *ExpansionInitializer, SourceLocation LParenLoc,
+  SourceLocation ColonLoc, SourceLocation RParenLoc,
+  ArrayRef LifetimeExtendTemps = {});
+
   ExprResult
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index f1cd2baa9ae39..8e46a45304aa7 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -24,6 +24,25 @@
 using namespace clang;
 using namespace sema;
 
+namespace {
+struct IterableExpansionStmtData {
+  enum class State {
+NotIterable,
+Error,
+Ok,
+  };
+
+  DeclStmt *RangeDecl = nullptr;
+  DeclStmt *BeginDecl = nullptr;
+  DeclStmt *EndDecl = nullptr;
+  Expr *Initializer = nullptr;
+  State TheState = State::NotIterable;
+
+  bool isIterable() const { return TheState == State::Ok; }
+  bool hasError() { return TheState == State::Error; }
+};
+} // namespace
+
 // Build a 'DeclRefExpr' designating the template parameter '__N'.
 static DeclRefExpr *BuildIndexDRE(Sema &S, CXXExpansionStmtDecl *ESD) {
   return S.BuildDeclRefExpr(ESD->getIndexTemplateParm(),
@@ -42,6 +61,118 @@ static bool FinaliseExpansionVar(Sema &S, VarDecl 
*ExpansionVar,
   return ExpansionVar->isInvalidDecl();
 }
 
+static IterableExpansionStmtData
+TryBuildIterableExpansionStmtInitializer(Sema &S, Expr *ExpansionInitializer,
+ Expr *Index, SourceLocation ColonLoc,
+ bool VarIsConstexpr) {
+  IterableExpansionStmtData Data;
+
+  // C++26 [stmt.expand]p3: An expression is expansion-iterable if it does not
+  // have array type [...]
+  QualType Ty = ExpansionInitializer->getType().getNonReferenceType();
+  if (Ty->isArrayType())
+return Data;
+
+  // Lookup member and ADL 'begin()'/'end()'. Only check if they exist; even if
+  // they're deleted, inaccessible, etc., this is still an iterating expansion
+  // statement, albeit an ill-formed one.
+  DeclarationNameInfo BeginName(&S.PP.getIdentifierTable().get("begin"),
+ColonLoc);
+  DeclarationNameInfo EndName(&S.PP.getIdentifierTable().get("end"), ColonLoc);
+
+  // Try member lookup first.
+  bool FoundBeginEnd = false;
+  if (auto *Record = Ty->getAsCXXRecordDecl()) {
+LookupResult BeginLR(S, BeginName, Sema::LookupMemberName);
+LookupResult EndLR(S, EndName, Sema::LookupMemberName);
+FoundBeginEnd = S.LookupQualifiedName(BeginLR, Record) &&
+S.LookupQualifiedName

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 10: Expansion Limit) (PR #169689)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169689

>From 8e22321c5540419bde23f07f64164cf6685d0f64 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:41:45 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 10)

---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Basic/LangOptions.def |  1 +
 clang/include/clang/Options/Options.td|  4 ++
 clang/lib/Driver/ToolChains/Clang.cpp |  1 +
 clang/lib/Sema/SemaExpand.cpp | 18 +
 .../SemaCXX/cxx2c-expansion-stmts-limit.cpp   | 68 +++
 .../SemaCXX/cxx2c-fexpansion-statements.cpp   |  9 +++
 7 files changed, 105 insertions(+)
 create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-limit.cpp
 create mode 100644 clang/test/SemaCXX/cxx2c-fexpansion-statements.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bf6d017e845fc..7b0e9be0484b9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -167,6 +167,10 @@ def note_constexpr_assert_failed : Note<
   "assertion failed during evaluation of constant expression">;
 def err_expansion_size_expr_not_ice : Error<
   "expansion size is not a constant expression">;
+def err_expansion_too_big : Error<
+  "expansion size %0 exceeds maximum configured size %1">;
+def note_use_fexpansion_limit : Note<
+  "use -fexpansion-limit=N to adjust this limit">;
 
 // Semantic analysis of constant literals.
 def ext_predef_outside_function : Warning<
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 40fc66ea12e34..315cb4dc5e1cf 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -377,6 +377,7 @@ LANGOPT(ConstexprCallDepth, 32, 512, Benign,
 "maximum constexpr call depth")
 LANGOPT(ConstexprStepLimit, 32, 1048576, Benign,
 "maximum constexpr evaluation steps")
+LANGOPT(MaxTemplateForExpansions, 32, 256, Benign, "maximum template for 
expansions")
 LANGOPT(EnableNewConstInterp, 1, 0, Benign,
 "enable the experimental new constant interpreter")
 LANGOPT(BracketDepth, 32, 256, Benign,
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 0e88656c5e1bc..86867b4814eeb 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -2054,6 +2054,10 @@ def fconstexpr_steps_EQ : Joined<["-"], 
"fconstexpr-steps=">, Group,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Set the maximum number of steps in constexpr function evaluation 
(0 = no limit)">,
   MarshallingInfoInt, "1048576">;
+def fexpansion_limit_EQ : Joined<["-"], "fexpansion-limit=">, Group,
+  Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Set the maximum number of times a single expansion statement may 
be expanded (0 = no limit)">,
+  MarshallingInfoInt, "256">;
 def fexperimental_new_constant_interpreter : Flag<["-"], 
"fexperimental-new-constant-interpreter">, Group,
   HelpText<"Enable the experimental new constant interpreter">,
   Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c5d40c9825fab..649d4c3e4ca97 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6358,6 +6358,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   Args.AddLastArg(CmdArgs, options::OPT_foperator_arrow_depth_EQ);
   Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_depth_EQ);
   Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_steps_EQ);
+  Args.AddLastArg(CmdArgs, options::OPT_fexpansion_limit_EQ);
 
   Args.AddLastArg(CmdArgs, options::OPT_fexperimental_library);
 
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 532797c68b534..cb284cf08a03b 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -44,6 +44,18 @@ struct IterableExpansionStmtData {
 };
 } // namespace
 
+static bool CheckExpansionSize(Sema &S, uint64_t NumInstantiations,
+   SourceLocation Loc) {
+  unsigned Max = S.LangOpts.MaxTemplateForExpansions;
+  if (Max != 0 && NumInstantiations > Max) {
+S.Diag(Loc, diag::err_expansion_too_big) << NumInstantiations << Max;
+S.Diag(Loc, diag::note_use_fexpansion_limit);
+return true;
+  }
+
+  return false;
+}
+
 // Build a 'DeclRefExpr' designating the template parameter '__N'.
 static DeclRefExpr *BuildIndexDRE(Sema &S, CXXExpansionStmtDecl *ESD) {
   return S.BuildDeclRefExpr(ESD->getIndexTemplateParm(),
@@ -216,6 +228,9 @@ static StmtResult BuildDestructuringCXXExpansionStmt(
 return StmtError();
   }
 
+  if (CheckExpansionSize(S, *Arity, ColonLoc))
+return StmtError();
+
   QualType AutoRRef = S.Context.getAutoRRefDeductType();

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 11: Final Touches and Tests) (PR #169690)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169690

>From f78d11e73a37f28b9d28bbff8836dd662028c1b2 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 18:03:57 +0100
Subject: [PATCH 1/2] [Clang] [C++26] Expansion Statements (Part 11)

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticCommonKinds.td  |   4 -
 clang/test/AST/ast-dump-expansion-stmt.cpp|  49 +
 clang/test/AST/ast-print-expansion-stmts.cpp  | 104 ++
 clang/www/cxx_status.html |   2 +-
 5 files changed, 156 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-expansion-stmt.cpp
 create mode 100644 clang/test/AST/ast-print-expansion-stmts.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 51f07256c5d9f..14f31c0ee5a2b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -187,6 +187,8 @@ C++2c Feature Support
   At this timem, references to constexpr and decomposition of *tuple-like* 
types are not supported
   (only arrays and aggregates are).
 
+- Implemented `P1306R5 `_ Expansion Statements.
+
 C++23 Feature Support
 ^
 
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 0b9225980e826..6e50e225a8cc1 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -22,10 +22,6 @@ def select_constexpr_spec_kind : TextSubstitution<
 def fatal_too_many_errors
   : Error<"too many errors emitted, stopping now">, DefaultFatal;
 
-// TODO: Remove this.
-def err_expansion_statements_todo : Error<
-  "TODO (expansion statements)">;
-
 def warn_stack_exhausted : Warning<
   "stack nearly exhausted; compilation time may suffer, and "
   "crashes due to stack overflow are likely">,
diff --git a/clang/test/AST/ast-dump-expansion-stmt.cpp 
b/clang/test/AST/ast-dump-expansion-stmt.cpp
new file mode 100644
index 0..146157e2c13e6
--- /dev/null
+++ b/clang/test/AST/ast-dump-expansion-stmt.cpp
@@ -0,0 +1,49 @@
+// Test without serialization:
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-unknown-unknown -ast-dump %s
+//
+// Test with serialization:
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -triple x86_64-unknown-unknown 
-include-pch %t -ast-dump-all /dev/null \
+// RUN: | sed -e "s/ //" -e "s/ imported//"
+
+template 
+struct Array {
+  T data[size]{};
+  constexpr const T* begin() const { return data; }
+  constexpr const T* end() const { return data + size; }
+};
+
+void foo(int);
+
+template 
+void test(T t) {
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXEnumeratingExpansionStmtPattern
+  // CHECK:CXXExpansionStmtInstantiation
+  template for (auto x : {1, 2, 3}) {
+foo(x);
+  }
+
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXIteratingExpansionStmtPattern
+  // CHECK:CXXExpansionStmtInstantiation
+  static constexpr Array a;
+  template for (auto x : a) {
+foo(x);
+  }
+
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXDestructuringExpansionStmtPattern
+  // CHECK:CXXExpansionStmtInstantiation
+  int arr[3]{1, 2, 3};
+  template for (auto x : arr) {
+foo(x);
+  }
+
+  // CHECK:  CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXDependentExpansionStmtPattern
+  // CHECK-NOT:CXXExpansionStmtInstantiation
+  template for (auto x : t) {
+foo(x);
+  }
+}
diff --git a/clang/test/AST/ast-print-expansion-stmts.cpp 
b/clang/test/AST/ast-print-expansion-stmts.cpp
new file mode 100644
index 0..bb9f79c6644c0
--- /dev/null
+++ b/clang/test/AST/ast-print-expansion-stmts.cpp
@@ -0,0 +1,104 @@
+// Without serialization:
+// RUN: %clang_cc1 -std=c++26 -ast-print %s | FileCheck %s
+//
+// With serialization:
+// RUN: %clang_cc1 -std=c++26 -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -include-pch %t -ast-print  /dev/null | 
FileCheck %s
+
+template 
+struct Array {
+  T data[size]{};
+  constexpr const T* begin() const { return data; }
+  constexpr const T* end() const { return data + size; }
+};
+
+// CHECK: void foo(int);
+void foo(int);
+
+// CHECK: template  void test(T t) {
+template 
+void test(T t) {
+  // Enumerating expansion statement.
+  //
+  // CHECK:  template for (auto x : { 1, 2, 3 }) {
+  // CHECK-NEXT: foo(x);
+  // CHECK-NEXT: }
+  template for (auto x : {1, 2, 3}) {
+foo(x);
+  }
+
+  // Iterating expansion statement.
+  //
+  // CHECK:  static constexpr Array a;
+  // CHECK-NEXT: template for (auto x : a) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  static constexpr Array a;
+  template for (auto x : a) {
+foo(x);
+  }
+
+  // Destructuring expansion statement.
+  //
+  // CHECK:  int arr[3]{1, 2, 3};
+  // CHECK-NEXT: template for (auto x : arr

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 13fb7c82109cb09d60cbc7f49fd6b85171f51b9e Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3c3589e0ae22a..d91e1526ae47f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3700,6 +3700,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6685f891be77b..268c81351e744 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15714,6 +15714,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index c4bc38bf1e465..532797c68b534 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -191,6 +191,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -339,8 +385,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, E

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 01/14] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 02/14] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 03/14] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 01/15] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 02/15] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 03/15] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/5] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/5] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/5] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/6] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/6] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/6] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/7] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/7] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/7] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/8] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/8] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/8] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 01/10] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 02/10] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 03/10] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (

[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 1/9] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 2/9] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 3/9] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (pr_num

[llvm-branch-commits] [llvm] DAG: Avoid more uses of getLibcallName (PR #170402)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/170402

None

>From 77249d0059b431c93dcb35424696f31b87ff635f Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Tue, 2 Dec 2025 20:41:15 -0500
Subject: [PATCH] DAG: Avoid more uses of getLibcallName

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp| 2 +-
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp 
b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 70950084ee6b7..0e52f0516b09a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4983,7 +4983,7 @@ static bool isDivRemLibcallAvailable(SDNode *Node, bool 
isSigned,
   case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; 
break;
   }
 
-  return TLI.getLibcallName(LC) != nullptr;
+  return TLI.getLibcallImpl(LC) != RTLIB::Unsupported;
 }
 
 /// Issue divrem if both quotient and remainder are needed.
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp 
b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 3564cbebed5c2..0ba8816bf1e82 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11121,7 +11121,8 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG 
&DAG, const SDLoc &dl,
   else if (WideVT == MVT::i128)
 LC = RTLIB::MUL_I128;
 
-  if (LC == RTLIB::UNKNOWN_LIBCALL || !getLibcallName(LC)) {
+  RTLIB::LibcallImpl LibcallImpl = getLibcallImpl(LC);
+  if (LibcallImpl == RTLIB::Unsupported) {
 forceExpandMultiply(DAG, dl, Signed, Lo, Hi, LHS, RHS);
 return;
   }

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid more uses of getLibcallName (PR #170402)

2025-12-02 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.com/github/pr/llvm/llvm-project/170402?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#170402** https://app.graphite.com/github/pr/llvm/llvm-project/170402?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/170402?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#170400** https://app.graphite.com/github/pr/llvm/llvm-project/170400?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/170402
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid more uses of getLibcallName (PR #170402)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/170402
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 01/11] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 02/11] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 03/11] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (

[llvm-branch-commits] [llvm] DAG: Avoid more uses of getLibcallName (PR #170402)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-selectiondag

Author: Matt Arsenault (arsenm)


Changes



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


2 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+2-1) 


``diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp 
b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 70950084ee6b7..0e52f0516b09a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4983,7 +4983,7 @@ static bool isDivRemLibcallAvailable(SDNode *Node, bool 
isSigned,
   case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; 
break;
   }
 
-  return TLI.getLibcallName(LC) != nullptr;
+  return TLI.getLibcallImpl(LC) != RTLIB::Unsupported;
 }
 
 /// Issue divrem if both quotient and remainder are needed.
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp 
b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 3564cbebed5c2..0ba8816bf1e82 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11121,7 +11121,8 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG 
&DAG, const SDLoc &dl,
   else if (WideVT == MVT::i128)
 LC = RTLIB::MUL_I128;
 
-  if (LC == RTLIB::UNKNOWN_LIBCALL || !getLibcallName(LC)) {
+  RTLIB::LibcallImpl LibcallImpl = getLibcallImpl(LC);
+  if (LibcallImpl == RTLIB::Unsupported) {
 forceExpandMultiply(DAG, dl, Signed, Lo, Hi, LHS, RHS);
 return;
   }

``




https://github.com/llvm/llvm-project/pull/170402
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 updated 
https://github.com/llvm/llvm-project/pull/170216

>From f4dc493d9245a9739ab0e45a81ee7fef48c41801 Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:01:04 +
Subject: [PATCH 01/12] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index fa3fbe8176a16..122b5028448f2 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -81,7 +81,7 @@ runs:
 
   core.setOutput("urls", " ".join(artifact_urls));
   core.setOutput("ids", " ".join(artifact_ids));
-  core.setOutput("names", " ".join(artifact_names)")
+  core.setOutput("names", " ".join(artifact_names));
 
 - shell: bash
   if: steps.artifact-url.outputs.urls != ''

>From f6e0b79f1f176559a7d1bd7828a8665fe11c044d Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:02:31 +
Subject: [PATCH 02/12] fix

Created using spr 1.3.7
---
 .github/workflows/unprivileged-download-artifact/action.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/unprivileged-download-artifact/action.yml 
b/.github/workflows/unprivileged-download-artifact/action.yml
index 122b5028448f2..cefa1ff58fcd9 100644
--- a/.github/workflows/unprivileged-download-artifact/action.yml
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -49,7 +49,7 @@ runs:
 
   artifacts_to_download = []
   for (artifact of response.data.artifacts) {
-if (artifact.name.startswith(${{ inputs.artifact-name }})) {
+if (artifact.name.startswith("${{ inputs.artifact-name }}")) {
   artifacts_to_download.push(artifact)
 }
   }

>From bcc35cc917ef5b92731e63588cb2b4254f79068a Mon Sep 17 00:00:00 2001
From: Aiden Grossman 
Date: Wed, 3 Dec 2025 02:10:54 +
Subject: [PATCH 03/12] test

Created using spr 1.3.7
---
 .github/workflows/issue-write.js  | 106 ++
 .../unprivileged-download-artifact/action.yml |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 .github/workflows/issue-write.js

diff --git a/.github/workflows/issue-write.js b/.github/workflows/issue-write.js
new file mode 100644
index 0..4f0acd3ff4f50
--- /dev/null
+++ b/.github/workflows/issue-write.js
@@ -0,0 +1,106 @@
+var fs = require('fs');
+const comments = JSON.parse(fs.readFileSync('./comments'));
+if (!comments || comments.length == 0) {
+  return;
+}
+
+let runInfo = await github.rest.actions.getWorkflowRun({
+  owner: context.repo.owner,
+  repo: context.repo.repo,
+  run_id: context.payload.workflow_run.id
+});
+
+console.log(runInfo);
+
+
+// Query to find the number of the pull request that triggered this job.
+// The associated pull requests are based off of the branch name, so if
+// you create a pull request for a branch, close it, and then create
+// another pull request with the same branch, then this query will return
+// two associated pull requests.  This is why we have to fetch all the
+// associated pull requests and then iterate through them to find the
+// one that is open.
+const gql_query = `
+  query($repo_owner : String!, $repo_name : String!, $branch: String!) {
+repository(owner: $repo_owner, name: $repo_name) {
+  ref (qualifiedName: $branch) {
+associatedPullRequests(first: 100) {
+  nodes {
+baseRepository {
+  owner {
+login
+  }
+}
+number
+state
+  }
+}
+  }
+}
+  }
+`
+const gql_variables = {
+  repo_owner: runInfo.data.head_repository.owner.login,
+  repo_name: runInfo.data.head_repository.name,
+  branch: runInfo.data.head_branch
+}
+const gql_result = await github.graphql(gql_query, gql_variables);
+console.log(gql_result);
+// If the branch for the PR was deleted before this job has a chance
+// to run, then the ref will be null.  This can happen if someone:
+// 1. Rebase the PR, which triggers some workflow.
+// 2. Immediately merges the PR and deletes the branch.
+// 3. The workflow finishes and triggers this job.
+if (!gql_result.repository.ref) {
+  console.log("Ref has been deleted");
+  return;
+}
+console.log(gql_result.repository.ref.associatedPullRequests.nodes);
+
+var pr_number = 0;
+gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {
+
+  // The largest PR number is the one we care about.  The only way
+  // to have more than one associated pull requests is if all the
+  // old pull requests are in the closed state.
+  if (pr.baseRepository.owner.login = context.repo.owner && pr.number > 
pr_number) {
+pr_number = pr.number;
+  }
+});
+if (

[llvm-branch-commits] [clang] [Clang] [NFC] Expansion Statements (Part 4: for-range and `ParseScope` refactor) (PR #169683)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide edited 
https://github.com/llvm/llvm-project/pull/169683
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Github] Make unprivileged-download-artifact download multiple artifacts (PR #170216)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 ready_for_review 
https://github.com/llvm/llvm-project/pull/170216
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [NFC] Expansion Statements (Part 4: for-range refactor) (PR #169683)

2025-12-02 Thread via llvm-branch-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff origin/main HEAD --extensions h,cpp -- 
clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Scope.h 
clang/include/clang/Sema/Sema.h clang/lib/Interpreter/IncrementalParser.cpp 
clang/lib/Parse/ParseCXXInlineMethods.cpp clang/lib/Parse/ParseDecl.cpp 
clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp 
clang/lib/Parse/ParseExprCXX.cpp clang/lib/Parse/ParseHLSL.cpp 
clang/lib/Parse/ParseObjc.cpp clang/lib/Parse/ParseOpenACC.cpp 
clang/lib/Parse/ParseOpenMP.cpp clang/lib/Parse/ParsePragma.cpp 
clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/ParseTemplate.cpp 
clang/lib/Parse/Parser.cpp clang/lib/Sema/Scope.cpp clang/lib/Sema/Sema.cpp 
clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaStmt.cpp 
--diff_from_common_commit
``

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index ecf1cba8c..e997dd300 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4826,7 +4826,7 @@ void Parser::ParseStructUnionBody(SourceLocation 
RecordLoc,
   if (T.consumeOpen())
 return;
 
-  ParseScope StructScope(Actions, Scope::ClassScope|Scope::DeclScope);
+  ParseScope StructScope(Actions, Scope::ClassScope | Scope::DeclScope);
   Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
 
   // `LateAttrParseExperimentalExtOnly=true` requests that only attributes
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 79938b5db..cc712489e 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -12,8 +12,8 @@
 
//===--===//
 
 #include "clang/Sema/Scope.h"
-#include "clang/Sema/Sema.h"
 #include "clang/AST/Decl.h"
+#include "clang/Sema/Sema.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index efd33fd39..153bf071e 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2987,7 +2987,7 @@ void Sema::ExitScope() {
 
 void Sema::FreeScopes() {
   // Take care not to delete 'CurScope' twice.
-  auto IsCurScope = [&](auto& S) { return S.get() == CurScope; };
+  auto IsCurScope = [&](auto &S) { return S.get() == CurScope; };
   if (llvm::find_if(ScopeCache, IsCurScope) == ScopeCache.end())
 delete CurScope;
 
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index da1005f8a..f5b388868 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2738,12 +2738,10 @@ Sema::ForRangeBeginEndInfo 
Sema::BuildCXXForRangeBeginEndVars(
   // Build auto __begin = begin-expr, __end = end-expr.
   // Divide by 2, since the variables are in the inner scope (loop body).
   const auto DepthStr = std::to_string(S->getDepth() / 2);
-  VarDecl *BeginVar =
-  BuildForRangeVarDecl(*this, ColonLoc, AutoType,
-   std::string("__begin") + DepthStr, Constexpr);
-  VarDecl *EndVar =
-  BuildForRangeVarDecl(*this, ColonLoc, AutoType,
-   std::string("__end") + DepthStr, Constexpr);
+  VarDecl *BeginVar = BuildForRangeVarDecl(
+  *this, ColonLoc, AutoType, std::string("__begin") + DepthStr, Constexpr);
+  VarDecl *EndVar = BuildForRangeVarDecl(
+  *this, ColonLoc, AutoType, std::string("__end") + DepthStr, Constexpr);
 
   // Build begin-expr and end-expr and attach to __begin and __end variables.
   ExprResult BeginExpr, EndExpr;

``




https://github.com/llvm/llvm-project/pull/169683
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 5: Iterating Expansion Statements) (PR #169684)

2025-12-02 Thread via llvm-branch-commits

Sirraide wrote:

> Update, I think I have figured out the lambda situation at this point (as in 
> building the lambda and evaluating it works for simple examples); now I just 
> need to test it thoroughly.

Ok, just pushed that too and I’ve also implemented support for [CWG 
3131](https://github.com/cplusplus/CWG/issues/805), though note that the 
wording of that issue is likely still subject to change—at least considering 
the ongoing discussion on the issue. In particular, the comment Barry made wrt 
the fact that `begin` and `iter` should be `constexpr` only if the 
for-range-declaration makes sense to me and I’ve implemented that here.

https://github.com/llvm/llvm-project/pull/169684
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [NFC] Expansion Statements (Part 4: for-range and `ParseScope` refactor) (PR #169683)

2025-12-02 Thread via llvm-branch-commits

Sirraide wrote:

Update: Iterating expansion statements require building a lambda in Sema (see 
part 5 in this patch series), which necessitated moving `ParseScope` and 
friends from the Parser into Sema; I’ve included this refactor in this NFC 
patch.

As an aside, it makes more sense for `ParseScope` etc. to be in Sema anyway 
since its implementation exclusively calls Sema functions—technically, it does 
call _some_ parser functions, but _those functions_ then in turn only call Sema 
functions and don’t actually access any parser state. The only reference to 
parser state is that the current token location is passed to Sema... but Sema 
doesn’t do anything w/ it, so I just removed that parameter.

https://github.com/llvm/llvm-project/pull/169683
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [NFC] Expansion Statements (Part 4: for-range and `ParseScope` refactor) (PR #169683)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide edited 
https://github.com/llvm/llvm-project/pull/169683
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid more uses of getLibcallName (PR #170402)

2025-12-02 Thread via llvm-branch-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

* 166641 tests passed
* 2901 tests skipped
* 1 test failed

## Failed Tests
(click on a test name to see its output)

### lldb-api

lldb-api.functionalities/scripted_frame_provider/circular_dependency/TestFrameProviderCircularDependency.py

```
Script:
--
/usr/bin/python3 
/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py
 -u CXXFLAGS -u CFLAGS --env 
LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib
 --env 
LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include
 --env 
LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin
 --libcxx-include-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 
--libcxx-include-target-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1
 --libcxx-library-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu
 --arch x86_64 --build-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex
 --lldb-module-cache-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api
 --clang-module-cache-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api
 --executable 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb 
--compiler 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang 
--dsymutil 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil 
--make /usr/bin/gmake --llvm-tools-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin 
--lldb-obj-root 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb 
--lldb-libs-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib 
--cmake-build-type Release 
/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/circular_dependency
 -p TestFrameProviderCircularDependency.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 
e491e1fb70812ebed9a0f948178ea79a937263f8)
  clang revision e491e1fb70812ebed9a0f948178ea79a937263f8
  llvm revision e491e1fb70812ebed9a0f948178ea79a937263f8
Skipping the following test categories: msvcstl, dsym, pdb, gmodules, 
debugserver, objc

--
Command Output (stderr):
--
Traceback (most recent call last):
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py",
 line 8, in 
lldbsuite.test.run_suite()
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py",
 line 1115, in run_suite
visit("Test", dirpath, filenames)
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py",
 line 716, in visit
visit_file(dir, name)
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py",
 line 659, in visit_file
module = __import__(base)
 
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/circular_dependency/TestFrameProviderCircularDependency.py",
 line 12, in 
class FrameProviderCircularDependencyTestCase(TestBase):
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/circular_dependency/TestFrameProviderCircularDependency.py",
 line 19, in FrameProviderCircularDependencyTestCase
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
 ^^
NameError: name 'expectedFailureAll' is not defined

--

```


If these failures are unrelated to your changes (for example tests are broken 
or flaky at HEAD), please open an issue at 
https://github.com/llvm/llvm-project/issues and add the `infrastructure` label.

https://github.com/llvm/llvm-project/pull/170402
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 5: Iterating Expansion Statements) (PR #169684)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide edited 
https://github.com/llvm/llvm-project/pull/169684
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [Github] Make issue-write workflow support reading from multiple files (PR #170411)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

boomanaiden154 wrote:

This needs the issue-write changes to enable the workflow to actually enable 
the workflow to run after the test workflow finishes to land before proper 
testing can be done, but the patch is relatively small.

https://github.com/llvm/llvm-project/pull/170411
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [Github] Make issue-write workflow support reading from multiple files (PR #170411)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-github-workflow

Author: Aiden Grossman (boomanaiden154)


Changes

This is so that we can read from multiple files emitted by the premerge
workflow.


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


2 Files Affected:

- (modified) .github/workflows/issue-write-test.yaml (+10-3) 
- (modified) .github/workflows/issue-write.yml (+6-1) 


``diff
diff --git a/.github/workflows/issue-write-test.yaml 
b/.github/workflows/issue-write-test.yaml
index 9497e719e35b1..8fae346038680 100644
--- a/.github/workflows/issue-write-test.yaml
+++ b/.github/workflows/issue-write-test.yaml
@@ -16,10 +16,17 @@ jobs:
 steps:
   - name: Write Comment
 run: |
-  echo '[{"body": "This is a comment for testing the issue write 
workflow"}]' > comments
+  echo '[{"body": "This is a comment for testing the issue write 
workflow"}]' > comments-foo
+  echo '[{"body": "This is another comment for testing the issue write 
workflow that was placed in a separate file"}]' > comments-bar
   - name: Upload Comment
 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 
# v5.0.0
 with:
-  name: workflow-args
+  name: workflow-args-foo
   path: |
-comments
+comments-foo
+  - name: Upload Comment
+uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 
# v5.0.0
+with:
+  name: workflow-args-bar
+  path: |
+comments-bar
diff --git a/.github/workflows/issue-write.yml 
b/.github/workflows/issue-write.yml
index ac75dffd8b3b8..9ceadbe971093 100644
--- a/.github/workflows/issue-write.yml
+++ b/.github/workflows/issue-write.yml
@@ -47,7 +47,12 @@ jobs:
   github-token: ${{ secrets.GITHUB_TOKEN }}
   script: |
 var fs = require('fs');
-const comments = JSON.parse(fs.readFileSync('./comments'));
+var comments = []
+for (local_file of fs.readdirSync('.')) {
+  if (local_file.startsWith("comments")) {
+comments.push(...JSON.parse(fs.readFileSync(local_file)))
+  }
+}
 if (!comments || comments.length == 0) {
   return;
 }

``




https://github.com/llvm/llvm-project/pull/170411
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [Github] Make issue-write workflow support reading from multiple files (PR #170411)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 created 
https://github.com/llvm/llvm-project/pull/170411

This is so that we can read from multiple files emitted by the premerge
workflow.



___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid using getLibcallName when looking for a divrem call (PR #170413)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/170413
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid using getLibcallName when looking for a divrem call (PR #170413)

2025-12-02 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.com/github/pr/llvm/llvm-project/170413?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#170413** https://app.graphite.com/github/pr/llvm/llvm-project/170413?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/170413?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#170402** https://app.graphite.com/github/pr/llvm/llvm-project/170402?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#170400** https://app.graphite.com/github/pr/llvm/llvm-project/170400?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/170413
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid using getLibcallName when looking for a divrem call (PR #170413)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-selectiondag

Author: Matt Arsenault (arsenm)


Changes

Also introduce an error if it's not available, which is not yet
testable.

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


1 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (+13-2) 


``diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 99d14a60c6ed1..8336e1d1f4134 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2381,8 +2381,19 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
   Entry.IsZExt = !isSigned;
   Args.push_back(Entry);
 
-  SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
- 
TLI.getPointerTy(DAG.getDataLayout()));
+  RTLIB::LibcallImpl LibcallImpl = TLI.getLibcallImpl(LC);
+  if (LibcallImpl == RTLIB::Unsupported) {
+DAG.getContext()->emitError(Twine("no libcall available for ") +
+Node->getOperationName(&DAG));
+SDValue Poison = DAG.getPOISON(RetVT);
+Results.push_back(Poison);
+Results.push_back(Poison);
+return;
+  }
+
+  SDValue Callee =
+  DAG.getExternalSymbol(TLI.getLibcallImplName(LibcallImpl).data(),
+TLI.getPointerTy(DAG.getDataLayout()));
 
   SDLoc dl(Node);
   TargetLowering::CallLoweringInfo CLI(DAG);

``




https://github.com/llvm/llvm-project/pull/170413
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid using getLibcallName when looking for a divrem call (PR #170413)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/170413

Also introduce an error if it's not available, which is not yet
testable.

>From b5ef5ed3e65584020a039a2fa8cd98c4d7ce31f9 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Tue, 2 Dec 2025 21:03:00 -0500
Subject: [PATCH] DAG: Avoid using getLibcallName when looking for a divrem
 call

Also introduce an error if it's not available, which is not yet
testable.
---
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 99d14a60c6ed1..8336e1d1f4134 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2381,8 +2381,19 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
   Entry.IsZExt = !isSigned;
   Args.push_back(Entry);
 
-  SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
- 
TLI.getPointerTy(DAG.getDataLayout()));
+  RTLIB::LibcallImpl LibcallImpl = TLI.getLibcallImpl(LC);
+  if (LibcallImpl == RTLIB::Unsupported) {
+DAG.getContext()->emitError(Twine("no libcall available for ") +
+Node->getOperationName(&DAG));
+SDValue Poison = DAG.getPOISON(RetVT);
+Results.push_back(Poison);
+Results.push_back(Poison);
+return;
+  }
+
+  SDValue Callee =
+  DAG.getExternalSymbol(TLI.getLibcallImplName(LibcallImpl).data(),
+TLI.getPointerTy(DAG.getDataLayout()));
 
   SDLoc dl(Node);
   TargetLowering::CallLoweringInfo CLI(DAG);

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 7: Constexpr support and tests) (PR #169686)

2025-12-02 Thread Vlad Serebrennikov via llvm-branch-commits

Endilll wrote:

Can you clarify the status of the following Core issues in your implementation:
[CWG3044](https://cplusplus.github.io/CWG/issues/3044.html) "Iterating 
expansion statements woes"
[CWG3048](https://cplusplus.github.io/CWG/issues/3048.html) "Empty 
destructuring expansion statements"
[CWG3061](https://cplusplus.github.io/CWG/issues/3061.html) "Trailing comma in 
an expansion-init-list"
[CWG3123](https://cplusplus.github.io/CWG/issues/3123.html) "Global lookup for 
begin and end for expansion statements"
[CWG3131](https://cplusplus.github.io/CWG/issues/3131.html) "Value categories 
and types for the range in iterable expansion statements"

I'd also be very grateful if you added tests for those Core issues. Probably 
not right now, as the last two hasn't even been discussed in Core, and we can't 
run `make_cxx_dr_status` script, because we need to revisit our test for 
CWG2917 (#170410).

https://github.com/llvm/llvm-project/pull/169686
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [Github][CI] Make premerge upload results on Linux and Windows (PR #170414)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-infrastructure

Author: Aiden Grossman (boomanaiden154)


Changes

Now that the issue-write workflow can support writing comments from
multiple files, make the premerge workflow write out comments from both
x86_64 Linux and Windows. AArch64 Linux right now is left out as the
premerge advisor does not currently support it.


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


2 Files Affected:

- (modified) .ci/premerge_advisor_explain.py (+2-1) 
- (modified) .github/workflows/premerge.yaml (+10-2) 


``diff
diff --git a/.ci/premerge_advisor_explain.py b/.ci/premerge_advisor_explain.py
index 155e91bef55f8..bd65eb3d1588b 100644
--- a/.ci/premerge_advisor_explain.py
+++ b/.ci/premerge_advisor_explain.py
@@ -129,7 +129,8 @@ def main(
 # If the job succeeds and there is not an existing comment, we
 # should not write one to reduce noise.
 comments = []
-with open("comments", "w") as comment_file_handle:
+comments_file_name = f"comments-{platform.system()}-{platform.machine()}"
+with open(comments_file_name, "w") as comment_file_handle:
 json.dump(comments, comment_file_handle)
 
 
diff --git a/.github/workflows/premerge.yaml b/.github/workflows/premerge.yaml
index 10f7f6a827b30..4ea5397edbeac 100644
--- a/.github/workflows/premerge.yaml
+++ b/.github/workflows/premerge.yaml
@@ -124,9 +124,9 @@ jobs:
 if: ${{ always() && !startsWith(matrix.runs-on, 
'depot-ubuntu-24.04-arm') }}
 continue-on-error: true
 with:
-  name: workflow-args
+  name: workflow-args-x86-linux
   path: |
-comments
+comments-Linux-x86_64
 
   premerge-checks-windows:
 name: Build and Test Windows
@@ -185,6 +185,14 @@ jobs:
   path: artifacts/
   retention-days: 5
   include-hidden-files: 'true'
+  - name: Upload Comment
+uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 
# v5.0.0
+if: always()
+continue-on-error: true
+with:
+  name: workflow-args-windows
+  path: |
+comments-Windows-x86_64
 
   premerge-check-macos:
 name: MacOS Premerge Checks

``




https://github.com/llvm/llvm-project/pull/170414
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [Github][CI] Make premerge upload results on Linux and Windows (PR #170414)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-github-workflow

Author: Aiden Grossman (boomanaiden154)


Changes

Now that the issue-write workflow can support writing comments from
multiple files, make the premerge workflow write out comments from both
x86_64 Linux and Windows. AArch64 Linux right now is left out as the
premerge advisor does not currently support it.


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


2 Files Affected:

- (modified) .ci/premerge_advisor_explain.py (+2-1) 
- (modified) .github/workflows/premerge.yaml (+10-2) 


``diff
diff --git a/.ci/premerge_advisor_explain.py b/.ci/premerge_advisor_explain.py
index 155e91bef55f8..bd65eb3d1588b 100644
--- a/.ci/premerge_advisor_explain.py
+++ b/.ci/premerge_advisor_explain.py
@@ -129,7 +129,8 @@ def main(
 # If the job succeeds and there is not an existing comment, we
 # should not write one to reduce noise.
 comments = []
-with open("comments", "w") as comment_file_handle:
+comments_file_name = f"comments-{platform.system()}-{platform.machine()}"
+with open(comments_file_name, "w") as comment_file_handle:
 json.dump(comments, comment_file_handle)
 
 
diff --git a/.github/workflows/premerge.yaml b/.github/workflows/premerge.yaml
index 10f7f6a827b30..4ea5397edbeac 100644
--- a/.github/workflows/premerge.yaml
+++ b/.github/workflows/premerge.yaml
@@ -124,9 +124,9 @@ jobs:
 if: ${{ always() && !startsWith(matrix.runs-on, 
'depot-ubuntu-24.04-arm') }}
 continue-on-error: true
 with:
-  name: workflow-args
+  name: workflow-args-x86-linux
   path: |
-comments
+comments-Linux-x86_64
 
   premerge-checks-windows:
 name: Build and Test Windows
@@ -185,6 +185,14 @@ jobs:
   path: artifacts/
   retention-days: 5
   include-hidden-files: 'true'
+  - name: Upload Comment
+uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 
# v5.0.0
+if: always()
+continue-on-error: true
+with:
+  name: workflow-args-windows
+  path: |
+comments-Windows-x86_64
 
   premerge-check-macos:
 name: MacOS Premerge Checks

``




https://github.com/llvm/llvm-project/pull/170414
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [Github][CI] Make premerge upload results on Linux and Windows (PR #170414)

2025-12-02 Thread Aiden Grossman via llvm-branch-commits

https://github.com/boomanaiden154 created 
https://github.com/llvm/llvm-project/pull/170414

Now that the issue-write workflow can support writing comments from
multiple files, make the premerge workflow write out comments from both
x86_64 Linux and Windows. AArch64 Linux right now is left out as the
premerge advisor does not currently support it.



___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 7: Constexpr support and tests) (PR #169686)

2025-12-02 Thread via llvm-branch-commits

Sirraide wrote:

They’re essentially all already implemented:

* [CWG3044](https://cplusplus.github.io/CWG/issues/3044.html) "Iterating 
expansion statements woes": This one is implemented, but note that it’s 
partially superseded by 3131.
* [CWG3048](https://cplusplus.github.io/CWG/issues/3048.html) "Empty 
destructuring expansion statements": Also implemented (though the AST 
representation is currently bit strange since we end up w/ an empty 
`DecompositionDecl`; I’m not sure we care to change that though)
* [CWG3061](https://cplusplus.github.io/CWG/issues/3061.html) "Trailing comma 
in an expansion-init-list" : Also implemented.
* [CWG3123](https://cplusplus.github.io/CWG/issues/3123.html) "Global lookup 
for begin and end for expansion statements": That one I opened, so yes, it’s 
implemented.
* [CWG3131](https://cplusplus.github.io/CWG/issues/3131.html) "Value categories 
and types for the range in iterable expansion statements": That one I just got 
done implementing; see 
https://github.com/llvm/llvm-project/pull/169684#issuecomment-3604786775 as 
well as some of the comments I just added to that patch.

> I'd also be very grateful if you added tests for those Core issues. Probably 
> not right now, as the last two hasn't even been discussed in Core

Then should I make that a follow-up patch after this entire patch series is 
merged?



https://github.com/llvm/llvm-project/pull/169686
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 7: Constexpr support and tests) (PR #169686)

2025-12-02 Thread via llvm-branch-commits

Sirraide wrote:

There is also [CWG 3043](https://cplusplus.github.io/CWG/issues/3043.html), 
which is also implemented.

https://github.com/llvm/llvm-project/pull/169686
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 8: Codegen) (PR #169687)

2025-12-02 Thread via llvm-branch-commits

Sirraide wrote:

Windows CI failure seems unrelated

https://github.com/llvm/llvm-project/pull/169687
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] DAG: Avoid using getLibcallName when looking for a divrem call (PR #170413)

2025-12-02 Thread via llvm-branch-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

* 166637 tests passed
* 2905 tests skipped
* 1 test failed

## Failed Tests
(click on a test name to see its output)

### lldb-api

lldb-api.functionalities/scripted_frame_provider/circular_dependency/TestFrameProviderCircularDependency.py

```
Script:
--
/usr/bin/python3 
/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py
 -u CXXFLAGS -u CFLAGS --env 
LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib
 --env 
LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include
 --env 
LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin
 --libcxx-include-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 
--libcxx-include-target-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1
 --libcxx-library-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu
 --arch x86_64 --build-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex
 --lldb-module-cache-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api
 --clang-module-cache-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api
 --executable 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb 
--compiler 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang 
--dsymutil 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil 
--make /usr/bin/gmake --llvm-tools-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin 
--lldb-obj-root 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb 
--lldb-libs-dir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib 
--cmake-build-type Release 
/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/circular_dependency
 -p TestFrameProviderCircularDependency.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 
839675d22eab0e656dc278c2ba6f08c690d82c80)
  clang revision 839675d22eab0e656dc278c2ba6f08c690d82c80
  llvm revision 839675d22eab0e656dc278c2ba6f08c690d82c80
Skipping the following test categories: msvcstl, dsym, pdb, gmodules, 
debugserver, objc

--
Command Output (stderr):
--
Traceback (most recent call last):
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py",
 line 8, in 
lldbsuite.test.run_suite()
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py",
 line 1115, in run_suite
visit("Test", dirpath, filenames)
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py",
 line 716, in visit
visit_file(dir, name)
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py",
 line 659, in visit_file
module = __import__(base)
 
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/circular_dependency/TestFrameProviderCircularDependency.py",
 line 12, in 
class FrameProviderCircularDependencyTestCase(TestBase):
  File 
"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/circular_dependency/TestFrameProviderCircularDependency.py",
 line 19, in FrameProviderCircularDependencyTestCase
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
 ^^
NameError: name 'expectedFailureAll' is not defined

--

```


If these failures are unrelated to your changes (for example tests are broken 
or flaky at HEAD), please open an issue at 
https://github.com/llvm/llvm-project/issues and add the `infrastructure` label.

https://github.com/llvm/llvm-project/pull/170413
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 Thread Saleem Abdulrasool via llvm-branch-commits

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


https://github.com/llvm/llvm-project/pull/170329
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [LifetimeSafety] Move shouldTrack functions to LifetimeAnnotations (PR #170005)

2025-12-02 Thread Utkarsh Saxena via llvm-branch-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/170005
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU] Avoid undefs in hazard-gfx1250-flat-scr-hi.mir. NFC (PR #170396)

2025-12-02 Thread Stanislav Mekhanoshin via llvm-branch-commits

https://github.com/rampitec created 
https://github.com/llvm/llvm-project/pull/170396

None

>From 78f3a2ae93791d29ea1fdf5d79891a333727232d Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin 
Date: Tue, 2 Dec 2025 16:37:01 -0800
Subject: [PATCH] [AMDGPU] Avoid undefs in hazard-gfx1250-flat-scr-hi.mir. NFC

---
 .../AMDGPU/hazard-gfx1250-flat-scr-hi.mir | 84 ---
 1 file changed, 54 insertions(+), 30 deletions(-)

diff --git a/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir 
b/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir
index e3b28c5518695..5dafa1b72ed10 100644
--- a/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir
+++ b/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir
@@ -8,10 +8,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_ashr_i64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_ASHR_I64_:%[0-9]+]]:sreg_64 = S_ASHR_I64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_ASHR_I64_:%[0-9]+]]:sreg_64 = S_ASHR_I64 [[DEF]], 
[[COPY]], implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_ASHR_I64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_ASHR_I64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -21,10 +23,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_lshl_b64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_LSHL_B64_:%[0-9]+]]:sreg_64 = S_LSHL_B64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_LSHL_B64_:%[0-9]+]]:sreg_64 = S_LSHL_B64 [[DEF]], 
[[COPY]], implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_LSHL_B64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_LSHL_B64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -34,10 +38,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_lshr_b64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_LSHR_B64_:%[0-9]+]]:sreg_64 = S_LSHR_B64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_LSHR_B64_:%[0-9]+]]:sreg_64 = S_LSHR_B64 [[DEF]], 
[[COPY]], implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_LSHR_B64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_LSHR_B64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -47,10 +53,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_bfe_i64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 [[DEF]], [[COPY]], 
implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_BFE_I64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_BFE_I64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -60,10 +68,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_bfe_u64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 [[DEF]], [[COPY]], 
implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_BFE_U64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_BFE_U64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -86,10 +96,14 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_bitcmp0_b64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: S_BITCMP0_B64 undef %1:sreg_64, [[COPY]], implicit undef $scc, 
implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: $scc = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: S_BITCMP0_B64 [[DEF]], [[COPY]], implicit $scc, implicit-def 
$scc
+%1:sreg_64 = IMPLICIT_DEF
+$scc = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-S_BITCMP0_B64 undef %1:sreg_64, %0, implicit undef $scc, implicit-def $scc
+S_BITCMP0_B6

[llvm-branch-commits] [llvm] [AMDGPU] Avoid undefs in hazard-gfx1250-flat-scr-hi.mir. NFC (PR #170396)

2025-12-02 Thread Stanislav Mekhanoshin via llvm-branch-commits

rampitec wrote:

* #170396 👈
* #170395
* `main`



This stack of pull requests is managed by https://github.com/shiltian/sgh";>sgh.


https://github.com/llvm/llvm-project/pull/170396
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU] Avoid undefs in hazard-gfx1250-flat-scr-hi.mir. NFC (PR #170396)

2025-12-02 Thread Stanislav Mekhanoshin via llvm-branch-commits

https://github.com/rampitec ready_for_review 
https://github.com/llvm/llvm-project/pull/170396
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU] Avoid undefs in hazard-gfx1250-flat-scr-hi.mir. NFC (PR #170396)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-amdgpu

Author: Stanislav Mekhanoshin (rampitec)


Changes



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


1 Files Affected:

- (modified) llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir (+54-30) 


``diff
diff --git a/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir 
b/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir
index e3b28c5518695..5dafa1b72ed10 100644
--- a/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir
+++ b/llvm/test/CodeGen/AMDGPU/hazard-gfx1250-flat-scr-hi.mir
@@ -8,10 +8,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_ashr_i64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_ASHR_I64_:%[0-9]+]]:sreg_64 = S_ASHR_I64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_ASHR_I64_:%[0-9]+]]:sreg_64 = S_ASHR_I64 [[DEF]], 
[[COPY]], implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_ASHR_I64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_ASHR_I64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -21,10 +23,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_lshl_b64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_LSHL_B64_:%[0-9]+]]:sreg_64 = S_LSHL_B64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_LSHL_B64_:%[0-9]+]]:sreg_64 = S_LSHL_B64 [[DEF]], 
[[COPY]], implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_LSHL_B64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_LSHL_B64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -34,10 +38,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_lshr_b64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_LSHR_B64_:%[0-9]+]]:sreg_64 = S_LSHR_B64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_LSHR_B64_:%[0-9]+]]:sreg_64 = S_LSHR_B64 [[DEF]], 
[[COPY]], implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_LSHR_B64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_LSHR_B64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -47,10 +53,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_bfe_i64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 [[DEF]], [[COPY]], 
implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_BFE_I64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_BFE_I64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -60,10 +68,12 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_bfe_u64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 undef %2:sreg_64, 
[[COPY]], implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 [[DEF]], [[COPY]], 
implicit-def $scc
+%1:sreg_64 = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-%2:sreg_64 = S_BFE_U64 undef %1:sreg_64, %0, implicit-def $scc
+%2:sreg_64 = S_BFE_U64 %1:sreg_64, %0, implicit-def $scc
 ...
 
 ---
@@ -86,10 +96,14 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_bitcmp0_b64
-; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
-; GCN-NEXT: S_BITCMP0_B64 undef %1:sreg_64, [[COPY]], implicit undef $scc, 
implicit-def $scc
+; GCN: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+; GCN-NEXT: $scc = IMPLICIT_DEF
+; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $src_flat_scratch_base_hi
+; GCN-NEXT: S_BITCMP0_B64 [[DEF]], [[COPY]], implicit $scc, implicit-def 
$scc
+%1:sreg_64 = IMPLICIT_DEF
+$scc = IMPLICIT_DEF
 %0:sreg_32 = COPY $src_flat_scratch_base_hi
-S_BITCMP0_B64 undef %1:sreg_64, %0, implicit undef $scc, implicit-def $scc
+S_BITCMP0_B64 %1:sreg_64, %0, implicit $scc, implicit-def $scc
 ...
 
 ---
@@ -99,10 +113,14 @@ body: |
   bb.0:
 
 ; GCN-LABEL: name: s_b

[llvm-branch-commits] [clang] [Clang] Support __bf16 type for SPIR/SPIR-V (#169012) (PR #170230)

2025-12-02 Thread Wenju He via llvm-branch-commits

wenju-he wrote:

> Does that actually need to be backported? It seems to be a new feature and 
> Clang 22 will release in a couple of months. Thanks!

let me double check, thanks

https://github.com/llvm/llvm-project/pull/170230
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU] Avoid undefs in hazard-gfx1250-flat-scr-hi.mir. NFC (PR #170396)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

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


https://github.com/llvm/llvm-project/pull/170396
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Peter Collingbourne via llvm-branch-commits

https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/151647

>From 37c355e3264bba72999fa6dcbc565ae82bc1a1a5 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne 
Date: Wed, 26 Nov 2025 11:01:52 -0800
Subject: [PATCH 1/2] Fix tests

Created using spr 1.3.6-beta.1
---
 .../protected-field-pointer-addrspace1.ll | 4 ++--
 .../PreISelIntrinsicLowering/protected-field-pointer.ll   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git 
a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
 
b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
index 5493d38eb49ba..6b4c9ef646660 100644
--- 
a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
+++ 
b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
@@ -157,11 +157,11 @@ declare ptr addrspace(1) @llvm.protected.field.ptr.p1(ptr 
addrspace(1), i64, i1
 ;.
 ; NOPAUTH: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; NOPAUTH: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(none) }
-; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
 ; PAUTH: attributes #[[ATTR0]] = { "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; PAUTH: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(none) }
-; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
diff --git 
a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll 
b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll
index b8c605177e33b..cd0fcb40d0d77 100644
--- a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll
+++ b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll
@@ -157,11 +157,11 @@ declare ptr @llvm.protected.field.ptr.p0(ptr, i64, i1 
immarg)
 ;.
 ; NOPAUTH: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; NOPAUTH: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(none) }
-; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
 ; PAUTH: attributes #[[ATTR0]] = { "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; PAUTH: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(none) }
-; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.

>From 31141b689aa94a34dba095c149bea88634411a42 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne 
Date: Wed, 26 Nov 2025 16:32:47 -0800
Subject: [PATCH 2/2] Unsupport SW encoding

Created using spr 1.3.6-beta.1
---
 llvm/docs/LangRef.rst |  6 +-
 llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 26 +---
 .../protected-field-pointer-addrspace1.ll | 64 ++-
 .../protected-field-pointer.ll| 64 ++-
 4 files changed, 13 insertions(+), 147 deletions(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 8048c89b41663..7e93c67a9a31d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -31762,10 +31762,8 @@ third argument is 1, the pointer is signed (using 
pointer authentication
 instructions or emulated PAC if not supported by the hardware) using
 the discriminator before being stored, and authenticated after being
 loaded. Note that it is currently unsupported to have the third argument
-be 1 on targets other than AArch64. When the third argument is 0, it is
-rotated left by 16 bits and the discriminator is subtracted before being
-stored, and the discriminator is added and the pointer is rotated right
-by 16 bits after being loaded.
+be 1 on targets other than AArch64, and it is also currently unsupported
+to have the third argument be 0 at all.
 
 If the pointer is used other than for loading 

[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Peter Collingbourne via llvm-branch-commits

https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/151647

>From 37c355e3264bba72999fa6dcbc565ae82bc1a1a5 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne 
Date: Wed, 26 Nov 2025 11:01:52 -0800
Subject: [PATCH 1/2] Fix tests

Created using spr 1.3.6-beta.1
---
 .../protected-field-pointer-addrspace1.ll | 4 ++--
 .../PreISelIntrinsicLowering/protected-field-pointer.ll   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git 
a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
 
b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
index 5493d38eb49ba..6b4c9ef646660 100644
--- 
a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
+++ 
b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer-addrspace1.ll
@@ -157,11 +157,11 @@ declare ptr addrspace(1) @llvm.protected.field.ptr.p1(ptr 
addrspace(1), i64, i1
 ;.
 ; NOPAUTH: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; NOPAUTH: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(none) }
-; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
 ; PAUTH: attributes #[[ATTR0]] = { "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; PAUTH: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(none) }
-; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
diff --git 
a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll 
b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll
index b8c605177e33b..cd0fcb40d0d77 100644
--- a/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll
+++ b/llvm/test/Transforms/PreISelIntrinsicLowering/protected-field-pointer.ll
@@ -157,11 +157,11 @@ declare ptr @llvm.protected.field.ptr.p0(ptr, i64, i1 
immarg)
 ;.
 ; NOPAUTH: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; NOPAUTH: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(none) }
-; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; NOPAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
 ; PAUTH: attributes #[[ATTR0]] = { "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) "target-features"="+pauth" }
 ; PAUTH: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind 
willreturn memory(none) }
 ; PAUTH: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(none) }
-; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind 
speculatable willreturn memory(none) }
+; PAUTH: attributes #[[ATTR4:[0-9]+]] = { nocallback nocreateundeforpoison 
nofree nosync nounwind speculatable willreturn memory(none) }
 ;.

>From 31141b689aa94a34dba095c149bea88634411a42 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne 
Date: Wed, 26 Nov 2025 16:32:47 -0800
Subject: [PATCH 2/2] Unsupport SW encoding

Created using spr 1.3.6-beta.1
---
 llvm/docs/LangRef.rst |  6 +-
 llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 26 +---
 .../protected-field-pointer-addrspace1.ll | 64 ++-
 .../protected-field-pointer.ll| 64 ++-
 4 files changed, 13 insertions(+), 147 deletions(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 8048c89b41663..7e93c67a9a31d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -31762,10 +31762,8 @@ third argument is 1, the pointer is signed (using 
pointer authentication
 instructions or emulated PAC if not supported by the hardware) using
 the discriminator before being stored, and authenticated after being
 loaded. Note that it is currently unsupported to have the third argument
-be 1 on targets other than AArch64. When the third argument is 0, it is
-rotated left by 16 bits and the discriminator is subtracted before being
-stored, and the discriminator is added and the pointer is rotated right
-by 16 bits after being loaded.
+be 1 on targets other than AArch64, and it is also currently unsupported
+to have the third argument be 0 at all.
 
 If the pointer is used other than for loading 

[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Peter Collingbourne via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);
+
+  auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
+  return B.CreateCall(SignIntr, {Val, B.getInt32(2), Disc}, DSBundle);

pcc wrote:

That's `AArch64PACKey::DA` from the AArch64 backend but we can't access it from 
here so I left a comment.

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Peter Collingbourne via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);
+
+  auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))

pcc wrote:

No, the `__emupac_*` functions check for PAC support and use the PAC 
instructions if available, so the encoding will be consistent. The 
target-feature effectively lets us optimize away the else branch of the
```
if (pac) {
  use pac instructions;
} else { 
  use emulated pac;
}
```
in the emupac runtime.

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Peter Collingbourne via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);
+
+  auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
+  return B.CreateCall(SignIntr, {Val, B.getInt32(2), Disc}, DSBundle);
+return B.CreateCall(EmuSignIntr, {Val, Disc}, DSBundle);
+  };
+
+  auto CreateAuth = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
+  return B.CreateCall(AuthIntr, {Val, B.getInt32(2), Disc}, DSBundle);
+return B.CreateCall(EmuAuthIntr, {Val, Disc}, DSBundle);
+  };
+
+  auto GetDeactivationSymbol = [&](CallInst *Call) -> GlobalValue * {
+if (auto Bundle =
+Call->getOperandBundle(LLVMContext::OB_deactivation_symbol))
+  return cast(Bundle->Inputs[0]);
+return nullptr;
+  };
+
+  for (User *U : llvm::make_early_inc_range(Intr.users())) {
+auto *Call = cast(U);
+
+auto *Pointer = Call->getArgOperand(0);
+auto *Disc = Call->getArgOperand(1);
+bool UseHWEncoding =
+cast(Call->getArgOperand(2))->getZExtValue();
+assert(UseHWEncoding && "software encoding currently unsupported");

pcc wrote:

Done

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Peter Collingbourne via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);

pcc wrote:

Done

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-x86

Author: Matt Arsenault (arsenm)


Changes

GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.

Old pass manager hacking

---

Patch is 49.98 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/170328.diff


15 Files Affected:

- (modified) llvm/include/llvm/Analysis/RuntimeLibcallInfo.h (+2) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h (+6-5) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h (+43-30) 
- (modified) llvm/include/llvm/CodeGen/LibcallLoweringInfo.h (+11-5) 
- (modified) llvm/include/llvm/CodeGen/Passes.h (+2) 
- (modified) llvm/lib/CodeGen/ExpandFp.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/GlobalISel/Legalizer.cpp (+16-9) 
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+71-78) 
- (modified) llvm/lib/CodeGen/LibcallLoweringInfo.cpp (+6-3) 
- (modified) llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/TargetPassConfig.cpp (+2) 
- (modified) llvm/lib/Target/ARM/ARMLegalizerInfo.cpp (+9-9) 
- (modified) llvm/unittests/CodeGen/GlobalISel/GISelMITest.h (+4) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (+32-31) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp (+3-3) 


``diff
diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h 
b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
index 2d31c8aa6301b..b0f398d6e2b28 100644
--- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
+++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
@@ -32,6 +32,8 @@ class LLVM_ABI RuntimeLibraryAnalysis
   LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
   ModuleAnalysisManager &);
 
+  operator bool() const { return LibcallsInfo.has_value(); }
+
 private:
   friend AnalysisInfoMixin;
   LLVM_ABI static AnalysisKey Key;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h 
b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
+class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult
-  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
-  ArrayRef AuxObservers,
-  LostDebugLocObserver &LocObserver,
-  MachineIRBuilder &MIRBuilder, GISelValueTracking 
*VT);
+  static MFResult legalizeMachineFunction(
+  MachineFunction &MF, const LegalizerInfo &LI,
+  ArrayRef AuxObservers,
+  LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+  const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h 
b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-  GISelValueTracking *VT;
+
+  // FIXME: Should probably make Libcalls mandatory
+  const LibcallLoweringInfo *Libcalls = nullptr;
+  GISelValueTracking *VT = nullptr;
 
 public:
   enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
+  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-   MachineIRBuilder &B);
+   MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Obs

[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-aarch64

Author: Matt Arsenault (arsenm)


Changes

GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.

Old pass manager hacking

---

Patch is 49.98 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/170328.diff


15 Files Affected:

- (modified) llvm/include/llvm/Analysis/RuntimeLibcallInfo.h (+2) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h (+6-5) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h (+43-30) 
- (modified) llvm/include/llvm/CodeGen/LibcallLoweringInfo.h (+11-5) 
- (modified) llvm/include/llvm/CodeGen/Passes.h (+2) 
- (modified) llvm/lib/CodeGen/ExpandFp.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/GlobalISel/Legalizer.cpp (+16-9) 
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+71-78) 
- (modified) llvm/lib/CodeGen/LibcallLoweringInfo.cpp (+6-3) 
- (modified) llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/TargetPassConfig.cpp (+2) 
- (modified) llvm/lib/Target/ARM/ARMLegalizerInfo.cpp (+9-9) 
- (modified) llvm/unittests/CodeGen/GlobalISel/GISelMITest.h (+4) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (+32-31) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp (+3-3) 


``diff
diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h 
b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
index 2d31c8aa6301b..b0f398d6e2b28 100644
--- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
+++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
@@ -32,6 +32,8 @@ class LLVM_ABI RuntimeLibraryAnalysis
   LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
   ModuleAnalysisManager &);
 
+  operator bool() const { return LibcallsInfo.has_value(); }
+
 private:
   friend AnalysisInfoMixin;
   LLVM_ABI static AnalysisKey Key;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h 
b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
+class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult
-  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
-  ArrayRef AuxObservers,
-  LostDebugLocObserver &LocObserver,
-  MachineIRBuilder &MIRBuilder, GISelValueTracking 
*VT);
+  static MFResult legalizeMachineFunction(
+  MachineFunction &MF, const LegalizerInfo &LI,
+  ArrayRef AuxObservers,
+  LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+  const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h 
b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-  GISelValueTracking *VT;
+
+  // FIXME: Should probably make Libcalls mandatory
+  const LibcallLoweringInfo *Libcalls = nullptr;
+  GISelValueTracking *VT = nullptr;
 
 public:
   enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
+  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-   MachineIRBuilder &B);
+   MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver 

[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)


Changes

GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.

Old pass manager hacking

---

Patch is 49.98 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/170328.diff


15 Files Affected:

- (modified) llvm/include/llvm/Analysis/RuntimeLibcallInfo.h (+2) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h (+6-5) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h (+43-30) 
- (modified) llvm/include/llvm/CodeGen/LibcallLoweringInfo.h (+11-5) 
- (modified) llvm/include/llvm/CodeGen/Passes.h (+2) 
- (modified) llvm/lib/CodeGen/ExpandFp.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/GlobalISel/Legalizer.cpp (+16-9) 
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+71-78) 
- (modified) llvm/lib/CodeGen/LibcallLoweringInfo.cpp (+6-3) 
- (modified) llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/TargetPassConfig.cpp (+2) 
- (modified) llvm/lib/Target/ARM/ARMLegalizerInfo.cpp (+9-9) 
- (modified) llvm/unittests/CodeGen/GlobalISel/GISelMITest.h (+4) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (+32-31) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp (+3-3) 


``diff
diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h 
b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
index 2d31c8aa6301b..b0f398d6e2b28 100644
--- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
+++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
@@ -32,6 +32,8 @@ class LLVM_ABI RuntimeLibraryAnalysis
   LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
   ModuleAnalysisManager &);
 
+  operator bool() const { return LibcallsInfo.has_value(); }
+
 private:
   friend AnalysisInfoMixin;
   LLVM_ABI static AnalysisKey Key;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h 
b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
+class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult
-  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
-  ArrayRef AuxObservers,
-  LostDebugLocObserver &LocObserver,
-  MachineIRBuilder &MIRBuilder, GISelValueTracking 
*VT);
+  static MFResult legalizeMachineFunction(
+  MachineFunction &MF, const LegalizerInfo &LI,
+  ArrayRef AuxObservers,
+  LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+  const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h 
b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-  GISelValueTracking *VT;
+
+  // FIXME: Should probably make Libcalls mandatory
+  const LibcallLoweringInfo *Libcalls = nullptr;
+  GISelValueTracking *VT = nullptr;
 
 public:
   enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
+  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-   MachineIRBuilder &B);
+   MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver 

[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/170329
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/170328
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/170329

None

>From 9cf982a53216d83086bb9fd7a82f4fee8565567a Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 24 Nov 2025 13:48:45 -0500
Subject: [PATCH] StackProtector: Use LibcallLoweringInfo analysis

---
 llvm/lib/CodeGen/StackProtector.cpp   | 82 +--
 .../NVPTX/no-stack-protector-libcall-error.ll |  2 +-
 .../X86/stack-protector-atomicrmw-xchg.ll |  4 +-
 .../cross-dso-cfi-stack-chk-fail.ll   |  2 +-
 .../StackProtector/missing-analysis.ll|  7 ++
 .../StackProtector/stack-chk-fail-alias.ll|  2 +-
 6 files changed, 67 insertions(+), 32 deletions(-)
 create mode 100644 llvm/test/Transforms/StackProtector/missing-analysis.ll

diff --git a/llvm/lib/CodeGen/StackProtector.cpp 
b/llvm/lib/CodeGen/StackProtector.cpp
index 5fd5d6cce23df..d56ef00ac7d08 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -69,13 +69,15 @@ static cl::opt 
DisableCheckNoReturn("disable-check-noreturn-call",
 ///  - The prologue code loads and stores the stack guard onto the stack.
 ///  - The epilogue checks the value stored in the prologue against the 
original
 ///value. It calls __stack_chk_fail if they differ.
-static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
-  DomTreeUpdater *DTU, bool &HasPrologue,
-  bool &HasIRCheck);
+static bool InsertStackProtectors(const TargetLowering &TLI,
+  const LibcallLoweringInfo &Libcalls,
+  Function *F, DomTreeUpdater *DTU,
+  bool &HasPrologue, bool &HasIRCheck);
 
 /// CreateFailBB - Create a basic block to jump to when the stack protector
 /// check fails.
-static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
+static BasicBlock *CreateFailBB(Function *F,
+const LibcallLoweringInfo &Libcalls);
 
 bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
   return HasPrologue && !HasIRCheck && isa(BB.getTerminator());
@@ -131,8 +133,23 @@ PreservedAnalyses StackProtectorPass::run(Function &F,
   return PreservedAnalyses::all();
   }
 
+  auto &MAMProxy = FAM.getResult(F);
+  const LibcallLoweringModuleAnalysisResult *LibcallLowering =
+  MAMProxy.getCachedResult(*F.getParent());
+
+  if (!LibcallLowering) {
+F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
+ "' analysis required");
+return PreservedAnalyses::all();
+  }
+
+  const TargetSubtargetInfo *STI = TM->getSubtargetImpl(F);
+  const TargetLowering *TLI = STI->getTargetLowering();
+  const LibcallLoweringInfo &Libcalls =
+  LibcallLowering->getLibcallLowering(*STI);
+
   ++NumFunProtected;
-  bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,
+  bool Changed = InsertStackProtectors(*TLI, Libcalls, &F, DT ? &DTU : nullptr,
Info.HasPrologue, Info.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DT ||
@@ -156,6 +173,7 @@ StackProtector::StackProtector() : FunctionPass(ID) {
 
 INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE,
   "Insert stack protectors", false, true)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
@@ -164,6 +182,7 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
 FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }
 
 void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired();
   AU.addRequired();
   AU.addPreserved();
 }
@@ -190,9 +209,16 @@ bool StackProtector::runOnFunction(Function &Fn) {
   return false;
   }
 
+  const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(Fn);
+  const LibcallLoweringInfo &Libcalls =
+  getAnalysis().getLibcallLowering(*M,
+   *Subtarget);
+
+  const TargetLowering *TLI = Subtarget->getTargetLowering();
+
   ++NumFunProtected;
   bool Changed =
-  InsertStackProtectors(TM, F, DTU ? &*DTU : nullptr,
+  InsertStackProtectors(*TLI, Libcalls, F, DTU ? &*DTU : nullptr,
 LayoutInfo.HasPrologue, LayoutInfo.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DTU ||
@@ -519,10 +545,10 @@ bool SSPLayoutAnalysis::requiresStackProtector(Function 
*F,
 
 /// Create a stack guard loading and populate whether SelectionDAG SSP is
 /// supported.
-static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
+static Value *getStackGuard(const TargetLoweringBase &TLI, Module *M,
 IRBuilder<> &B,
 bool *SupportsSelectionDAGSP = nullptr) {
-  Value *Guard = TLI->g

[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/170328

GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.

Old pass manager hacking

>From 2175cd70bae2b4464717327196ee5ffec85c0a34 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 24 Nov 2025 18:15:49 -0500
Subject: [PATCH 1/2] GlobalISel: Use LibcallLoweringInfo analysis in legalizer

This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.

I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.
---
 .../llvm/CodeGen/GlobalISel/Legalizer.h   |  11 +-
 .../llvm/CodeGen/GlobalISel/LegalizerHelper.h |  73 +
 llvm/lib/CodeGen/GlobalISel/Legalizer.cpp |  24 +--
 .../CodeGen/GlobalISel/LegalizerHelper.cpp| 149 +-
 llvm/lib/Target/ARM/ARMLegalizerInfo.cpp  |  18 +--
 .../CodeGen/GlobalISel/GISelMITest.h  |   4 +
 .../GlobalISel/LegalizerHelperTest.cpp|  63 
 .../CodeGen/GlobalISel/LegalizerTest.cpp  |   6 +-
 8 files changed, 183 insertions(+), 165 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h 
b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
+class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult
-  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
-  ArrayRef AuxObservers,
-  LostDebugLocObserver &LocObserver,
-  MachineIRBuilder &MIRBuilder, GISelValueTracking 
*VT);
+  static MFResult legalizeMachineFunction(
+  MachineFunction &MF, const LegalizerInfo &LI,
+  ArrayRef AuxObservers,
+  LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+  const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h 
b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-  GISelValueTracking *VT;
+
+  // FIXME: Should probably make Libcalls mandatory
+  const LibcallLoweringInfo *Libcalls = nullptr;
+  GISelValueTracking *VT = nullptr;
 
 public:
   enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
+  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-   MachineIRBuilder &B);
+   MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer, MachineIRBuilder &B,
+   const LibcallLoweringInfo *Libcalls = nullptr,
GISelValueTracking *VT = nullptr);
 
   /// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
   /// def by inserting a G_BITCAST from \p CastTy
   LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
 
+  // Useful for libcalls where all operands have the same type.
+  LLVM_ABI LegalizeResult
+  simpleLibcall(Machi

[llvm-branch-commits] [llvm] GlobalISel: Use LibcallLoweringInfo analysis in legalizer (PR #170328)

2025-12-02 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.com/github/pr/llvm/llvm-project/170328?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#170329** https://app.graphite.com/github/pr/llvm/llvm-project/170329?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#170328** https://app.graphite.com/github/pr/llvm/llvm-project/170328?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/170328?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#168622** https://app.graphite.com/github/pr/llvm/llvm-project/168622?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#168621** https://app.graphite.com/github/pr/llvm/llvm-project/168621?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#168620** https://app.graphite.com/github/pr/llvm/llvm-project/168620?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/170328
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 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.com/github/pr/llvm/llvm-project/170329?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#170329** https://app.graphite.com/github/pr/llvm/llvm-project/170329?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/170329?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#170328** https://app.graphite.com/github/pr/llvm/llvm-project/170328?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#168622** https://app.graphite.com/github/pr/llvm/llvm-project/168622?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#168621** https://app.graphite.com/github/pr/llvm/llvm-project/168621?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#168620** https://app.graphite.com/github/pr/llvm/llvm-project/168620?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/170329
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] StackProtector: Use LibcallLoweringInfo analysis (PR #170329)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-globalisel

Author: Matt Arsenault (arsenm)


Changes



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


6 Files Affected:

- (modified) llvm/lib/CodeGen/StackProtector.cpp (+55-27) 
- (modified) llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll (+1-1) 
- (modified) llvm/test/CodeGen/X86/stack-protector-atomicrmw-xchg.ll (+2-2) 
- (modified) 
llvm/test/Transforms/StackProtector/cross-dso-cfi-stack-chk-fail.ll (+1-1) 
- (added) llvm/test/Transforms/StackProtector/missing-analysis.ll (+7) 
- (modified) llvm/test/Transforms/StackProtector/stack-chk-fail-alias.ll (+1-1) 


``diff
diff --git a/llvm/lib/CodeGen/StackProtector.cpp 
b/llvm/lib/CodeGen/StackProtector.cpp
index 5fd5d6cce23df..d56ef00ac7d08 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -69,13 +69,15 @@ static cl::opt 
DisableCheckNoReturn("disable-check-noreturn-call",
 ///  - The prologue code loads and stores the stack guard onto the stack.
 ///  - The epilogue checks the value stored in the prologue against the 
original
 ///value. It calls __stack_chk_fail if they differ.
-static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
-  DomTreeUpdater *DTU, bool &HasPrologue,
-  bool &HasIRCheck);
+static bool InsertStackProtectors(const TargetLowering &TLI,
+  const LibcallLoweringInfo &Libcalls,
+  Function *F, DomTreeUpdater *DTU,
+  bool &HasPrologue, bool &HasIRCheck);
 
 /// CreateFailBB - Create a basic block to jump to when the stack protector
 /// check fails.
-static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
+static BasicBlock *CreateFailBB(Function *F,
+const LibcallLoweringInfo &Libcalls);
 
 bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
   return HasPrologue && !HasIRCheck && isa(BB.getTerminator());
@@ -131,8 +133,23 @@ PreservedAnalyses StackProtectorPass::run(Function &F,
   return PreservedAnalyses::all();
   }
 
+  auto &MAMProxy = FAM.getResult(F);
+  const LibcallLoweringModuleAnalysisResult *LibcallLowering =
+  MAMProxy.getCachedResult(*F.getParent());
+
+  if (!LibcallLowering) {
+F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
+ "' analysis required");
+return PreservedAnalyses::all();
+  }
+
+  const TargetSubtargetInfo *STI = TM->getSubtargetImpl(F);
+  const TargetLowering *TLI = STI->getTargetLowering();
+  const LibcallLoweringInfo &Libcalls =
+  LibcallLowering->getLibcallLowering(*STI);
+
   ++NumFunProtected;
-  bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,
+  bool Changed = InsertStackProtectors(*TLI, Libcalls, &F, DT ? &DTU : nullptr,
Info.HasPrologue, Info.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DT ||
@@ -156,6 +173,7 @@ StackProtector::StackProtector() : FunctionPass(ID) {
 
 INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE,
   "Insert stack protectors", false, true)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
@@ -164,6 +182,7 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
 FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }
 
 void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired();
   AU.addRequired();
   AU.addPreserved();
 }
@@ -190,9 +209,16 @@ bool StackProtector::runOnFunction(Function &Fn) {
   return false;
   }
 
+  const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(Fn);
+  const LibcallLoweringInfo &Libcalls =
+  getAnalysis().getLibcallLowering(*M,
+   *Subtarget);
+
+  const TargetLowering *TLI = Subtarget->getTargetLowering();
+
   ++NumFunProtected;
   bool Changed =
-  InsertStackProtectors(TM, F, DTU ? &*DTU : nullptr,
+  InsertStackProtectors(*TLI, Libcalls, F, DTU ? &*DTU : nullptr,
 LayoutInfo.HasPrologue, LayoutInfo.HasIRCheck);
 #ifdef EXPENSIVE_CHECKS
   assert((!DTU ||
@@ -519,10 +545,10 @@ bool SSPLayoutAnalysis::requiresStackProtector(Function 
*F,
 
 /// Create a stack guard loading and populate whether SelectionDAG SSP is
 /// supported.
-static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
+static Value *getStackGuard(const TargetLoweringBase &TLI, Module *M,
 IRBuilder<> &B,
 bool *SupportsSelectionDAGSP = nullptr) {
-  Value *Guard = TLI->getIRStackGuard(B);
+  Value *Guard = TLI.getIRStackGuard(B);
   StringRef GuardMode = M->getStackProt

[llvm-branch-commits] [clang] clang/AMDGPU: Enable opencl 2.0 features for unknown target (PR #170308)

2025-12-02 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Matt Arsenault (arsenm)


Changes

Assume amdhsa triples support flat addressing, which matches
the backend logic for the default target. This fixes the
rocm device-libs build.

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


2 Files Affected:

- (modified) clang/lib/Basic/Targets/AMDGPU.h (+13-1) 
- (modified) clang/test/Misc/amdgcn.languageOptsOpenCL.cl (+3) 


``diff
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 1d8f27ab915e2..8dcf1d1c9561a 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -84,6 +84,18 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
 return TT.getArch() == llvm::Triple::r600;
   }
 
+  bool hasFlatSupport() const {
+if (GPUKind >= llvm::AMDGPU::GK_GFX700)
+  return true;
+
+// Dummy target is assumed to be gfx700+ for amdhsa.
+if (GPUKind == llvm::AMDGPU::GK_NONE &&
+getTriple().getOS() == llvm::Triple::AMDHSA)
+  return true;
+
+return false;
+  }
+
 public:
   AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
 
@@ -325,7 +337,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
   Opts["__opencl_c_atomic_order_seq_cst"] = true;
   Opts["__opencl_c_atomic_scope_all_devices"] = true;
 
-  if (GPUKind >= llvm::AMDGPU::GK_GFX700) {
+  if (hasFlatSupport()) {
 Opts["__opencl_c_generic_address_space"] = true;
 Opts["__opencl_c_device_enqueue"] = true;
   }
diff --git a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl 
b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
index 57ea891b3eb29..08715fc5a1f4a 100644
--- a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
+++ b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
@@ -11,6 +11,9 @@
 // RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple 
amdgcn-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
 // RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple 
amdgcn-unknown-unknown -target-cpu gfx700 -Wpedantic-core-features 
-DTEST_CORE_FEATURES -DFLAT_SUPPORT
 
+// Test none target with amdhsa triple, which implies >= gfx700
+// RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple 
amdgcn-unknown-amdhsa -Wpedantic-core-features -DTEST_CORE_FEATURES 
-DFLAT_SUPPORT
+
 // Extensions in all versions
 #ifndef cl_clang_storage_class_specifiers
 #error "Missing cl_clang_storage_class_specifiers define"

``




https://github.com/llvm/llvm-project/pull/170308
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] clang/AMDGPU: Enable opencl 2.0 features for unknown target (PR #170308)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/170308

>From bab99b54ec0364cce91e470d5d1b9fd8bd21f5fb Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Tue, 2 Dec 2025 07:06:54 -0500
Subject: [PATCH] clang/AMDGPU: Enable opencl 2.0 features for unknown target

Assume amdhsa triples support flat addressing, which matches
the backend logic for the default target. This fixes the
rocm device-libs build.
---
 clang/lib/Basic/Targets/AMDGPU.h | 14 +-
 clang/test/CodeGenOpenCL/address-spaces.cl   |  5 +++--
 clang/test/CodeGenOpenCL/builtins-alloca.cl  |  4 ++--
 clang/test/Misc/amdgcn.languageOptsOpenCL.cl |  3 +++
 4 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 1d8f27ab915e2..8dcf1d1c9561a 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -84,6 +84,18 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
 return TT.getArch() == llvm::Triple::r600;
   }
 
+  bool hasFlatSupport() const {
+if (GPUKind >= llvm::AMDGPU::GK_GFX700)
+  return true;
+
+// Dummy target is assumed to be gfx700+ for amdhsa.
+if (GPUKind == llvm::AMDGPU::GK_NONE &&
+getTriple().getOS() == llvm::Triple::AMDHSA)
+  return true;
+
+return false;
+  }
+
 public:
   AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
 
@@ -325,7 +337,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
   Opts["__opencl_c_atomic_order_seq_cst"] = true;
   Opts["__opencl_c_atomic_scope_all_devices"] = true;
 
-  if (GPUKind >= llvm::AMDGPU::GK_GFX700) {
+  if (hasFlatSupport()) {
 Opts["__opencl_c_generic_address_space"] = true;
 Opts["__opencl_c_device_enqueue"] = true;
   }
diff --git a/clang/test/CodeGenOpenCL/address-spaces.cl 
b/clang/test/CodeGenOpenCL/address-spaces.cl
index 5b2a95c6ac16a..b9f01069fa26c 100644
--- a/clang/test/CodeGenOpenCL/address-spaces.cl
+++ b/clang/test/CodeGenOpenCL/address-spaces.cl
@@ -2,9 +2,10 @@
 // RUN: %clang_cc1 %s -O0 -cl-std=CL3.0 -cl-ext=-all -ffake-address-space-map 
-emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR
 // RUN: %clang_cc1 %s -O0 -cl-std=clc++2021 -cl-ext=-all 
-ffake-address-space-map -emit-llvm -o - | FileCheck %s 
--check-prefixes=CHECK,SPIR
 // RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map 
-emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -emit-llvm -o - | 
FileCheck --check-prefixes=CHECK,AMDGCN %s
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -emit-llvm 
-o - | FileCheck --check-prefixes=CHECK,AMDGCN %s
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-mesa3d -emit-llvm -o - | 
FileCheck --check-prefixes=CHECK,AMDGCN %s
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-mesa3d -cl-std=CL3.0 -emit-llvm 
-o - | FileCheck --check-prefixes=CHECK,AMDGCN %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -DCL20 -cl-std=CL2.0 
-emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20AMDGCN
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -DCL20 -cl-std=CL3.0 
-emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20AMDGCN
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -emit-llvm -o - | 
FileCheck --check-prefixes=CHECK,AMDGCN %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -cl-std=CL3.0 -emit-llvm 
-o - | FileCheck --check-prefixes=CHECK,AMDGCN %s
 // RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -o - | FileCheck 
--check-prefixes=CHECK,AMDGCN %s
diff --git a/clang/test/CodeGenOpenCL/builtins-alloca.cl 
b/clang/test/CodeGenOpenCL/builtins-alloca.cl
index ce7da3aba9e45..51da8e3b3badb 100644
--- a/clang/test/CodeGenOpenCL/builtins-alloca.cl
+++ b/clang/test/CodeGenOpenCL/builtins-alloca.cl
@@ -3,9 +3,9 @@
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL12 %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL2.0 \
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL20 %s
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 \
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-mesa3d -target-cpu gfx600 
-cl-std=CL3.0 \
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL30 %s
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 
-cl-ext=+__opencl_c_generic_address_space \
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 \
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL30GAS %s
 
 // OPENCL-LABEL: define dso_local void @test1_builtin_alloca(
diff --git a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl 
b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
index 57ea891b3eb29..08715fc5a1f4a 100644
--- a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
+++ b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
@@ -11,6 +11,9 @@
 // RUN: %clang_cc1 -x cl -cl-std=CL3.0

[llvm-branch-commits] [clang] clang/AMDGPU: Enable opencl 2.0 features for unknown target (PR #170308)

2025-12-02 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/170308

>From bab99b54ec0364cce91e470d5d1b9fd8bd21f5fb Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Tue, 2 Dec 2025 07:06:54 -0500
Subject: [PATCH] clang/AMDGPU: Enable opencl 2.0 features for unknown target

Assume amdhsa triples support flat addressing, which matches
the backend logic for the default target. This fixes the
rocm device-libs build.
---
 clang/lib/Basic/Targets/AMDGPU.h | 14 +-
 clang/test/CodeGenOpenCL/address-spaces.cl   |  5 +++--
 clang/test/CodeGenOpenCL/builtins-alloca.cl  |  4 ++--
 clang/test/Misc/amdgcn.languageOptsOpenCL.cl |  3 +++
 4 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 1d8f27ab915e2..8dcf1d1c9561a 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -84,6 +84,18 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
 return TT.getArch() == llvm::Triple::r600;
   }
 
+  bool hasFlatSupport() const {
+if (GPUKind >= llvm::AMDGPU::GK_GFX700)
+  return true;
+
+// Dummy target is assumed to be gfx700+ for amdhsa.
+if (GPUKind == llvm::AMDGPU::GK_NONE &&
+getTriple().getOS() == llvm::Triple::AMDHSA)
+  return true;
+
+return false;
+  }
+
 public:
   AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
 
@@ -325,7 +337,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
   Opts["__opencl_c_atomic_order_seq_cst"] = true;
   Opts["__opencl_c_atomic_scope_all_devices"] = true;
 
-  if (GPUKind >= llvm::AMDGPU::GK_GFX700) {
+  if (hasFlatSupport()) {
 Opts["__opencl_c_generic_address_space"] = true;
 Opts["__opencl_c_device_enqueue"] = true;
   }
diff --git a/clang/test/CodeGenOpenCL/address-spaces.cl 
b/clang/test/CodeGenOpenCL/address-spaces.cl
index 5b2a95c6ac16a..b9f01069fa26c 100644
--- a/clang/test/CodeGenOpenCL/address-spaces.cl
+++ b/clang/test/CodeGenOpenCL/address-spaces.cl
@@ -2,9 +2,10 @@
 // RUN: %clang_cc1 %s -O0 -cl-std=CL3.0 -cl-ext=-all -ffake-address-space-map 
-emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR
 // RUN: %clang_cc1 %s -O0 -cl-std=clc++2021 -cl-ext=-all 
-ffake-address-space-map -emit-llvm -o - | FileCheck %s 
--check-prefixes=CHECK,SPIR
 // RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map 
-emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -emit-llvm -o - | 
FileCheck --check-prefixes=CHECK,AMDGCN %s
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -emit-llvm 
-o - | FileCheck --check-prefixes=CHECK,AMDGCN %s
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-mesa3d -emit-llvm -o - | 
FileCheck --check-prefixes=CHECK,AMDGCN %s
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-mesa3d -cl-std=CL3.0 -emit-llvm 
-o - | FileCheck --check-prefixes=CHECK,AMDGCN %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -DCL20 -cl-std=CL2.0 
-emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20AMDGCN
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -DCL20 -cl-std=CL3.0 
-emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20AMDGCN
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -emit-llvm -o - | 
FileCheck --check-prefixes=CHECK,AMDGCN %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -cl-std=CL3.0 -emit-llvm 
-o - | FileCheck --check-prefixes=CHECK,AMDGCN %s
 // RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -o - | FileCheck 
--check-prefixes=CHECK,AMDGCN %s
diff --git a/clang/test/CodeGenOpenCL/builtins-alloca.cl 
b/clang/test/CodeGenOpenCL/builtins-alloca.cl
index ce7da3aba9e45..51da8e3b3badb 100644
--- a/clang/test/CodeGenOpenCL/builtins-alloca.cl
+++ b/clang/test/CodeGenOpenCL/builtins-alloca.cl
@@ -3,9 +3,9 @@
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL12 %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL2.0 \
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL20 %s
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 \
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-mesa3d -target-cpu gfx600 
-cl-std=CL3.0 \
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL30 %s
-// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 
-cl-ext=+__opencl_c_generic_address_space \
+// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 \
 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL30GAS %s
 
 // OPENCL-LABEL: define dso_local void @test1_builtin_alloca(
diff --git a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl 
b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
index 57ea891b3eb29..08715fc5a1f4a 100644
--- a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
+++ b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
@@ -11,6 +11,9 @@
 // RUN: %clang_cc1 -x cl -cl-std=CL3.0

[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Nikita Popov via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);

nikic wrote:

We should avoid inserting function declarations that are not going to be used. 
I think this late we'll end up actually emitting those symbols.

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Nikita Popov via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);
+
+  auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
+  return B.CreateCall(SignIntr, {Val, B.getInt32(2), Disc}, DSBundle);

nikic wrote:

What's the magic number 2 here?

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Nikita Popov via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);
+
+  auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))

nikic wrote:

Hm... what about the case where some of the llvm.protected.field.ptr uses are 
in `+pauth` functions and some in `-pauth` functions? Aren't we going to end up 
using an inconsistent encoding in that case?

I think that this needs to be an ABI decision, not a target-feature decision.

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Add llvm.protected.field.ptr intrinsic and pre-ISel lowering. (PR #151647)

2025-12-02 Thread Nikita Popov via llvm-branch-commits


@@ -461,6 +463,139 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
   return Changed;
 }
 
+static bool expandProtectedFieldPtr(Function &Intr) {
+  Module &M = *Intr.getParent();
+
+  SmallPtrSet DSsToDeactivate;
+
+  Type *Int8Ty = Type::getInt8Ty(M.getContext());
+  Type *Int64Ty = Type::getInt64Ty(M.getContext());
+  PointerType *PtrTy = PointerType::get(M.getContext(), 0);
+
+  Function *SignIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
+  Function *AuthIntr =
+  Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
+
+  auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
+  FunctionCallee EmuSignIntr = M.getOrInsertFunction("__emupac_pacda", 
EmuFnTy);
+  FunctionCallee EmuAuthIntr = M.getOrInsertFunction("__emupac_autda", 
EmuFnTy);
+
+  auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
+  return B.CreateCall(SignIntr, {Val, B.getInt32(2), Disc}, DSBundle);
+return B.CreateCall(EmuSignIntr, {Val, Disc}, DSBundle);
+  };
+
+  auto CreateAuth = [&](IRBuilder<> &B, Value *Val, Value *Disc,
+OperandBundleDef DSBundle) {
+Function *F = B.GetInsertBlock()->getParent();
+Attribute FSAttr = F->getFnAttribute("target-features");
+if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
+  return B.CreateCall(AuthIntr, {Val, B.getInt32(2), Disc}, DSBundle);
+return B.CreateCall(EmuAuthIntr, {Val, Disc}, DSBundle);
+  };
+
+  auto GetDeactivationSymbol = [&](CallInst *Call) -> GlobalValue * {
+if (auto Bundle =
+Call->getOperandBundle(LLVMContext::OB_deactivation_symbol))
+  return cast(Bundle->Inputs[0]);
+return nullptr;
+  };
+
+  for (User *U : llvm::make_early_inc_range(Intr.users())) {
+auto *Call = cast(U);
+
+auto *Pointer = Call->getArgOperand(0);
+auto *Disc = Call->getArgOperand(1);
+bool UseHWEncoding =
+cast(Call->getArgOperand(2))->getZExtValue();
+assert(UseHWEncoding && "software encoding currently unsupported");

nikic wrote:

Make this a reportFatalUsageError() instead. asserts should not be reachable.

https://github.com/llvm/llvm-project/pull/151647
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU] Add structural stall heuristic to scheduling strategies (PR #169617)

2025-12-02 Thread Austin Kerbow via llvm-branch-commits

https://github.com/kerbowa updated 
https://github.com/llvm/llvm-project/pull/169617

>From 305fb4fbfadccd26c39249a725e9e06bea8a9102 Mon Sep 17 00:00:00 2001
From: Austin Kerbow 
Date: Tue, 25 Nov 2025 22:18:19 -0800
Subject: [PATCH] [AMDGPU] Add structural stall heuristic to scheduling
 strategies

Implements a structural stall heuristic that considers both resource
hazards and latency constraints when selecting instructions from the
pending queue.

- Add getStructuralStallCycles() to GCNSchedStrategy that computes the
number of cycles an instruction must wait due to:
  - Resource conflicts on unbuffered resources (from the SchedModel)
  - Sequence-dependent hazards (from GCNHazardRecognizer)

- Add getHazardWaitStates() to GCNHazardRecognizer that returns the number
of wait states until all hazards for an instruction are resolved,
providing cycle-accurate hazard information for scheduling heuristics.
---
 .../Target/AMDGPU/AMDGPUMLSchedStrategy.cpp   | 72 +++
 .../lib/Target/AMDGPU/AMDGPUMLSchedStrategy.h |  3 +
 .../lib/Target/AMDGPU/GCNHazardRecognizer.cpp |  4 ++
 llvm/lib/Target/AMDGPU/GCNHazardRecognizer.h  |  6 ++
 llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp   | 35 +
 llvm/lib/Target/AMDGPU/GCNSchedStrategy.h |  8 ++-
 .../AMDGPU/ml-sched-effective-stall.mir   |  8 ++-
 7 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp
index 8c68223c0a492..08cf930de3178 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMLSchedStrategy.cpp
@@ -13,6 +13,10 @@
 
 #include "AMDGPUMLSchedStrategy.h"
 
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "machine-scheduler"
+
 using namespace llvm;
 
 AMDGPUMLSchedStrategy::AMDGPUMLSchedStrategy(const MachineSchedContext *C)
@@ -130,6 +134,74 @@ bool AMDGPUMLSchedStrategy::tryCandidate(SchedCandidate 
&Cand,
   return false;
 }
 
+bool AMDGPUMLSchedStrategy::tryPendingCandidate(SchedCandidate &Cand,
+SchedCandidate &TryCand,
+SchedBoundary *Zone) const {
+  // Initialize the candidate if needed.
+  if (!Cand.isValid()) {
+TryCand.Reason = NodeOrder;
+return true;
+  }
+
+  // Bias PhysReg Defs and copies to their uses and defined respectively.
+  if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
+ biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
+return TryCand.Reason != NoCand;
+
+  // Avoid exceeding the target's limit.
+  if (DAG->isTrackingPressure() &&
+  tryPressure(TryCand.RPDelta.Excess, Cand.RPDelta.Excess, TryCand, Cand,
+  RegExcess, TRI, DAG->MF))
+return TryCand.Reason != NoCand;
+
+  // Avoid increasing the max critical pressure in the scheduled region.
+  if (DAG->isTrackingPressure() &&
+  tryPressure(TryCand.RPDelta.CriticalMax, Cand.RPDelta.CriticalMax,
+  TryCand, Cand, RegCritical, TRI, DAG->MF))
+return TryCand.Reason != NoCand;
+
+  bool SameBoundary = Zone != nullptr;
+  if (SameBoundary) {
+// Compare effective stall cycles between candidates.
+// Effective stall = max(structural stall, latency stall)
+// - Structural stalls: resource/hazard constraints (HW not ready)
+// - Latency stalls: data dependency constraints (operands not ready)
+//
+// This allows picking a pending instruction with structural stalls over
+// an available instruction with higher latency stalls (e.g., scheduling
+// a WMMA while waiting for a memory load result).
+unsigned TryStructStall = getStructuralStallCycles(*Zone, TryCand.SU);
+unsigned TryLatencyStall = Zone->getLatencyStallCycles(TryCand.SU);
+unsigned TryEffectiveStall = std::max(TryStructStall, TryLatencyStall);
+
+unsigned CandStructStall = getStructuralStallCycles(*Zone, Cand.SU);
+unsigned CandLatencyStall = Zone->getLatencyStallCycles(Cand.SU);
+unsigned CandEffectiveStall = std::max(CandStructStall, CandLatencyStall);
+
+LLVM_DEBUG(if (TryEffectiveStall || CandEffectiveStall) {
+  dbgs() << "Effective stalls: try=" << TryEffectiveStall
+ << " (struct=" << TryStructStall << ", lat=" << TryLatencyStall
+ << ") cand=" << CandEffectiveStall
+ << " (struct=" << CandStructStall << ", lat=" << CandLatencyStall
+ << ")\n";
+});
+
+if (tryLess(TryEffectiveStall, CandEffectiveStall, TryCand, Cand, Stall))
+  return TryCand.Reason != NoCand;
+
+TryCand.initResourceDelta(DAG, SchedModel);
+if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
+TryCand, Cand, ResourceReduce))
+  return TryCand.Reason != NoCand;
+if (tryGreater(TryCand.ResDelta.DemandedResources,
+   Cand.ResDelta.DemandedResources, TryCand, Cand,
+   ResourceDemand))
+

  1   2   >