[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
https://github.com/usx95 updated
https://github.com/llvm/llvm-project/pull/159991
>From 8a7ec9fe4b3e098b629102219cf52a116472e9a2 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena
Date: Sun, 21 Sep 2025 16:30:28 +
Subject: [PATCH] liveness-based-lifetime-policy
---
.../clang/Analysis/Analyses/LifetimeSafety.h | 18 +-
clang/lib/Analysis/LifetimeSafety.cpp | 461 +---
.../test/Analysis/LifetimeSafety/benchmark.py | 82 ++-
clang/test/Sema/warn-lifetime-safety.cpp | 138 +++--
.../unittests/Analysis/LifetimeSafetyTest.cpp | 501 +-
5 files changed, 713 insertions(+), 487 deletions(-)
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76cd6349..6d3e3f61446e0 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -29,7 +29,7 @@
namespace clang::lifetimes {
/// Enum to track the confidence level of a potential error.
-enum class Confidence {
+enum class Confidence : uint8_t {
None,
Maybe, // Reported as a potential error (-Wlifetime-safety-strict)
Definite // Reported as a definite error (-Wlifetime-safety-permissive)
@@ -55,6 +55,7 @@ class Fact;
class FactManager;
class LoanPropagationAnalysis;
class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
struct LifetimeFactory;
/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +90,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
OriginID ID) {
// TODO(opt): Consider using a bitset to represent the set of loans.
using LoanSet = llvm::ImmutableSet;
using OriginSet = llvm::ImmutableSet;
+using OriginLoanMap = llvm::ImmutableMap;
/// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
/// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +112,16 @@ class LifetimeSafetyAnalysis {
/// Returns the set of loans an origin holds at a specific program point.
LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
- /// Returns the set of loans that have expired at a specific program point.
- std::vector getExpiredLoansAtPoint(ProgramPoint PP) const;
+ /// Returns the set of origins that are live at a specific program point,
+ /// along with the confidence level of their liveness.
+ ///
+ /// An origin is considered live if there are potential future uses of that
+ /// origin after the given program point. The confidence level indicates
+ /// whether the origin is definitely live (Definite) due to being domintated
+ /// by a set of uses or only possibly live (Maybe) only on some but not all
+ /// control flow paths.
+ std::vector>
+ getLiveOriginsAtPoint(ProgramPoint PP) const;
/// Finds the OriginID for a given declaration.
/// Returns a null optional if not found.
@@ -138,7 +148,7 @@ class LifetimeSafetyAnalysis {
std::unique_ptr Factory;
std::unique_ptr FactMgr;
std::unique_ptr LoanPropagation;
- std::unique_ptr ExpiredLoans;
+ std::unique_ptr LiveOrigins;
};
} // namespace internal
} // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp
b/clang/lib/Analysis/LifetimeSafety.cpp
index 14fb945382e65..7d880ea26833b 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -22,6 +22,7 @@
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
#include
#include
@@ -865,29 +866,30 @@ class DataflowAnalysis {
std::conditional_t;
Worklist W(Cfg, AC);
+llvm::SmallBitVector Seen(Cfg.getNumBlockIDs() + 1);
const CFGBlock *Start = isForward() ? &Cfg.getEntry() : &Cfg.getExit();
InStates[Start] = D.getInitialState();
+Seen.set(Start->getBlockID());
W.enqueueBlock(Start);
-llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
-
while (const CFGBlock *B = W.dequeue()) {
Lattice StateIn = getInState(B);
Lattice StateOut = transferBlock(B, StateIn);
OutStates[B] = StateOut;
- Visited.set(B->getBlockID());
for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
if (!AdjacentB)
continue;
Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+bool SeeingFirstTime = !Seen.test(AdjacentB->getBlockID());
+Lattice NewInState =
+SeeingFirstTime ? StateOut : D.join(OldInState, StateOut);
// Enqueue the adjacent block if its in-state has changed or if we have
-// never visited it.
-if (!Visited.test(AdjacentB->getBlockID()) ||
-NewInState != OldInState) {
+// never seen it.
+if (SeeingFirstTime || NewInState != OldInState) {
InStates[AdjacentB] = NewInState
[llvm-branch-commits] [llvm] [LV] Use VPReductionRecipe for partial reductions (PR #147513)
https://github.com/SamTebbs33 edited https://github.com/llvm/llvm-project/pull/147513 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/141665
>From 9e5d66ac23bd52eb56f959812426e4acaaa58a19 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
helpers
Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()
This patch is NFC aside from minor debug output changes.
---
bolt/lib/Passes/PAuthGadgetScanner.cpp| 67 +--
.../AArch64/gs-pauth-debug-output.s | 14 ++--
2 files changed, 38 insertions(+), 43 deletions(-)
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 192b1da27759e..cfc0bc2cfc0da 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
TrackedRegisters(ArrayRef RegsToTrack)
: Registers(RegsToTrack),
RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
- RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+ RegToIndexMapping[Reg] = MappedIndex;
}
ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
SafeToDerefRegs &= StateIn.SafeToDerefRegs;
TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
- for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+ ThisSet.insert_range(OtherSet);
return *this;
}
@@ -224,11 +224,9 @@ struct SrcState {
static void printInstsShort(raw_ostream &OS,
ArrayRef Insts) {
OS << "Insts: ";
- for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+ for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
- OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
OS << ")";
}
}
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
// ... an address can be updated in a safe manner, producing the result
// which is as trusted as the input address.
if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
- if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+ auto [DstReg, SrcReg] = *DstAndSrc;
+ if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
}
// Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
// ... an address can be updated in a safe manner, producing the result
// which is as trusted as the input address.
if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
- if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+ auto [DstReg, SrcReg] = *DstAndSrc;
+ if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
}
return Regs;
@@ -868,9 +868,9 @@ struct DstState {
return (*this = StateIn);
CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
- for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+ ThisSet.insert_range(OtherSet);
return *this;
}
@@ -1036,8 +1036,7 @@ class DstSafetyAnalysis {
// ... an address can be updated in a safe manner, or
if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
- MCPhysReg DstReg, SrcReg;
- std::tie(DstReg, SrcReg) = *DstAndSrc;
+ auto [DstReg, SrcReg] = *DstAndSrc;
// Note that *all* registers containing the derived values must be safe,
// both source and destination ones. No temporaries are supported at now.
if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1077,7 +1076,7 @@ class DstSafetyAnalysis {
// If this instruction terminates the program immediately, no
// authentication oracles are possible past this point.
if (BC.MIB->isTrap(Point)) {
- LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+ LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
Next.CannotEscapeUnchecked.set();
return Next;
@@ -1255,7 +1254,7 @@ class CFGUnawareDstSafetyAnalysis : public
DstSafetyAnalysis,
// starting to analyze Inst.
[llvm-branch-commits] [flang] [llvm] [openmp] [Flang] Add standalone tile support (PR #160298)
llvmbot wrote:
@llvm/pr-subscribers-flang-fir-hlfir
Author: Michael Kruse (Meinersbur)
Changes
Add support for the standalone OpenMP tile construct:
```f90
!$omp tile sizes(...)
DO i = 1, 100
...
```
This is complementary to #143715 which added support for the tile
construct as part of another loop-associated construct such as
worksharing-loop, distribute, etc.
PR Stack:
* #160283
* #159773
* #160292
* #160298 (this PR)
---
Patch is 50.41 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/160298.diff
25 Files Affected:
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+13)
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.h (+2)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+236-124)
- (modified) flang/lib/Lower/OpenMP/Utils.cpp (+20-4)
- (modified) flang/lib/Lower/OpenMP/Utils.h (+7)
- (modified) flang/lib/Semantics/check-directive-structure.h (+4-3)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+7-1)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+12-4)
- (added) flang/test/Lower/OpenMP/tile01.f90 (+58)
- (added) flang/test/Lower/OpenMP/tile02.f90 (+88)
- (modified) flang/test/Parser/OpenMP/loop-transformation-construct02.f90
(+3-2)
- (added) flang/test/Parser/OpenMP/tile-fail.f90 (+32)
- (modified) flang/test/Parser/OpenMP/tile.f90 (+10-5)
- (added) flang/test/Semantics/OpenMP/tile01.f90 (+26)
- (added) flang/test/Semantics/OpenMP/tile02.f90 (+15)
- (added) flang/test/Semantics/OpenMP/tile03.f90 (+15)
- (added) flang/test/Semantics/OpenMP/tile04.f90 (+38)
- (added) flang/test/Semantics/OpenMP/tile05.f90 (+14)
- (added) flang/test/Semantics/OpenMP/tile06.f90 (+44)
- (added) flang/test/Semantics/OpenMP/tile07.f90 (+35)
- (added) flang/test/Semantics/OpenMP/tile08.f90 (+15)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+3)
- (added) openmp/runtime/test/transform/tile/intfor.f90 (+31)
- (added) openmp/runtime/test/transform/tile/intfor_2d.f90 (+53)
- (added) openmp/runtime/test/transform/tile/intfor_2d_varsizes.F90 (+60)
``diff
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index a96884f5680ba..55eda7e3404c1 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -431,6 +431,19 @@ bool ClauseProcessor::processNumTasks(
return false;
}
+bool ClauseProcessor::processSizes(StatementContext &stmtCtx,
+ mlir::omp::SizesClauseOps &result) const {
+ if (auto *clause = findUniqueClause()) {
+result.sizes.reserve(clause->v.size());
+for (const ExprTy &vv : clause->v)
+ result.sizes.push_back(fir::getBase(converter.genExprValue(vv,
stmtCtx)));
+
+return true;
+ }
+
+ return false;
+}
+
bool ClauseProcessor::processNumTeams(
lower::StatementContext &stmtCtx,
mlir::omp::NumTeamsClauseOps &result) const {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h
b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 324ea3c1047a5..9e352fa574a97 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -66,6 +66,8 @@ class ClauseProcessor {
mlir::omp::LoopRelatedClauseOps &loopResult,
mlir::omp::CollapseClauseOps &collapseResult,
llvm::SmallVectorImpl &iv) const;
+ bool processSizes(StatementContext &stmtCtx,
+mlir::omp::SizesClauseOps &result) const;
bool processDevice(lower::StatementContext &stmtCtx,
mlir::omp::DeviceClauseOps &result) const;
bool processDeviceType(mlir::omp::DeviceTypeClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 5681be664d450..7812d9fe00be2 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1984,125 +1984,241 @@ genLoopOp(lower::AbstractConverter &converter,
lower::SymMap &symTable,
return loopOp;
}
-static mlir::omp::CanonicalLoopOp
-genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap
&symTable,
- semantics::SemanticsContext &semaCtx,
- lower::pft::Evaluation &eval, mlir::Location loc,
- const ConstructQueue &queue,
- ConstructQueue::const_iterator item,
- llvm::ArrayRef ivs,
- llvm::omp::Directive directive) {
+static void genCanonicalLoopNest(
+lower::AbstractConverter &converter, lower::SymMap &symTable,
+semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+mlir::Location loc, const ConstructQueue &queue,
+ConstructQueue::const_iterator item, size_t numLoops,
+llvm::SmallVectorImpl &loops) {
+ assert(loops.empty() && "Expecting empty list to fill");
+ assert(numLoops >= 1 && "Expecting at least one loop");
+
fir::FirOpBuilder &firOpBuilder = converter.getFirOp
[llvm-branch-commits] [flang] [llvm] [openmp] [Flang] Add standalone tile support (PR #160298)
https://github.com/Meinersbur ready_for_review https://github.com/llvm/llvm-project/pull/160298 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AllocToken, Clang] Implement __builtin_infer_alloc_token() and llvm.alloc.token.id (PR #156842)
zmodem wrote: > for `__builtin_infer_allocation_token` that won't work, because then we have > to pull out all the token calculation logic in a way that Clang can access > it. And some of that depends on configuration specific to the LLVM IR pass, > that is not yet known. Not sure if there's a clean way other than somehow > creating an API that can be used to do the token calculation that can be > shared between Clang and IR pass. Separating the instrumentation pass and the token generation might be a good idea though? The pass could focus on IR manipulation, and there could be a separate utility for token generation. I agree that it would make sense if this were constant evaluate-able since it is a compile time constant in the end, but I don't know whether there are actually important use cases for this. https://github.com/llvm/llvm-project/pull/156842 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
@@ -1118,109 +1119,189 @@ class LoanPropagationAnalysis
OriginLoanMapFactory.add(In.Origins, DestOID, MergedLoans));
}
- LoanSet getLoans(OriginID OID, ProgramPoint P) {
+ LoanSet getLoans(OriginID OID, ProgramPoint P) const {
return getLoans(getState(P), OID);
}
private:
- LoanSet getLoans(Lattice L, OriginID OID) {
+ LoanSet getLoans(Lattice L, OriginID OID) const {
if (auto *Loans = L.Origins.lookup(OID))
return *Loans;
return LoanSetFactory.getEmptySet();
}
};
// = //
-// Expired Loans Analysis
+// Live Origins Analysis
// = //
-/// The dataflow lattice for tracking the set of expired loans.
-struct ExpiredLattice {
- /// Map from an expired `LoanID` to the `ExpireFact` that made it expire.
- ExpiredLoanMap Expired;
+/// Information about why an origin is live at a program point.
+struct LivenessInfo {
+ /// The use that makes the origin live. If liveness is propagated from
+ /// multiple uses along different paths, this will point to the use appearing
+ /// before in the translation unit.
+ const UseFact *CausingUseFact;
+ /// The confidence in the liveness of the origin.
+ /// `Definite`: The origin is live on all control-flow paths from the current
+ /// point to the function's exit (i.e. the current point is dominated by a
set
+ /// of uses).
+ /// `Maybe`: indicates it is live on some but not all paths.
+ Confidence ConfidenceLevel;
+
+ LivenessInfo() : CausingUseFact(nullptr), ConfidenceLevel(Confidence::None)
{}
+ LivenessInfo(const UseFact *UF, Confidence C)
+ : CausingUseFact(UF), ConfidenceLevel(C) {}
+
+ bool operator==(const LivenessInfo &Other) const {
+return CausingUseFact == Other.CausingUseFact &&
+ ConfidenceLevel == Other.ConfidenceLevel;
+ }
+ bool operator!=(const LivenessInfo &Other) const { return !(*this == Other);
}
+
+ void Profile(llvm::FoldingSetNodeID &IDBuilder) const {
+IDBuilder.AddPointer(CausingUseFact);
+IDBuilder.Add(ConfidenceLevel);
+ }
+};
+
+using LivenessMap = llvm::ImmutableMap;
+
+/// The dataflow lattice for origin liveness analysis.
+/// It tracks which origins are live, why they're live (which UseFact),
+/// and the confidence level of that liveness.
+struct LivenessLattice {
+ LivenessMap LiveOrigins;
+
+ LivenessLattice() : LiveOrigins(nullptr) {};
- ExpiredLattice() : Expired(nullptr) {};
- explicit ExpiredLattice(ExpiredLoanMap M) : Expired(M) {}
+ explicit LivenessLattice(LivenessMap L) : LiveOrigins(L) {}
- bool operator==(const ExpiredLattice &Other) const {
-return Expired == Other.Expired;
+ bool operator==(const LivenessLattice &Other) const {
+return LiveOrigins == Other.LiveOrigins;
}
- bool operator!=(const ExpiredLattice &Other) const {
+
+ bool operator!=(const LivenessLattice &Other) const {
return !(*this == Other);
}
- void dump(llvm::raw_ostream &OS) const {
-OS << "ExpiredLattice State:\n";
-if (Expired.isEmpty())
+ void dump(llvm::raw_ostream &OS, const OriginManager &OM) const {
+if (LiveOrigins.isEmpty())
OS << " \n";
-for (const auto &[ID, _] : Expired)
- OS << " Loan " << ID << " is expired\n";
+for (const auto &Entry : LiveOrigins) {
+ OriginID OID = Entry.first;
+ const LivenessInfo &Info = Entry.second;
+ OS << " ";
+ OM.dump(OID, OS);
+ OS << " is ";
+ switch (Info.ConfidenceLevel) {
+ case Confidence::Definite:
+OS << "definitely";
+break;
+ case Confidence::Maybe:
+OS << "maybe";
+break;
+ case Confidence::None:
+llvm_unreachable("liveness condidence should not be none.");
+ }
+ OS << " live at this point\n";
+}
}
};
-/// The analysis that tracks which loans have expired.
-class ExpiredLoansAnalysis
-: public DataflowAnalysis {
-
- ExpiredLoanMap::Factory &Factory;
+/// The analysis that tracks which origins are live, with granular information
+/// about the causing use fact and confidence level. This is a backward
+/// analysis.
+class LiveOriginAnalysis
+: public DataflowAnalysis {
+ FactManager &FactMgr;
+ LivenessMap::Factory &Factory;
public:
- ExpiredLoansAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
- LifetimeFactory &Factory)
- : DataflowAnalysis(C, AC, F), Factory(Factory.ExpiredLoanMapFactory) {}
-
- using Base::transfer;
+ LiveOriginAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
+ LivenessMap::Factory &SF)
+ : DataflowAnalysis(C, AC, F), FactMgr(F), Factory(SF) {}
+ using DataflowAnalysis::transfer;
- StringRef getAnalysisName() const { return "ExpiredLoans"; }
+ StringRef getAnalysisName() const { return "LiveOrigins"; }
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
@@ -873,19 +874,26 @@ class DataflowAnalysis {
llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
while (const CFGBlock *B = W.dequeue()) {
- Lattice StateIn = getInState(B);
+ Lattice StateIn = *getInState(B);
Lattice StateOut = transferBlock(B, StateIn);
OutStates[B] = StateOut;
- Visited.set(B->getBlockID());
for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
if (!AdjacentB)
continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
usx95 wrote:
Reverted to original behaviour of `getInState` and used a separate bit vector
to track visitations.
https://github.com/llvm/llvm-project/pull/159991
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/159991 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Use initializer list for recoloring candidates (NFC) (PR #160486)
https://github.com/lukel97 approved this pull request. https://github.com/llvm/llvm-project/pull/160486 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Use initializer list for recoloring candidates (NFC) (PR #160486)
arsenm wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/160486?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#160486** https://app.graphite.dev/github/pr/llvm/llvm-project/160486?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/160486?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#160485** https://app.graphite.dev/github/pr/llvm/llvm-project/160485?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#160484** https://app.graphite.dev/github/pr/llvm/llvm-project/160484?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#160424** https://app.graphite.dev/github/pr/llvm/llvm-project/160424?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/>: 1 other dependent PR ([#160467](https://github.com/llvm/llvm-project/pull/160467) https://app.graphite.dev/github/pr/llvm/llvm-project/160467?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/>) * **#160294** https://app.graphite.dev/github/pr/llvm/llvm-project/160294?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/160486 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Move physreg check when trying to recolor vregs (NFC) (PR #160484)
https://github.com/lukel97 approved this pull request. https://github.com/llvm/llvm-project/pull/160484 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Use initializer list for recoloring candidates (NFC) (PR #160486)
https://github.com/arsenm ready_for_review https://github.com/llvm/llvm-project/pull/160486 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Use initializer list for recoloring candidates (NFC) (PR #160486)
llvmbot wrote:
@llvm/pr-subscribers-backend-x86
Author: Matt Arsenault (arsenm)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/160486.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/RegAllocGreedy.cpp (+2-4)
``diff
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp
b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 6957548ac6c7a..bb8ebe7d7ddf1 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2486,15 +2486,13 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
// We have a broken hint, check if it is possible to fix it by
// reusing PhysReg for the copy-related live-ranges. Indeed, we evicted
// some register and PhysReg may be available for the other live-ranges.
- SmallSet Visited;
- SmallVector RecoloringCandidates;
HintsInfo Info;
Register Reg = VirtReg.reg();
MCRegister PhysReg = VRM->getPhys(Reg);
// Start the recoloring algorithm from the input live-interval, then
// it will propagate to the ones that are copy-related with it.
- Visited.insert(Reg);
- RecoloringCandidates.push_back(Reg);
+ SmallSet Visited = {Reg};
+ SmallVector RecoloringCandidates = {Reg};
LLVM_DEBUG(dbgs() << "Trying to reconcile hints for: " << printReg(Reg, TRI)
<< '(' << printReg(PhysReg, TRI) << ")\n");
``
https://github.com/llvm/llvm-project/pull/160486
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/139778
>From 8dc0489843c88abe4749f3e29775cea04050d925 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: optionally assume auth traps on
failure
On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.
This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
.../binary-analysis/AArch64/cmdline-args.test | 1 +
.../AArch64/gs-pauth-authentication-oracles.s | 6 +-
.../binary-analysis/AArch64/gs-pauth-calls.s | 5 +-
.../AArch64/gs-pauth-debug-output.s | 177 ++---
.../AArch64/gs-pauth-jump-table.s | 6 +-
.../AArch64/gs-pauth-signing-oracles.s| 54 ++---
.../AArch64/gs-pauth-tail-calls.s | 184 +-
8 files changed, 318 insertions(+), 227 deletions(-)
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 3a6c3e3d925cf..4fc0bf2ae54a9 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
#include "bolt/Passes/PAuthGadgetScanner.h"
#include "bolt/Core/ParallelUtilities.h"
#include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
namespace bolt {
namespace PAuthGadgetScanner {
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
[[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef
Label,
const MCInst &MI) {
dbgs() << " " << Label << ": ";
@@ -364,6 +370,34 @@ class SrcSafetyAnalysis {
return Clobbered;
}
+ std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+ SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+ return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+ return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+ return std::nullopt;
+
+return RegCheckedBySequence;
+ }
+
// Returns all registers that can be treated as if they are written by an
// authentication instruction.
SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -386,18 +420,38 @@ class SrcSafetyAnalysis {
Regs.push_back(DstAndSrc->first);
}
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov x16, x30 ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp x30, x16
+//b.eq 1f; end of the sequence: LR is marked as trusted
+//brk 0x1234
+// 1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+ Regs.push_back(*CheckedReg);
+
return Regs;
}
// Returns all registers made trusted by this instruction.
SmallVector getRegsMadeTrusted(const MCInst &Point,
const SrcState &Cur) const {
+assert(!AuthTrapsOnFailur
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138884
>From 5c1edeb727636b1dcbf6573dd4d3f9d14abd8799 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
tables
As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.
This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).
For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
bolt/include/bolt/Core/MCInstUtils.h | 9 +
bolt/include/bolt/Core/MCPlusBuilder.h| 14 +
bolt/lib/Core/MCInstUtils.cpp | 20 +
bolt/lib/Passes/PAuthGadgetScanner.cpp| 10 +
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 73 ++
.../AArch64/gs-pauth-jump-table.s | 703 ++
6 files changed, 829 insertions(+)
create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s
diff --git a/bolt/include/bolt/Core/MCInstUtils.h
b/bolt/include/bolt/Core/MCInstUtils.h
index 2436e1359f40e..2df2054712457 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -142,6 +142,15 @@ class MCInstReference {
return nullptr;
}
+ /// Returns the only preceding instruction, or std::nullopt if multiple or no
+ /// predecessors are possible.
+ ///
+ /// If CFG information is available, basic block boundary can be crossed,
+ /// provided there is exactly one predecessor. If CFG is not available, the
+ /// preceding instruction in the offset order is returned, unless this is the
+ /// first instruction of the function.
+ std::optional getSinglePredecessor();
+
raw_ostream &print(raw_ostream &OS) const;
};
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h
b/bolt/include/bolt/Core/MCPlusBuilder.h
index ae04891e791f9..f13e41c75c2ac 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
#ifndef BOLT_CORE_MCPLUSBUILDER_H
#define BOLT_CORE_MCPLUSBUILDER_H
+#include "bolt/Core/MCInstUtils.h"
#include "bolt/Core/MCPlus.h"
#include "bolt/Core/Relocation.h"
#include "llvm/ADT/ArrayRef.h"
@@ -711,6 +712,19 @@ class MCPlusBuilder {
return std::nullopt;
}
+ /// Tests if BranchInst corresponds to an instruction sequence which is known
+ /// to be a safe dispatch via jump table.
+ ///
+ /// The target can decide which instruction sequences to consider "safe" from
+ /// the Pointer Authentication point of view, such as any jump table dispatch
+ /// sequence without function calls inside, any sequence which is contiguous,
+ /// or only some specific well-known sequences.
+ virtual bool
+ isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+ }
+
virtual bool isTerminator(const MCInst &Inst) const;
virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 3cdb9673d4dc0..39bc96f087f8e 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -54,3 +54,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
OS << ">";
return OS;
}
+
+std::optional MCInstReference::getSinglePredecessor() {
+ if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+ return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+ return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+ }
+
+ const RefInBF &Ref = getRefInBF();
+ if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+ return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 5d884e2d37354..3a6c3e3d925cf 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1370,6 +1370,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC,
const BinaryFunction &BF,
return std::nullopt;
}
+ if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/141665
>From 9e5d66ac23bd52eb56f959812426e4acaaa58a19 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
helpers
Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()
This patch is NFC aside from minor debug output changes.
---
bolt/lib/Passes/PAuthGadgetScanner.cpp| 67 +--
.../AArch64/gs-pauth-debug-output.s | 14 ++--
2 files changed, 38 insertions(+), 43 deletions(-)
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 192b1da27759e..cfc0bc2cfc0da 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
TrackedRegisters(ArrayRef RegsToTrack)
: Registers(RegsToTrack),
RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
- RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+ RegToIndexMapping[Reg] = MappedIndex;
}
ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
SafeToDerefRegs &= StateIn.SafeToDerefRegs;
TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
- for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+ ThisSet.insert_range(OtherSet);
return *this;
}
@@ -224,11 +224,9 @@ struct SrcState {
static void printInstsShort(raw_ostream &OS,
ArrayRef Insts) {
OS << "Insts: ";
- for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+ for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
- OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
OS << ")";
}
}
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
// ... an address can be updated in a safe manner, producing the result
// which is as trusted as the input address.
if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
- if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+ auto [DstReg, SrcReg] = *DstAndSrc;
+ if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
}
// Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
// ... an address can be updated in a safe manner, producing the result
// which is as trusted as the input address.
if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
- if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+ auto [DstReg, SrcReg] = *DstAndSrc;
+ if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
}
return Regs;
@@ -868,9 +868,9 @@ struct DstState {
return (*this = StateIn);
CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
- for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+ ThisSet.insert_range(OtherSet);
return *this;
}
@@ -1036,8 +1036,7 @@ class DstSafetyAnalysis {
// ... an address can be updated in a safe manner, or
if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
- MCPhysReg DstReg, SrcReg;
- std::tie(DstReg, SrcReg) = *DstAndSrc;
+ auto [DstReg, SrcReg] = *DstAndSrc;
// Note that *all* registers containing the derived values must be safe,
// both source and destination ones. No temporaries are supported at now.
if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1077,7 +1076,7 @@ class DstSafetyAnalysis {
// If this instruction terminates the program immediately, no
// authentication oracles are possible past this point.
if (BC.MIB->isTrap(Point)) {
- LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+ LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
Next.CannotEscapeUnchecked.set();
return Next;
@@ -1255,7 +1254,7 @@ class CFGUnawareDstSafetyAnalysis : public
DstSafetyAnalysis,
// starting to analyze Inst.
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
@@ -1118,109 +1119,189 @@ class LoanPropagationAnalysis
OriginLoanMapFactory.add(In.Origins, DestOID, MergedLoans));
}
- LoanSet getLoans(OriginID OID, ProgramPoint P) {
+ LoanSet getLoans(OriginID OID, ProgramPoint P) const {
return getLoans(getState(P), OID);
}
private:
- LoanSet getLoans(Lattice L, OriginID OID) {
+ LoanSet getLoans(Lattice L, OriginID OID) const {
if (auto *Loans = L.Origins.lookup(OID))
return *Loans;
return LoanSetFactory.getEmptySet();
}
};
// = //
-// Expired Loans Analysis
+// Live Origins Analysis
// = //
-/// The dataflow lattice for tracking the set of expired loans.
-struct ExpiredLattice {
- /// Map from an expired `LoanID` to the `ExpireFact` that made it expire.
- ExpiredLoanMap Expired;
+/// Information about why an origin is live at a program point.
+struct LivenessInfo {
+ /// The use that makes the origin live. If liveness is propagated from
+ /// multiple uses along different paths, this will point to the use appearing
+ /// before in the translation unit.
+ const UseFact *CausingUseFact;
+ /// The confidence in the liveness of the origin.
+ /// `Definite`: The origin is live on all control-flow paths from the current
+ /// point to the function's exit (i.e. the current point is dominated by a
set
+ /// of uses).
+ /// `Maybe`: indicates it is live on some but not all paths.
+ Confidence ConfidenceLevel;
+
+ LivenessInfo() : CausingUseFact(nullptr), ConfidenceLevel(Confidence::None)
{}
+ LivenessInfo(const UseFact *UF, Confidence C)
+ : CausingUseFact(UF), ConfidenceLevel(C) {}
+
+ bool operator==(const LivenessInfo &Other) const {
+return CausingUseFact == Other.CausingUseFact &&
+ ConfidenceLevel == Other.ConfidenceLevel;
+ }
+ bool operator!=(const LivenessInfo &Other) const { return !(*this == Other);
}
+
+ void Profile(llvm::FoldingSetNodeID &IDBuilder) const {
+IDBuilder.AddPointer(CausingUseFact);
+IDBuilder.Add(ConfidenceLevel);
+ }
+};
+
+using LivenessMap = llvm::ImmutableMap;
+
+/// The dataflow lattice for origin liveness analysis.
+/// It tracks which origins are live, why they're live (which UseFact),
+/// and the confidence level of that liveness.
+struct LivenessLattice {
+ LivenessMap LiveOrigins;
+
+ LivenessLattice() : LiveOrigins(nullptr) {};
- ExpiredLattice() : Expired(nullptr) {};
- explicit ExpiredLattice(ExpiredLoanMap M) : Expired(M) {}
+ explicit LivenessLattice(LivenessMap L) : LiveOrigins(L) {}
- bool operator==(const ExpiredLattice &Other) const {
-return Expired == Other.Expired;
+ bool operator==(const LivenessLattice &Other) const {
+return LiveOrigins == Other.LiveOrigins;
}
- bool operator!=(const ExpiredLattice &Other) const {
+
+ bool operator!=(const LivenessLattice &Other) const {
return !(*this == Other);
}
- void dump(llvm::raw_ostream &OS) const {
-OS << "ExpiredLattice State:\n";
-if (Expired.isEmpty())
+ void dump(llvm::raw_ostream &OS, const OriginManager &OM) const {
+if (LiveOrigins.isEmpty())
OS << " \n";
-for (const auto &[ID, _] : Expired)
- OS << " Loan " << ID << " is expired\n";
+for (const auto &Entry : LiveOrigins) {
+ OriginID OID = Entry.first;
+ const LivenessInfo &Info = Entry.second;
+ OS << " ";
+ OM.dump(OID, OS);
+ OS << " is ";
+ switch (Info.ConfidenceLevel) {
+ case Confidence::Definite:
+OS << "definitely";
+break;
+ case Confidence::Maybe:
+OS << "maybe";
+break;
+ case Confidence::None:
+llvm_unreachable("liveness condidence should not be none.");
+ }
+ OS << " live at this point\n";
+}
}
};
-/// The analysis that tracks which loans have expired.
-class ExpiredLoansAnalysis
-: public DataflowAnalysis {
-
- ExpiredLoanMap::Factory &Factory;
+/// The analysis that tracks which origins are live, with granular information
+/// about the causing use fact and confidence level. This is a backward
+/// analysis.
+class LiveOriginAnalysis
+: public DataflowAnalysis {
+ FactManager &FactMgr;
+ LivenessMap::Factory &Factory;
public:
- ExpiredLoansAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
- LifetimeFactory &Factory)
- : DataflowAnalysis(C, AC, F), Factory(Factory.ExpiredLoanMapFactory) {}
-
- using Base::transfer;
+ LiveOriginAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
+ LivenessMap::Factory &SF)
+ : DataflowAnalysis(C, AC, F), FactMgr(F), Factory(SF) {}
+ using DataflowAnalysis::transfer;
- StringRef getAnalysisName() const { return "ExpiredLoans"; }
+ StringRef getAnalysisName() const { return "LiveOrigins"; }
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
@@ -873,19 +874,26 @@ class DataflowAnalysis {
llvm::SmallBitVector Visited(Cfg.getNumBlockIDs() + 1);
while (const CFGBlock *B = W.dequeue()) {
- Lattice StateIn = getInState(B);
+ Lattice StateIn = *getInState(B);
Lattice StateOut = transferBlock(B, StateIn);
OutStates[B] = StateOut;
- Visited.set(B->getBlockID());
for (const CFGBlock *AdjacentB : isForward() ? B->succs() : B->preds()) {
if (!AdjacentB)
continue;
-Lattice OldInState = getInState(AdjacentB);
-Lattice NewInState = D.join(OldInState, StateOut);
+Lattice OldInState;
+bool SawFirstTime = false;
+Lattice NewInState;
+if (const Lattice *In = getInState(AdjacentB)) {
Xazax-hun wrote:
Wouldn't it be simpler if `getInState` always returned a valid state? Just
defaulted to `D.getInitialState` when the lookup fail.
https://github.com/llvm/llvm-project/pull/159991
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
@@ -1085,11 +1080,17 @@ class LoanPropagationAnalysis
/// Merges two lattices by taking the union of loans for each origin.
// TODO(opt): Keep the state small by removing origins which become dead.
Lattice join(Lattice A, Lattice B) {
-OriginLoanMap JoinedOrigins =
-utils::join(A.Origins, B.Origins, OriginLoanMapFactory,
-[&](LoanSet S1, LoanSet S2) {
- return utils::join(S1, S2, LoanSetFactory);
-});
+OriginLoanMap JoinedOrigins = utils::join(
+A.Origins, B.Origins, OriginLoanMapFactory,
+[&](const LoanSet *S1, const LoanSet *S2) {
+ assert((S1 || S2) && "unexpectedly merging 2 empty sets");
+ if (!S1)
+return *S2;
+ if (!S2)
+return *S1;
+ return utils::join(*S1, *S2, LoanSetFactory);
+},
+/*JoinAllKeys=*/false);
Xazax-hun wrote:
Could you elaborate on why do we not want to join all the keys?
https://github.com/llvm/llvm-project/pull/159991
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [LoongArch] Override cost hooks to expose more DAG combine opportunities (PR #157824)
https://github.com/zhaoqi5 edited https://github.com/llvm/llvm-project/pull/157824 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Merge VirtRegMap queries into one use (NFC) (PR #160485)
https://github.com/arsenm created
https://github.com/llvm/llvm-project/pull/160485
None
>From 549ba6c5469304a2949e2a1482f2a18a42ee1d54 Mon Sep 17 00:00:00 2001
From: Matt Arsenault
Date: Wed, 24 Sep 2025 19:06:39 +0900
Subject: [PATCH] Greedy: Merge VirtRegMap queries into one use (NFC)
---
llvm/lib/CodeGen/RegAllocGreedy.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp
b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index dc23ab3ce9d2b..6957548ac6c7a 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2502,8 +2502,10 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
do {
Reg = RecoloringCandidates.pop_back_val();
+MCRegister CurrPhys = VRM->getPhys(Reg);
+
// This may be a skipped register.
-if (!VRM->hasPhys(Reg)) {
+if (!CurrPhys) {
assert(!shouldAllocateRegister(Reg) &&
"We have an unallocated variable which should have been handled");
continue;
@@ -2512,7 +2514,6 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
// Get the live interval mapped with this virtual register to be able
// to check for the interference with the new color.
LiveInterval &LI = LIS->getInterval(Reg);
-MCRegister CurrPhys = VRM->getPhys(Reg);
// Check that the new color matches the register class constraints and
// that it is free for this live range.
if (CurrPhys != PhysReg && (!MRI->getRegClass(Reg)->contains(PhysReg) ||
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Move physreg check when trying to recolor vregs (NFC) (PR #160484)
llvmbot wrote:
@llvm/pr-subscribers-backend-systemz
Author: Matt Arsenault (arsenm)
Changes
Instead of checking if the recoloring candidate is a virtual register,
avoid adding it to the candidates in the first place.
---
Full diff: https://github.com/llvm/llvm-project/pull/160484.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/RegAllocGreedy.cpp (+2-5)
``diff
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp
b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 6e0585b2e9e55..dc23ab3ce9d2b 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2502,10 +2502,6 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
do {
Reg = RecoloringCandidates.pop_back_val();
-// We cannot recolor physical register.
-if (Reg.isPhysical())
- continue;
-
// This may be a skipped register.
if (!VRM->hasPhys(Reg)) {
assert(!shouldAllocateRegister(Reg) &&
@@ -2553,7 +2549,8 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
// Push all copy-related live-ranges to keep reconciling the broken
// hints.
for (const HintInfo &HI : Info) {
- if (Visited.insert(HI.Reg).second)
+ // We cannot recolor physical register.
+ if (HI.Reg.isVirtual() && Visited.insert(HI.Reg).second)
RecoloringCandidates.push_back(HI.Reg);
}
} while (!RecoloringCandidates.empty());
``
https://github.com/llvm/llvm-project/pull/160484
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Merge VirtRegMap queries into one use (NFC) (PR #160485)
https://github.com/arsenm ready_for_review https://github.com/llvm/llvm-project/pull/160485 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)
https://github.com/joaosaffran updated
https://github.com/llvm/llvm-project/pull/160210
>From 6b191d041990ad667d86b6b07eeed7c802e3fe45 Mon Sep 17 00:00:00 2001
From: Joao Saffran
Date: Mon, 22 Sep 2025 15:31:47 -0700
Subject: [PATCH 1/2] adding metadata static sampler flags
---
clang/test/CodeGenHLSL/RootSignature.hlsl | 4 +-
.../Frontend/HLSL/RootSignatureMetadata.cpp | 14 +-
...gnature-StaticSamplers-Invalid-AddressU.ll | 2 +-
...gnature-StaticSamplers-Invalid-AddressV.ll | 2 +-
...gnature-StaticSamplers-Invalid-AddressW.ll | 2 +-
...ture-StaticSamplers-Invalid-BorderColor.ll | 2 +-
...e-StaticSamplers-Invalid-ComparisonFunc.ll | 2 +-
...Signature-StaticSamplers-Invalid-Filter.ll | 2 +-
...re-StaticSamplers-Invalid-MaxAnisotropy.ll | 2 +-
...Signature-StaticSamplers-Invalid-MaxLod.ll | 2 +-
...Signature-StaticSamplers-Invalid-MinLod.ll | 2 +-
...ature-StaticSamplers-Invalid-MinLopBias.ll | 2 +-
...re-StaticSamplers-Invalid-RegisterSpace.ll | 2 +-
...e-StaticSamplers-Invalid-ShaderRegister.ll | 2 +-
...StaticSamplers-Invalid-ShaderVisibility.ll | 2 +-
.../RootSignature-StaticSamplers.ll | 2 +-
.../RootSignature-StaticSamplers_V3.ll| 43 +++
.../rootsignature-validation-fail-sampler.ll | 2 +-
...re-validation-fail-static-sampler-range.ll | 4 +-
19 files changed, 75 insertions(+), 20 deletions(-)
create mode 100644
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl
b/clang/test/CodeGenHLSL/RootSignature.hlsl
index bc40bdd79ce59..bbab6a73a3658 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -82,8 +82,8 @@ void RootDescriptorsEntry() {}
// checking minLOD, maxLOD
// CHECK-SAME: float -1.28e+02, float 1.28e+02,
-// checking register, space and visibility
-// CHECK-SAME: i32 42, i32 0, i32 0}
+// checking register, space, visibility and flags
+// CHECK-SAME: i32 42, i32 0, i32 0, i32 0}
#define SampleStaticSampler \
"StaticSampler(s42, " \
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..5ddf129265648 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const
StaticSampler &Sampler) {
ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
ConstantAsMetadata::get(
Builder.getInt32(to_underlying(Sampler.Visibility))),
+ ConstantAsMetadata::get(Builder.getInt32(0)),
};
return MDNode::get(Ctx, Operands);
}
@@ -411,7 +412,7 @@ Error
MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
MDNode *StaticSamplerNode) {
- if (StaticSamplerNode->getNumOperands() != 14)
+ if (StaticSamplerNode->getNumOperands() != 15)
return make_error("Static Sampler");
mcdxbc::StaticSampler Sampler;
@@ -495,6 +496,17 @@ Error
MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
return Error(std::move(E));
Sampler.ShaderVisibility = *Visibility;
+ if (RSD.Version < 3) {
+RSD.StaticSamplers.push_back(Sampler);
+return Error::success();
+ }
+ assert(RSD.Version >= 3);
+
+ if (std::optional Val = extractMdIntValue(StaticSamplerNode, 14))
+Sampler.Flags = *Val;
+ else
+return make_error("Static Sampler Flags");
+
RSD.StaticSamplers.push_back(Sampler);
return Error::success();
}
diff --git
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
index 288dea00b6e55..b043ea1418df6 100644
---
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
+++
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
@@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1"
"hlsl.shader"="compute" }
!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
-!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float
1.28e+02, i32 42, i32 0, i32 0 }
+!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float
1.28e+02, i32 42, i32 0, i32 0, i32 0 }
diff --git
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
index e9abcf966..8219ffdd679d2 100644
---
a/llvm/test/CodeGen/D
[llvm-branch-commits] [llvm] [profcheck][SimplifyCFG] Propagate !prof from `switch` to `select` (PR #159645)
https://github.com/mtrofin updated
https://github.com/llvm/llvm-project/pull/159645
>From 8027f039bd2b99e46420d27a6d468f7f269ded14 Mon Sep 17 00:00:00 2001
From: Mircea Trofin
Date: Mon, 15 Sep 2025 17:49:18 +
Subject: [PATCH] [profcheck][SimplifyCFG] Propagate !prof from `switch` to
`select`
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 86 ---
.../SimplifyCFG/switch-to-select-two-case.ll | 72 +---
2 files changed, 117 insertions(+), 41 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index a1f759dd1df83..f775991b5ba41 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -84,6 +84,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -6318,9 +6319,12 @@ static bool initializeUniqueCases(SwitchInst *SI,
PHINode *&PHI,
// Helper function that checks if it is possible to transform a switch with
only
// two cases (or two cases + default) that produces a result into a select.
// TODO: Handle switches with more than 2 cases that map to the same result.
+// The branch weights correspond to the provided Condition (i.e. if Condition
is
+// modified from the original SwitchInst, the caller must adjust the weights)
static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
Constant *DefaultResult, Value *Condition,
- IRBuilder<> &Builder, const DataLayout &DL) {
+ IRBuilder<> &Builder, const DataLayout &DL,
+ ArrayRef BranchWeights) {
// If we are selecting between only two cases transform into a simple
// select or a two-way select if default is possible.
// Example:
@@ -6329,6 +6333,10 @@ static Value *foldSwitchToSelect(const
SwitchCaseResultVectorTy &ResultVector,
// case 20: return 2; > %2 = icmp eq i32 %a, 20
// default: return 4; %3 = select i1 %2, i32 2, i32 %1
// }
+
+ const bool HasBranchWeights =
+ !BranchWeights.empty() && !ProfcheckDisableMetadataFixes;
+
if (ResultVector.size() == 2 && ResultVector[0].second.size() == 1 &&
ResultVector[1].second.size() == 1) {
ConstantInt *FirstCase = ResultVector[0].second[0];
@@ -6337,13 +6345,37 @@ static Value *foldSwitchToSelect(const
SwitchCaseResultVectorTy &ResultVector,
if (DefaultResult) {
Value *ValueCompare =
Builder.CreateICmpEQ(Condition, SecondCase, "switch.selectcmp");
- SelectValue = Builder.CreateSelect(ValueCompare, ResultVector[1].first,
- DefaultResult, "switch.select");
+ SelectInst *SelectValueInst = cast(Builder.CreateSelect(
+ ValueCompare, ResultVector[1].first, DefaultResult,
"switch.select"));
+ SelectValue = SelectValueInst;
+ if (HasBranchWeights) {
+// We start with 3 probabilities, where the numerator is the
+// corresponding BranchWeights[i], and the denominator is the sum over
+// BranchWeights. We want the probability and negative probability of
+// Condition == SecondCase.
+assert(BranchWeights.size() == 3);
+setBranchWeights(SelectValueInst, BranchWeights[2],
+ BranchWeights[0] + BranchWeights[1],
+ /*IsExpected=*/false);
+ }
}
Value *ValueCompare =
Builder.CreateICmpEQ(Condition, FirstCase, "switch.selectcmp");
-return Builder.CreateSelect(ValueCompare, ResultVector[0].first,
-SelectValue, "switch.select");
+SelectInst *Ret = cast(Builder.CreateSelect(
+ValueCompare, ResultVector[0].first, SelectValue, "switch.select"));
+if (HasBranchWeights) {
+ // We may have had a DefaultResult. Base the position of the first and
+ // second's branch weights accordingly. Also the proability that
Condition
+ // != FirstCase needs to take that into account.
+ assert(BranchWeights.size() >= 2);
+ size_t FirstCasePos = (Condition != nullptr);
+ size_t SecondCasePos = FirstCasePos + 1;
+ uint32_t DefaultCase = (Condition != nullptr) ? BranchWeights[0] : 0;
+ setBranchWeights(Ret, BranchWeights[FirstCasePos],
+ DefaultCase + BranchWeights[SecondCasePos],
+ /*IsExpected=*/false);
+}
+return Ret;
}
// Handle the degenerate case where two cases have the same result value.
@@ -6379,8 +6411,16 @@ static Value *foldSwitchToSelect(const
SwitchCaseResultVectorTy &ResultVector,
Value *And = Builder.CreateAnd(Condition, AndMask);
Value *Cmp = Builder.CreateICmpEQ(
And, Constant::getIntegerValue(And->getType(), AndMask));
- return Builder.CreateSelect(Cmp, ResultVector[0].first,
- DefaultResult);
+ Select
[llvm-branch-commits] [llvm] [profcheck][SimplifyCFG] Propagate !prof from `switch` to `select` (PR #159645)
mtrofin wrote: > In general this patch LGTM. > > I noticed that one downside of using `-profcheck-weights-for-test` is that > the original branch weights aren't in the test, so it's hard for me to > understand how this change modifies the branch weights. You're right. I think I'll just use `-profcheck-weights-for-test` "offline" to generate the .ll that is checked in. It's a convenience anyway - to avoid one having to write interesting profile metadata by hand in large tests. wdyt? https://github.com/llvm/llvm-project/pull/159645 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][omp] Improve canonloop/iv naming (PR #159773)
https://github.com/tblah edited https://github.com/llvm/llvm-project/pull/159773 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][omp] Improve canonloop/iv naming (PR #159773)
@@ -77,6 +77,177 @@ struct LLVMPointerPointerLikeModel
};
} // namespace
+/// Generate a name of a canonical loop nest of the format
+/// `(_s_r)*` that describes its nesting inside parent
+/// operations (`_r`) and that operation's region (`_s`). The region
+/// number is omitted if the parent operation has just one region. If a loop
+/// nest just consists of canonical loops nested inside each other, also uses
+/// `d` where is the nesting depth of the loop.
+static std::string generateLoopNestingName(StringRef prefix,
+ CanonicalLoopOp op) {
+ struct Component {
+// An region argument of an operation
+Operation *parentOp;
+size_t regionInOpIdx;
+bool isOnlyRegionInOp;
+bool skipRegion;
+
+// An operation somewhere in a parent region
+Operation *thisOp;
+Region *parentRegion;
+size_t opInRegionIdx;
+bool isOnlyOpInRegion;
+bool skipOp;
+int depth = -1;
+ };
+ SmallVector components;
+
+ // Gather a list of parent regions and operations, and the position within
+ // their parent
+ Operation *o = op.getOperation();
+ while (o) {
+if (o->hasTrait())
+ break;
+
+// Operation within a region
+Region *r = o->getParentRegion();
+if (!r)
+ break;
+
+llvm::ReversePostOrderTraversal
traversal(&r->getBlocks().front());
+size_t idx = 0;
+bool found = false;
+size_t sequentialIdx = -1;
+bool isOnlyLoop = true;
+for (Block *b : traversal) {
+ for (Operation &op : *b) {
+if (&op == o && !found) {
+ sequentialIdx = idx;
+ found = true;
+}
+if (op.getNumRegions()) {
+ idx += 1;
+ if (idx > 1)
+isOnlyLoop = false;
+}
+if (found && !isOnlyLoop)
+ break;
+ }
+}
+
+Component &comp = components.emplace_back();
+comp.thisOp = o;
+comp.parentRegion = r;
+comp.opInRegionIdx = sequentialIdx;
+comp.isOnlyOpInRegion = isOnlyLoop;
tblah wrote:
I think these names are a bit unclear.
An op containing regions doesn't mean that it is a loop. It could be an if
statement or an openmp block construct etc.
isOnlyOpInRegion == true doesn't mean there aren't other ops in the region; it
means that there aren't other ops containing regions in this region.
https://github.com/llvm/llvm-project/pull/159773
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][omp] Improve canonloop/iv naming (PR #159773)
@@ -77,6 +77,177 @@ struct LLVMPointerPointerLikeModel
};
} // namespace
+/// Generate a name of a canonical loop nest of the format
+/// `(_s_r)*` that describes its nesting inside parent
+/// operations (`_r`) and that operation's region (`_s`). The region
+/// number is omitted if the parent operation has just one region. If a loop
+/// nest just consists of canonical loops nested inside each other, also uses
+/// `d` where is the nesting depth of the loop.
+static std::string generateLoopNestingName(StringRef prefix,
+ CanonicalLoopOp op) {
+ struct Component {
+// An region argument of an operation
+Operation *parentOp;
+size_t regionInOpIdx;
+bool isOnlyRegionInOp;
+bool skipRegion;
+
+// An operation somewhere in a parent region
+Operation *thisOp;
+Region *parentRegion;
+size_t opInRegionIdx;
+bool isOnlyOpInRegion;
+bool skipOp;
+int depth = -1;
+ };
+ SmallVector components;
+
+ // Gather a list of parent regions and operations, and the position within
+ // their parent
+ Operation *o = op.getOperation();
+ while (o) {
+if (o->hasTrait())
+ break;
+
+// Operation within a region
+Region *r = o->getParentRegion();
+if (!r)
+ break;
+
+llvm::ReversePostOrderTraversal
traversal(&r->getBlocks().front());
+size_t idx = 0;
+bool found = false;
+size_t sequentialIdx = -1;
+bool isOnlyLoop = true;
+for (Block *b : traversal) {
+ for (Operation &op : *b) {
+if (&op == o && !found) {
+ sequentialIdx = idx;
+ found = true;
+}
+if (op.getNumRegions()) {
+ idx += 1;
+ if (idx > 1)
+isOnlyLoop = false;
+}
+if (found && !isOnlyLoop)
+ break;
+ }
+}
+
+Component &comp = components.emplace_back();
+comp.thisOp = o;
+comp.parentRegion = r;
+comp.opInRegionIdx = sequentialIdx;
+comp.isOnlyOpInRegion = isOnlyLoop;
+
+// Region argument of an operation
+Operation *parent = r->getParentOp();
+
+comp.parentOp = parent;
+comp.regionInOpIdx = 0;
+comp.isOnlyRegionInOp = true;
+if (parent && parent->getRegions().size() > 1) {
+ auto getRegionIndex = [](Operation *o, Region *r) {
+for (auto [idx, region] : llvm::enumerate(o->getRegions())) {
+ if (®ion == r)
+return idx;
+}
+llvm_unreachable("Region not child of its parent operation");
+ };
+ comp.regionInOpIdx = getRegionIndex(parent, r);
+ comp.isOnlyRegionInOp = false;
+}
+
+if (!parent)
+ break;
+
+// next parent
+o = parent;
+ }
+
+ // Reorder components from outermost to innermost
+ std::reverse(components.begin(), components.end());
tblah wrote:
Unsure if it is worth doing given I wouldn't expect components to ever be that
long, but the cost of this reversal could be avoided by just using backwards
iterators in the following loops (where needed).
https://github.com/llvm/llvm-project/pull/159773
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-remarkutil] Introduce summary tool (PR #160549)
@@ -0,0 +1,244 @@
+//===- RemarkSummary.cpp
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Specialized tool to summarize remarks
+//
+//===--===//
+
+#include "RemarkUtilHelpers.h"
+#include "RemarkUtilRegistry.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/WithColor.h"
+#include
+
+using namespace llvm;
+using namespace remarks;
+using namespace llvm::remarkutil;
+
+namespace summary {
+
+static cl::SubCommand
+SummarySub("summary", "Summarize Remarks using different strategies.");
+
+INPUT_FORMAT_COMMAND_LINE_OPTIONS(SummarySub)
+OUTPUT_FORMAT_COMMAND_LINE_OPTIONS(SummarySub)
+INPUT_OUTPUT_COMMAND_LINE_OPTIONS(SummarySub)
+
+static cl::OptionCategory SummaryStrategyCat("Strategy options");
+
+enum class KeepMode { None, Used, All };
+
+static cl::opt KeepInputOpt(
+"keep", cl::desc("Keep input remarks in output"), cl::init(KeepMode::None),
+cl::values(clEnumValN(KeepMode::None, "none",
+ "Don't keep input remarks (default)"),
+ clEnumValN(KeepMode::Used, "used",
+ "Keep only remarks used for summary"),
+ clEnumValN(KeepMode::All, "all", "Keep all input remarks")),
+cl::sub(SummarySub));
+
+static cl::opt
+IgnoreMalformedOpt("ignore-malformed",
+ cl::desc("Ignore remarks that fail to process"),
+ cl::init(false), cl::Hidden, cl::sub(SummarySub));
+
+// Use one cl::opt per Strategy, because future strategies might need to take
+// per-strategy parameters.
+static cl::opt EnableInlineSummaryOpt(
jroelofs wrote:
wdyt about making this a `cl::list>`? I think
that would nicely support repeated summaries, like an optimization pipeline of
sorts.
https://github.com/llvm/llvm-project/pull/160549
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-remarkutil] Introduce summary tool (PR #160549)
@@ -0,0 +1,244 @@
+//===- RemarkSummary.cpp
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Specialized tool to summarize remarks
+//
+//===--===//
+
+#include "RemarkUtilHelpers.h"
+#include "RemarkUtilRegistry.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/WithColor.h"
+#include
+
+using namespace llvm;
+using namespace remarks;
+using namespace llvm::remarkutil;
+
+namespace summary {
+
+static cl::SubCommand
+SummarySub("summary", "Summarize Remarks using different strategies.");
+
+INPUT_FORMAT_COMMAND_LINE_OPTIONS(SummarySub)
+OUTPUT_FORMAT_COMMAND_LINE_OPTIONS(SummarySub)
+INPUT_OUTPUT_COMMAND_LINE_OPTIONS(SummarySub)
+
+static cl::OptionCategory SummaryStrategyCat("Strategy options");
+
+enum class KeepMode { None, Used, All };
+
+static cl::opt KeepInputOpt(
+"keep", cl::desc("Keep input remarks in output"), cl::init(KeepMode::None),
+cl::values(clEnumValN(KeepMode::None, "none",
+ "Don't keep input remarks (default)"),
+ clEnumValN(KeepMode::Used, "used",
+ "Keep only remarks used for summary"),
+ clEnumValN(KeepMode::All, "all", "Keep all input remarks")),
+cl::sub(SummarySub));
+
+static cl::opt
+IgnoreMalformedOpt("ignore-malformed",
+ cl::desc("Ignore remarks that fail to process"),
+ cl::init(false), cl::Hidden, cl::sub(SummarySub));
+
+// Use one cl::opt per Strategy, because future strategies might need to take
+// per-strategy parameters.
+static cl::opt EnableInlineSummaryOpt(
+"inline-callees", cl::desc("Summarize per-callee inling statistics"),
+cl::cat(SummaryStrategyCat), cl::init(false), cl::sub(SummarySub));
+
+class SummaryStrategy {
+public:
+ virtual ~SummaryStrategy() = default;
+ virtual bool filter(Remark &R) = 0;
+ virtual Error process(Remark &R) = 0;
+ virtual void emit(RemarkSerializer &Serializer) = 0;
+};
jroelofs wrote:
Some doxygen here describing the high-level expectations of this interface
would be helpful.
https://github.com/llvm/llvm-project/pull/160549
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-remarkutil] Introduce summary tool (PR #160549)
https://github.com/jroelofs approved this pull request. https://github.com/llvm/llvm-project/pull/160549 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Add accessor functions to __tree_node_base (PR #147679)
@@ -132,18 +139,18 @@ unsigned __tree_sub_invariant(_NodePtr __x) {
if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
return 0;
// If this is red, neither child can be red
- if (!__x->__is_black_) {
-if (__x->__left_ && !__x->__left_->__is_black_)
+ if (__x->__color_ == __red) {
+if (__x->__left_ && __x->__left_->__color_ == __red)
return 0;
-if (__x->__right_ && !__x->__right_->__is_black_)
+if (__x->__right_ && __x->__right_->__color_ == __red)
return 0;
}
unsigned __h = std::__tree_sub_invariant(__x->__left_);
if (__h == 0)
return 0; // invalid left subtree
if (__h != std::__tree_sub_invariant(__x->__right_))
return 0;// invalid or different height right subtree
- return __h + __x->__is_black_; // return black height of this node
+ return __h + (__x->__color_ == __black ? 1 : 0); // return black height of
this node
ldionne wrote:
I think you should be using the accessor for getting the color here too.
https://github.com/llvm/llvm-project/pull/147679
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Add accessor functions to __tree_node_base (PR #147679)
https://github.com/ldionne approved this pull request. LGTM with nitpicks. https://github.com/llvm/llvm-project/pull/147679 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/21.x: [NVPTX] Disable relative lookup tables (#159748) (PR #160064)
https://github.com/Artem-B edited https://github.com/llvm/llvm-project/pull/160064 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-remarkutil] Introduce summary tool (PR #160549)
@@ -34,6 +42,14 @@ std::optional Argument::getValAsInt() const {
return KeyVal.getSExtValue();
}
+std::optional Argument::getValAsSignedInt() const {
jroelofs wrote:
what's the difference between this and `getValAsInt`?
https://github.com/llvm/llvm-project/pull/160549
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (PR #160573)
https://github.com/kparzysz updated
https://github.com/llvm/llvm-project/pull/160573
>From 525f12fa0da6c22dded6c19e2338b6bcc3c2da6f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek
Date: Wed, 24 Sep 2025 07:59:16 -0500
Subject: [PATCH 1/2] [flang][OpenMP] Use OmpDirectiveSpecification in
DECLARE_TARGET
---
flang/include/flang/Parser/openmp-utils.h | 2 -
flang/include/flang/Parser/parse-tree.h | 10 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 14 +-
flang/lib/Parser/openmp-parsers.cpp | 18 +-
flang/lib/Parser/unparse.cpp | 4 +-
flang/lib/Semantics/check-omp-structure.cpp | 245 +-
flang/lib/Semantics/check-omp-structure.h | 3 -
flang/lib/Semantics/resolve-directives.cpp| 27 +-
flang/lib/Semantics/resolve-names.cpp | 77 +++---
.../OpenMP/declare-target-indirect-tree.f90 | 28 +-
.../OpenMP/declare-target-to-clause.f90 | 14 +-
.../OpenMP/declare_target-device_type.f90 | 108 ++--
.../Parser/OpenMP/enter-automap-modifier.f90 | 11 +-
.../OpenMP/openmp6-directive-spellings.f90| 9 +-
.../Semantics/OpenMP/blank-common-block.f90 | 1 +
...lare-target-function-name-with-symbols.f90 | 2 +-
16 files changed, 319 insertions(+), 254 deletions(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index 4b8fe6a5b49f0..bf54f970a7d3a 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -41,7 +41,6 @@ struct ConstructId {
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
-MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -97,7 +96,6 @@ struct DirectiveNameScope {
} else if constexpr (std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
return MakeName(std::get(x.t).source, ConstructId::id);
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index be30a95763208..e7593d9875097 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4961,10 +4961,16 @@ struct OmpDeclareTargetSpecifier {
std::variant u;
};
+// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207],
+// [6.0:346-348]
+//
+// declare-target-directive -> // since 4.5
+//DECLARE_TARGET[(extended-list)] |
+//DECLARE_TARGET clause-list
struct OpenMPDeclareTargetConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclareTargetConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple t;
};
// OMP v5.2: 5.8.8
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index d2e865b3e1d0c..1cb3335abbd06 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(
static void getDeclareTargetInfo(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
-const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct,
+const parser::OpenMPDeclareTargetConstruct &construct,
mlir::omp::DeclareTargetOperands &clauseOps,
llvm::SmallVectorImpl &symbolAndClause) {
- const auto &spec =
- std::get(declareTargetConstruct.t);
- if (const auto *objectList{parser::Unwrap(spec.u)}) {
-ObjectList objects{makeObjects(*objectList, semaCtx)};
+
+ if (!construct.v.Arguments().v.empty()) {
+ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
symbolAndClause, /*automap=*/false);
- } else if (const auto *clauseList{
- parser::Unwrap(spec.u)}) {
-List clauses = makeClauses(*clauseList, semaCtx);
+ } else {
+List clauses = makeClauses(construct.v.Clauses(), semaCtx);
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index 0085576292ff5..bd080386c0aea 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1773,23 +1773,11 @@
TYPE_PARSER(sourced(construct(
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
Parser{})))
-// declare-target with list
-TYPE_PARSER(sourced(construct(
-parenth
[llvm-branch-commits] [clang] [llvm] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)
https://github.com/joaosaffran updated
https://github.com/llvm/llvm-project/pull/160210
>From 6b191d041990ad667d86b6b07eeed7c802e3fe45 Mon Sep 17 00:00:00 2001
From: Joao Saffran
Date: Mon, 22 Sep 2025 15:31:47 -0700
Subject: [PATCH 1/3] adding metadata static sampler flags
---
clang/test/CodeGenHLSL/RootSignature.hlsl | 4 +-
.../Frontend/HLSL/RootSignatureMetadata.cpp | 14 +-
...gnature-StaticSamplers-Invalid-AddressU.ll | 2 +-
...gnature-StaticSamplers-Invalid-AddressV.ll | 2 +-
...gnature-StaticSamplers-Invalid-AddressW.ll | 2 +-
...ture-StaticSamplers-Invalid-BorderColor.ll | 2 +-
...e-StaticSamplers-Invalid-ComparisonFunc.ll | 2 +-
...Signature-StaticSamplers-Invalid-Filter.ll | 2 +-
...re-StaticSamplers-Invalid-MaxAnisotropy.ll | 2 +-
...Signature-StaticSamplers-Invalid-MaxLod.ll | 2 +-
...Signature-StaticSamplers-Invalid-MinLod.ll | 2 +-
...ature-StaticSamplers-Invalid-MinLopBias.ll | 2 +-
...re-StaticSamplers-Invalid-RegisterSpace.ll | 2 +-
...e-StaticSamplers-Invalid-ShaderRegister.ll | 2 +-
...StaticSamplers-Invalid-ShaderVisibility.ll | 2 +-
.../RootSignature-StaticSamplers.ll | 2 +-
.../RootSignature-StaticSamplers_V3.ll| 43 +++
.../rootsignature-validation-fail-sampler.ll | 2 +-
...re-validation-fail-static-sampler-range.ll | 4 +-
19 files changed, 75 insertions(+), 20 deletions(-)
create mode 100644
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl
b/clang/test/CodeGenHLSL/RootSignature.hlsl
index bc40bdd79ce59..bbab6a73a3658 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -82,8 +82,8 @@ void RootDescriptorsEntry() {}
// checking minLOD, maxLOD
// CHECK-SAME: float -1.28e+02, float 1.28e+02,
-// checking register, space and visibility
-// CHECK-SAME: i32 42, i32 0, i32 0}
+// checking register, space, visibility and flags
+// CHECK-SAME: i32 42, i32 0, i32 0, i32 0}
#define SampleStaticSampler \
"StaticSampler(s42, " \
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..5ddf129265648 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const
StaticSampler &Sampler) {
ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
ConstantAsMetadata::get(
Builder.getInt32(to_underlying(Sampler.Visibility))),
+ ConstantAsMetadata::get(Builder.getInt32(0)),
};
return MDNode::get(Ctx, Operands);
}
@@ -411,7 +412,7 @@ Error
MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
MDNode *StaticSamplerNode) {
- if (StaticSamplerNode->getNumOperands() != 14)
+ if (StaticSamplerNode->getNumOperands() != 15)
return make_error("Static Sampler");
mcdxbc::StaticSampler Sampler;
@@ -495,6 +496,17 @@ Error
MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
return Error(std::move(E));
Sampler.ShaderVisibility = *Visibility;
+ if (RSD.Version < 3) {
+RSD.StaticSamplers.push_back(Sampler);
+return Error::success();
+ }
+ assert(RSD.Version >= 3);
+
+ if (std::optional Val = extractMdIntValue(StaticSamplerNode, 14))
+Sampler.Flags = *Val;
+ else
+return make_error("Static Sampler Flags");
+
RSD.StaticSamplers.push_back(Sampler);
return Error::success();
}
diff --git
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
index 288dea00b6e55..b043ea1418df6 100644
---
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
+++
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
@@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1"
"hlsl.shader"="compute" }
!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
-!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float
1.28e+02, i32 42, i32 0, i32 0 }
+!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float
1.28e+02, i32 42, i32 0, i32 0, i32 0 }
diff --git
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
index e9abcf966..8219ffdd679d2 100644
---
a/llvm/test/CodeGen/D
[llvm-branch-commits] [clang] [llvm] [HLSL] Update Frontend to support version 1.2 of root signature (PR #160616)
@@ -926,6 +929,20 @@ RootSignatureParser::parseStaticSamplerParams() {
if (!Visibility.has_value())
return std::nullopt;
Params.Visibility = Visibility;
+} else if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
+ // `flags` `=` UINT_BORDER_COLOR
inbelic wrote:
nit:
```suggestion
// `flags` `=` STATIC_SAMPLE_FLAGS
```
https://github.com/llvm/llvm-project/pull/160616
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libunwind] release/21.x: [Mips] Fixed libunwind::Registers_mips_o32::jumpto to allow for load delay (#152942) (PR #160638)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/160638 Backport a3d7c468bdc328f04da720088b2e542ef1f33ffc Requested by: @brad0 >From 841de79c34154f7d96d1f74c60edfb6299bd7494 Mon Sep 17 00:00:00 2001 From: Jade Marker Date: Thu, 25 Sep 2025 02:20:25 +0100 Subject: [PATCH] [Mips] Fixed libunwind::Registers_mips_o32::jumpto to allow for load delay (#152942) Fix #152922 MIPS III also has load delay, so libunwind::Registers_mips_newabi::jumpto() is also fixed. (cherry picked from commit a3d7c468bdc328f04da720088b2e542ef1f33ffc) --- libunwind/src/UnwindRegistersRestore.S | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S index 5e199188945df..1bcd205be260d 100644 --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -1044,9 +1044,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) lw$27, (4 * 27)($4) lw$28, (4 * 28)($4) lw$29, (4 * 29)($4) - lw$30, (4 * 30)($4) // load new pc into ra lw$31, (4 * 32)($4) + // MIPS 1 has load delay slot. Ensure lw $31 and jr are separated by an instruction. + lw$30, (4 * 30)($4) // jump to ra, load a0 in the delay slot jr$31 lw$4, (4 * 4)($4) @@ -1082,11 +1083,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) ld$2, (8 * 2)($4) ld$3, (8 * 3)($4) // skip a0 for now - .irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 + .irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29 ld $\i, (8 * \i)($4) .endr // load new pc into ra ld$31, (8 * 32)($4) + // MIPS 1 has load delay slot. Ensure lw $31 and jr are separated by an instruction. + ld$30, (8 * 30)($4) // jump to ra, load a0 in the delay slot jr$31 ld$4, (8 * 4)($4) ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/159991 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL] Update Frontend to support version 1.2 of root signature (PR #160616)
@@ -266,7 +266,8 @@ TEST(HLSLRootSignatureTest, DefaultStaticSamplerDump) {
"minLOD = 0.00e+00, "
"maxLOD = 3.402823e+38, "
"space = 0, "
- "visibility = All"
+ "visibility = All, "
+ "flags = 0x0"
inbelic wrote:
These flags should be output with their named values (and `None` instead of
`0`) to match the behaviour of the other flag types
https://github.com/llvm/llvm-project/pull/160616
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL] Update Frontend to support version 1.2 of root signature (PR #160616)
https://github.com/inbelic edited https://github.com/llvm/llvm-project/pull/160616 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libunwind] release/21.x: [Mips] Fixed libunwind::Registers_mips_o32::jumpto to allow for load delay (#152942) (PR #160638)
llvmbot wrote: @wzssyqa What do you think about merging this PR to the release branch? https://github.com/llvm/llvm-project/pull/160638 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)
https://github.com/bogner approved this pull request. LGTM once @inbelic is happy with it https://github.com/llvm/llvm-project/pull/160184 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)
@@ -212,6 +212,8 @@ MDNode *MetadataBuilder::BuildStaticSampler(const
StaticSampler &Sampler) {
ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
ConstantAsMetadata::get(
Builder.getInt32(to_underlying(Sampler.Visibility))),
+ ConstantAsMetadata::get(
+Builder.getInt32(to_underlying(Sampler.Visibility))),
inbelic wrote:
```suggestion
Builder.getInt32(0)),
```
I think 0 makes more sense as the temporary measure
https://github.com/llvm/llvm-project/pull/160210
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)
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 --
llvm/include/llvm/Object/DXContainer.h llvm/lib/Object/DXContainer.cpp
llvm/lib/ObjectYAML/DXContainerYAML.cpp
llvm/unittests/Object/DXContainerTest.cpp
``
: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/llvm/lib/ObjectYAML/DXContainerYAML.cpp
b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index efa8b40c2..3c09ae4e5 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -211,8 +211,7 @@ DXContainerYAML::RootSignatureYamlDesc::create(
if (Version > 2) {
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)
\
- NewS.Enum =
\
- (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum));
+ NewS.Enum = (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum));
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
RootSigDesc.StaticSamplers.push_back(NewS);
diff --git a/llvm/unittests/Object/DXContainerTest.cpp
b/llvm/unittests/Object/DXContainerTest.cpp
index 9e805639c..d6f7b26b9 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1201,8 +1201,8 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(Sampler.ShaderVisibility, 7u);
}
{
-// this is testing static sampler parsing for root signature version 1.2,
-// it changes: the version number, the size of root signature being
emitted
+// this is testing static sampler parsing for root signature version 1.2,
+// it changes: the version number, the size of root signature being emitted
// and the values for flag fields.
uint8_t Buffer[] = {
0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
``
https://github.com/llvm/llvm-project/pull/160184
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in ASSUMES (PR #160591)
llvmbot wrote:
@llvm/pr-subscribers-flang-openmp
Author: Krzysztof Parzyszek (kparzysz)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/160591.diff
6 Files Affected:
- (modified) flang/include/flang/Parser/openmp-utils.h (-2)
- (modified) flang/include/flang/Parser/parse-tree.h (+2-2)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+4-2)
- (modified) flang/lib/Parser/unparse.cpp (+2-2)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (-4)
- (modified) flang/test/Parser/OpenMP/assumption.f90 (+5-3)
``diff
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index bf54f970a7d3a..77c31b939e522 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -39,7 +39,6 @@ struct ConstructId {
}
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
-MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -94,7 +93,6 @@ struct DirectiveNameScope {
if constexpr (std::is_base_of_v) {
return std::get(x.t).DirName();
} else if constexpr (std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index 486be8b60ff8c..bd55166eb9f80 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4877,8 +4877,8 @@ struct OpenMPUtilityConstruct {
// ASSUMES absent-clause | contains-clause | holds-clause | no-openmp-clause
|
// no-openmp-routines-clause | no-parallelism-clause
struct OpenMPDeclarativeAssumes {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAssumes);
- std::tuple t;
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclarativeAssumes, OmpDirectiveSpecification);
CharBlock source;
};
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index bd080386c0aea..12e89e8c35456 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1852,8 +1852,10 @@ TYPE_PARSER(
lookAhead(endOmpLine / !statement(allocateStmt)))
// Assumes Construct
-TYPE_PARSER(sourced(construct(
-verbatim("ASSUMES"_tok), Parser{})))
+TYPE_PARSER(construct(
+predicated(OmpDirectiveNameParser{},
+IsDirective(llvm::omp::Directive::OMPD_assumes)) >=
+Parser{}))
// Declarative constructs
TYPE_PARSER(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index a2b0b9ef3196c..9812a656092ac 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2558,8 +2558,8 @@ class UnparseVisitor {
void Unparse(const OpenMPDeclarativeAssumes &x) {
BeginOpenMP();
-Word("!$OMP ASSUMES ");
-Walk(std::get(x.t));
+Word("!$OMP ");
+Walk(x.v);
Put("\n");
EndOpenMP();
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp
b/flang/lib/Semantics/check-omp-structure.cpp
index 05ff541657b1a..6538e0b794791 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -620,10 +620,6 @@ template struct
DirectiveSpellingVisitor {
checker_(GetDirName(x.t).source, Directive::OMPD_allocators);
return false;
}
- bool Pre(const parser::OpenMPDeclarativeAssumes &x) {
-checker_(std::get(x.t).source, Directive::OMPD_assumes);
-return false;
- }
bool Pre(const parser::OpenMPGroupprivate &x) {
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
return false;
diff --git a/flang/test/Parser/OpenMP/assumption.f90
b/flang/test/Parser/OpenMP/assumption.f90
index 0f333f99f9085..86cbad9e42f78 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -141,9 +141,11 @@ program p
end program p
!UNPARSE: PROGRAM p
-!UNPARSE: !$OMP ASSUMES NO_OPENMP
+!UNPARSE: !$OMP ASSUMES NO_OPENMP
!UNPARSE: END PROGRAM p
-!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes
-!PARSE-TREE: | Verbatim
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes ->
OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = assumes
!PARSE-TREE: | OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: | Flags = None
+!PARSE-TREE: ImplicitPart ->
``
https://github.com/llvm/llvm-project/pull/160591
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in ASSUMES (PR #160591)
llvmbot wrote:
@llvm/pr-subscribers-flang-semantics
Author: Krzysztof Parzyszek (kparzysz)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/160591.diff
6 Files Affected:
- (modified) flang/include/flang/Parser/openmp-utils.h (-2)
- (modified) flang/include/flang/Parser/parse-tree.h (+2-2)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+4-2)
- (modified) flang/lib/Parser/unparse.cpp (+2-2)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (-4)
- (modified) flang/test/Parser/OpenMP/assumption.f90 (+5-3)
``diff
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index bf54f970a7d3a..77c31b939e522 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -39,7 +39,6 @@ struct ConstructId {
}
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
-MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -94,7 +93,6 @@ struct DirectiveNameScope {
if constexpr (std::is_base_of_v) {
return std::get(x.t).DirName();
} else if constexpr (std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index 486be8b60ff8c..bd55166eb9f80 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4877,8 +4877,8 @@ struct OpenMPUtilityConstruct {
// ASSUMES absent-clause | contains-clause | holds-clause | no-openmp-clause
|
// no-openmp-routines-clause | no-parallelism-clause
struct OpenMPDeclarativeAssumes {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAssumes);
- std::tuple t;
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclarativeAssumes, OmpDirectiveSpecification);
CharBlock source;
};
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index bd080386c0aea..12e89e8c35456 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1852,8 +1852,10 @@ TYPE_PARSER(
lookAhead(endOmpLine / !statement(allocateStmt)))
// Assumes Construct
-TYPE_PARSER(sourced(construct(
-verbatim("ASSUMES"_tok), Parser{})))
+TYPE_PARSER(construct(
+predicated(OmpDirectiveNameParser{},
+IsDirective(llvm::omp::Directive::OMPD_assumes)) >=
+Parser{}))
// Declarative constructs
TYPE_PARSER(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index a2b0b9ef3196c..9812a656092ac 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2558,8 +2558,8 @@ class UnparseVisitor {
void Unparse(const OpenMPDeclarativeAssumes &x) {
BeginOpenMP();
-Word("!$OMP ASSUMES ");
-Walk(std::get(x.t));
+Word("!$OMP ");
+Walk(x.v);
Put("\n");
EndOpenMP();
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp
b/flang/lib/Semantics/check-omp-structure.cpp
index 05ff541657b1a..6538e0b794791 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -620,10 +620,6 @@ template struct
DirectiveSpellingVisitor {
checker_(GetDirName(x.t).source, Directive::OMPD_allocators);
return false;
}
- bool Pre(const parser::OpenMPDeclarativeAssumes &x) {
-checker_(std::get(x.t).source, Directive::OMPD_assumes);
-return false;
- }
bool Pre(const parser::OpenMPGroupprivate &x) {
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
return false;
diff --git a/flang/test/Parser/OpenMP/assumption.f90
b/flang/test/Parser/OpenMP/assumption.f90
index 0f333f99f9085..86cbad9e42f78 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -141,9 +141,11 @@ program p
end program p
!UNPARSE: PROGRAM p
-!UNPARSE: !$OMP ASSUMES NO_OPENMP
+!UNPARSE: !$OMP ASSUMES NO_OPENMP
!UNPARSE: END PROGRAM p
-!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes
-!PARSE-TREE: | Verbatim
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes ->
OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = assumes
!PARSE-TREE: | OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: | Flags = None
+!PARSE-TREE: ImplicitPart ->
``
https://github.com/llvm/llvm-project/pull/160591
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)
https://github.com/inbelic approved this pull request. https://github.com/llvm/llvm-project/pull/160184 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in ASSUMES (PR #160591)
https://github.com/kparzysz updated
https://github.com/llvm/llvm-project/pull/160591
>From eb12400ffc25b62205183f3102a1e0afdb785510 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek
Date: Wed, 24 Sep 2025 14:38:40 -0500
Subject: [PATCH 1/2] [flang][OpenMP] Use OmpDirectiveSpecification in ASSUMES
---
flang/include/flang/Parser/openmp-utils.h | 2 --
flang/include/flang/Parser/parse-tree.h | 4 ++--
flang/lib/Parser/openmp-parsers.cpp | 6 --
flang/lib/Parser/unparse.cpp| 4 ++--
flang/lib/Semantics/check-omp-structure.cpp | 4
flang/test/Parser/OpenMP/assumption.f90 | 8 +---
6 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index bf54f970a7d3a..77c31b939e522 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -39,7 +39,6 @@ struct ConstructId {
}
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
-MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -94,7 +93,6 @@ struct DirectiveNameScope {
if constexpr (std::is_base_of_v) {
return std::get(x.t).DirName();
} else if constexpr (std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index 486be8b60ff8c..bd55166eb9f80 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4877,8 +4877,8 @@ struct OpenMPUtilityConstruct {
// ASSUMES absent-clause | contains-clause | holds-clause | no-openmp-clause
|
// no-openmp-routines-clause | no-parallelism-clause
struct OpenMPDeclarativeAssumes {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAssumes);
- std::tuple t;
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclarativeAssumes, OmpDirectiveSpecification);
CharBlock source;
};
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index bd080386c0aea..12e89e8c35456 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1852,8 +1852,10 @@ TYPE_PARSER(
lookAhead(endOmpLine / !statement(allocateStmt)))
// Assumes Construct
-TYPE_PARSER(sourced(construct(
-verbatim("ASSUMES"_tok), Parser{})))
+TYPE_PARSER(construct(
+predicated(OmpDirectiveNameParser{},
+IsDirective(llvm::omp::Directive::OMPD_assumes)) >=
+Parser{}))
// Declarative constructs
TYPE_PARSER(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index a2b0b9ef3196c..9812a656092ac 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2558,8 +2558,8 @@ class UnparseVisitor {
void Unparse(const OpenMPDeclarativeAssumes &x) {
BeginOpenMP();
-Word("!$OMP ASSUMES ");
-Walk(std::get(x.t));
+Word("!$OMP ");
+Walk(x.v);
Put("\n");
EndOpenMP();
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp
b/flang/lib/Semantics/check-omp-structure.cpp
index 05ff541657b1a..6538e0b794791 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -620,10 +620,6 @@ template struct
DirectiveSpellingVisitor {
checker_(GetDirName(x.t).source, Directive::OMPD_allocators);
return false;
}
- bool Pre(const parser::OpenMPDeclarativeAssumes &x) {
-checker_(std::get(x.t).source, Directive::OMPD_assumes);
-return false;
- }
bool Pre(const parser::OpenMPGroupprivate &x) {
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
return false;
diff --git a/flang/test/Parser/OpenMP/assumption.f90
b/flang/test/Parser/OpenMP/assumption.f90
index 0f333f99f9085..86cbad9e42f78 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -141,9 +141,11 @@ program p
end program p
!UNPARSE: PROGRAM p
-!UNPARSE: !$OMP ASSUMES NO_OPENMP
+!UNPARSE: !$OMP ASSUMES NO_OPENMP
!UNPARSE: END PROGRAM p
-!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes
-!PARSE-TREE: | Verbatim
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes ->
OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = assumes
!PARSE-TREE: | OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: | Flags = None
+!PARSE-TREE: ImplicitPart ->
>From 7f1df5bd47499d75180ba2c8509730e4bba60956 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek
Date: Wed, 24 Sep 2025 14:49:35 -0500
Subject: [PATCH 2/2] Forgot "sourced"
---
flang/lib/Parser/openmp-parsers.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (PR #160573)
https://github.com/kparzysz updated
https://github.com/llvm/llvm-project/pull/160573
>From 525f12fa0da6c22dded6c19e2338b6bcc3c2da6f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek
Date: Wed, 24 Sep 2025 07:59:16 -0500
Subject: [PATCH 1/4] [flang][OpenMP] Use OmpDirectiveSpecification in
DECLARE_TARGET
---
flang/include/flang/Parser/openmp-utils.h | 2 -
flang/include/flang/Parser/parse-tree.h | 10 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 14 +-
flang/lib/Parser/openmp-parsers.cpp | 18 +-
flang/lib/Parser/unparse.cpp | 4 +-
flang/lib/Semantics/check-omp-structure.cpp | 245 +-
flang/lib/Semantics/check-omp-structure.h | 3 -
flang/lib/Semantics/resolve-directives.cpp| 27 +-
flang/lib/Semantics/resolve-names.cpp | 77 +++---
.../OpenMP/declare-target-indirect-tree.f90 | 28 +-
.../OpenMP/declare-target-to-clause.f90 | 14 +-
.../OpenMP/declare_target-device_type.f90 | 108 ++--
.../Parser/OpenMP/enter-automap-modifier.f90 | 11 +-
.../OpenMP/openmp6-directive-spellings.f90| 9 +-
.../Semantics/OpenMP/blank-common-block.f90 | 1 +
...lare-target-function-name-with-symbols.f90 | 2 +-
16 files changed, 319 insertions(+), 254 deletions(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index 4b8fe6a5b49f0..bf54f970a7d3a 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -41,7 +41,6 @@ struct ConstructId {
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
-MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -97,7 +96,6 @@ struct DirectiveNameScope {
} else if constexpr (std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
return MakeName(std::get(x.t).source, ConstructId::id);
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index be30a95763208..e7593d9875097 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4961,10 +4961,16 @@ struct OmpDeclareTargetSpecifier {
std::variant u;
};
+// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207],
+// [6.0:346-348]
+//
+// declare-target-directive -> // since 4.5
+//DECLARE_TARGET[(extended-list)] |
+//DECLARE_TARGET clause-list
struct OpenMPDeclareTargetConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclareTargetConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple t;
};
// OMP v5.2: 5.8.8
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index d2e865b3e1d0c..1cb3335abbd06 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(
static void getDeclareTargetInfo(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
-const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct,
+const parser::OpenMPDeclareTargetConstruct &construct,
mlir::omp::DeclareTargetOperands &clauseOps,
llvm::SmallVectorImpl &symbolAndClause) {
- const auto &spec =
- std::get(declareTargetConstruct.t);
- if (const auto *objectList{parser::Unwrap(spec.u)}) {
-ObjectList objects{makeObjects(*objectList, semaCtx)};
+
+ if (!construct.v.Arguments().v.empty()) {
+ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
symbolAndClause, /*automap=*/false);
- } else if (const auto *clauseList{
- parser::Unwrap(spec.u)}) {
-List clauses = makeClauses(*clauseList, semaCtx);
+ } else {
+List clauses = makeClauses(construct.v.Clauses(), semaCtx);
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index 0085576292ff5..bd080386c0aea 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1773,23 +1773,11 @@
TYPE_PARSER(sourced(construct(
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
Parser{})))
-// declare-target with list
-TYPE_PARSER(sourced(construct(
-parenth
[llvm-branch-commits] [libcxx] [libc++] Add accessor functions to __tree_node_base (PR #147679)
https://github.com/ldionne edited https://github.com/llvm/llvm-project/pull/147679 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Move physreg check when trying to recolor vregs (NFC) (PR #160484)
https://github.com/preames approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/160484 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-remarkutil] Introduce summary tool (PR #160549)
https://github.com/tobias-stadler created https://github.com/llvm/llvm-project/pull/160549 This tool provides a harness for implementing different strategies that summarize many remarks (possibly from multiple translation units) into new summary remarks. The remark summaries can then be viewed using tools like `opt-viewer`. The first summary strategy is `--inline-callees`, which generates remarks that summarize the per-callee inline statistics for functions that appear in inling remarks. This is useful for troubleshooting inlining issues/regressions on large codebases. ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Merge VirtRegMap queries into one use (NFC) (PR #160485)
https://github.com/preames approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/160485 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [DirectX] Updating Root Signature Metadata to contain Static Sampler flags (PR #160210)
https://github.com/joaosaffran updated
https://github.com/llvm/llvm-project/pull/160210
>From 6b191d041990ad667d86b6b07eeed7c802e3fe45 Mon Sep 17 00:00:00 2001
From: Joao Saffran
Date: Mon, 22 Sep 2025 15:31:47 -0700
Subject: [PATCH 1/5] adding metadata static sampler flags
---
clang/test/CodeGenHLSL/RootSignature.hlsl | 4 +-
.../Frontend/HLSL/RootSignatureMetadata.cpp | 14 +-
...gnature-StaticSamplers-Invalid-AddressU.ll | 2 +-
...gnature-StaticSamplers-Invalid-AddressV.ll | 2 +-
...gnature-StaticSamplers-Invalid-AddressW.ll | 2 +-
...ture-StaticSamplers-Invalid-BorderColor.ll | 2 +-
...e-StaticSamplers-Invalid-ComparisonFunc.ll | 2 +-
...Signature-StaticSamplers-Invalid-Filter.ll | 2 +-
...re-StaticSamplers-Invalid-MaxAnisotropy.ll | 2 +-
...Signature-StaticSamplers-Invalid-MaxLod.ll | 2 +-
...Signature-StaticSamplers-Invalid-MinLod.ll | 2 +-
...ature-StaticSamplers-Invalid-MinLopBias.ll | 2 +-
...re-StaticSamplers-Invalid-RegisterSpace.ll | 2 +-
...e-StaticSamplers-Invalid-ShaderRegister.ll | 2 +-
...StaticSamplers-Invalid-ShaderVisibility.ll | 2 +-
.../RootSignature-StaticSamplers.ll | 2 +-
.../RootSignature-StaticSamplers_V3.ll| 43 +++
.../rootsignature-validation-fail-sampler.ll | 2 +-
...re-validation-fail-static-sampler-range.ll | 4 +-
19 files changed, 75 insertions(+), 20 deletions(-)
create mode 100644
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl
b/clang/test/CodeGenHLSL/RootSignature.hlsl
index bc40bdd79ce59..bbab6a73a3658 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -82,8 +82,8 @@ void RootDescriptorsEntry() {}
// checking minLOD, maxLOD
// CHECK-SAME: float -1.28e+02, float 1.28e+02,
-// checking register, space and visibility
-// CHECK-SAME: i32 42, i32 0, i32 0}
+// checking register, space, visibility and flags
+// CHECK-SAME: i32 42, i32 0, i32 0, i32 0}
#define SampleStaticSampler \
"StaticSampler(s42, " \
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..5ddf129265648 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const
StaticSampler &Sampler) {
ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
ConstantAsMetadata::get(
Builder.getInt32(to_underlying(Sampler.Visibility))),
+ ConstantAsMetadata::get(Builder.getInt32(0)),
};
return MDNode::get(Ctx, Operands);
}
@@ -411,7 +412,7 @@ Error
MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
MDNode *StaticSamplerNode) {
- if (StaticSamplerNode->getNumOperands() != 14)
+ if (StaticSamplerNode->getNumOperands() != 15)
return make_error("Static Sampler");
mcdxbc::StaticSampler Sampler;
@@ -495,6 +496,17 @@ Error
MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
return Error(std::move(E));
Sampler.ShaderVisibility = *Visibility;
+ if (RSD.Version < 3) {
+RSD.StaticSamplers.push_back(Sampler);
+return Error::success();
+ }
+ assert(RSD.Version >= 3);
+
+ if (std::optional Val = extractMdIntValue(StaticSamplerNode, 14))
+Sampler.Flags = *Val;
+ else
+return make_error("Static Sampler Flags");
+
RSD.StaticSamplers.push_back(Sampler);
return Error::success();
}
diff --git
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
index 288dea00b6e55..b043ea1418df6 100644
---
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
+++
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll
@@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1"
"hlsl.shader"="compute" }
!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
-!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float
1.28e+02, i32 42, i32 0, i32 0 }
+!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float
0x3FF6C000, i32 9, i32 3, i32 2, float -1.28e+02, float
1.28e+02, i32 42, i32 0, i32 0, i32 0 }
diff --git
a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll
index e9abcf966..8219ffdd679d2 100644
---
a/llvm/test/CodeGen/D
[llvm-branch-commits] [mlir] [mlir][omp] Add omp.tile operation (PR #160292)
https://github.com/tblah edited https://github.com/llvm/llvm-project/pull/160292 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][omp] Add omp.tile operation (PR #160292)
https://github.com/tblah commented: Looks great. Just one question about the change to generic MLIR code. https://github.com/llvm/llvm-project/pull/160292 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Introduce a liveness-based lifetime policy (PR #159991)
@@ -138,7 +148,7 @@ class LifetimeSafetyAnalysis {
std::unique_ptr Factory;
std::unique_ptr FactMgr;
std::unique_ptr LoanPropagation;
- std::unique_ptr ExpiredLoans;
+ std::unique_ptr LiveOrigins;
usx95 wrote:
We cannot store these directly as we have a forward decl to these in `.h` and a
full definition is only available in the implementation file :/
https://github.com/llvm/llvm-project/pull/159991
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libunwind] release/21.x: [Mips] Fixed libunwind::Registers_mips_o32::jumpto to allow for load delay (#152942) (PR #160638)
llvmbot wrote: @llvm/pr-subscribers-libunwind Author: None (llvmbot) Changes Backport a3d7c468bdc328f04da720088b2e542ef1f33ffc Requested by: @brad0 --- Full diff: https://github.com/llvm/llvm-project/pull/160638.diff 1 Files Affected: - (modified) libunwind/src/UnwindRegistersRestore.S (+5-2) ``diff diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S index 5e199188945df..1bcd205be260d 100644 --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -1044,9 +1044,10 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) lw$27, (4 * 27)($4) lw$28, (4 * 28)($4) lw$29, (4 * 29)($4) - lw$30, (4 * 30)($4) // load new pc into ra lw$31, (4 * 32)($4) + // MIPS 1 has load delay slot. Ensure lw $31 and jr are separated by an instruction. + lw$30, (4 * 30)($4) // jump to ra, load a0 in the delay slot jr$31 lw$4, (4 * 4)($4) @@ -1082,11 +1083,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) ld$2, (8 * 2)($4) ld$3, (8 * 3)($4) // skip a0 for now - .irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 + .irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29 ld $\i, (8 * \i)($4) .endr // load new pc into ra ld$31, (8 * 32)($4) + // MIPS 1 has load delay slot. Ensure lw $31 and jr are separated by an instruction. + ld$30, (8 * 30)($4) // jump to ra, load a0 in the delay slot jr$31 ld$4, (8 * 4)($4) `` https://github.com/llvm/llvm-project/pull/160638 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libunwind] release/21.x: [Mips] Fixed libunwind::Registers_mips_o32::jumpto to allow for load delay (#152942) (PR #160638)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/160638 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-remarkutil] Introduce filter command (PR #159784)
@@ -0,0 +1,84 @@
+//===- RemarkFilter.cpp
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Generic tool to filter remarks
+//
+//===--===//
+
+#include "RemarkUtilHelpers.h"
+#include "RemarkUtilRegistry.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
+
+using namespace llvm;
+using namespace remarks;
+using namespace llvm::remarkutil;
+
+namespace filter {
+
+static cl::SubCommand FilterSub("filter",
+"Filter remarks based on specified criteria.");
+
+INPUT_FORMAT_COMMAND_LINE_OPTIONS(FilterSub)
+OUTPUT_FORMAT_COMMAND_LINE_OPTIONS(FilterSub)
+INPUT_OUTPUT_COMMAND_LINE_OPTIONS(FilterSub)
+REMARK_FILTER_COMMAND_LINE_OPTIONS(FilterSub)
+
+REMARK_FILTER_SETUP_FUNC()
+
+static Error tryFilter() {
+ auto MaybeFilter = getRemarkFilters();
+ if (!MaybeFilter)
+return MaybeFilter.takeError();
+ Filters &Filter = *MaybeFilter;
+
+ auto MaybeBuf = getInputMemoryBuffer(InputFileName);
+ if (!MaybeBuf)
+return MaybeBuf.takeError();
+ auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());
+ if (!MaybeParser)
+return MaybeParser.takeError();
+ auto &Parser = **MaybeParser;
+
+ Format SerializerFormat = OutputFormat;
+ if (SerializerFormat == Format::Auto) {
+SerializerFormat = Parser.ParserFormat;
+if (OutputFileName.empty() || OutputFileName == "-")
+ SerializerFormat = Format::YAML;
+ }
+
+ auto MaybeOF = getOutputFileForRemarks(OutputFileName, SerializerFormat);
+ if (!MaybeOF)
+return MaybeOF.takeError();
+ auto OF = std::move(*MaybeOF);
+
+ auto MaybeSerializer = createRemarkSerializer(SerializerFormat, OF->os());
+ if (!MaybeSerializer)
+return MaybeSerializer.takeError();
+ auto &Serializer = **MaybeSerializer;
+
+ auto MaybeRemark = Parser.next();
+ for (; MaybeRemark; MaybeRemark = Parser.next()) {
+Remark &Remark = **MaybeRemark;
+if (!Filter.filterRemark(Remark))
+ continue;
+Serializer.emit(Remark);
+ }
fhahn wrote:
Yeah that's OK, although this might be worth more thought in the future, to
avoid duplicating the logic in every remarks tool
https://github.com/llvm/llvm-project/pull/159784
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-remarkutil] Introduce filter command (PR #159784)
https://github.com/fhahn edited https://github.com/llvm/llvm-project/pull/159784 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][omp] Add omp.tile operation (PR #160292)
https://github.com/Meinersbur edited https://github.com/llvm/llvm-project/pull/160292 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][omp] Add omp.tile operation (PR #160292)
llvmbot wrote:
@llvm/pr-subscribers-mlir-llvm
Author: Michael Kruse (Meinersbur)
Changes
Add the `omp.tile` loop transformations for the OpenMP dialect. Used for
lowering a standalone `!$omp tile` in Flang.
The pretty operation printing format is currently inconcistent between
`omp.canonical_loop`, `omp.unroll_heuristic`, and `omp.tile`. Open for
suggestions what the concistent format should be.
PR Stack:
* #160283
* #159773
* #160292 (this PR)
* #160298
---
Patch is 45.67 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/160292.diff
13 Files Affected:
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td (+29)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td (+67-2)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td (+25-38)
- (modified) mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp (+154)
- (modified)
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+42)
- (added) mlir/test/Dialect/OpenMP/cli-tile.mlir (+138)
- (added) mlir/test/Dialect/OpenMP/invalid-tile.mlir (+119)
- (added) mlir/test/Target/LLVMIR/openmp-cli-tile01.mlir (+101)
- (added) mlir/test/Target/LLVMIR/openmp-cli-tile02.mlir (+190)
- (modified) mlir/test/mlir-tblgen/op-format-invalid.td (+1-1)
- (modified) mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp (+1)
- (modified) mlir/tools/mlir-tblgen/FormatGen.cpp (+1-1)
- (modified) mlir/tools/mlir-tblgen/OpFormatGen.cpp (+1)
``diff
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index 1eda5e4bc1618..8e43c4284d078 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -995,6 +995,35 @@ class OpenMP_NumTeamsClauseSkip<
def OpenMP_NumTeamsClause : OpenMP_NumTeamsClauseSkip<>;
+//===--===//
+// V5.1: [10.1.2] `sizes` clause
+//===--===//
+
+class OpenMP_SizesClauseSkip<
+bit traits = false, bit arguments = false, bit assemblyFormat = false,
+bit description = false, bit extraClassDeclaration = false
+ > : OpenMP_Clause {
+ let arguments = (ins
+Variadic:$sizes
+ );
+
+ let optAssemblyFormat = [{
+`sizes` `(` $sizes `:` type($sizes) `)`
+ }];
+
+ let description = [{
+The `sizes` clauses defines the size of a grid over a multi-dimensional
+logical iteration space. This grid is used for loop transformations such as
+`tile` and `strip`. The size per dimension can be a variable, but only
+values that are not at least 2 make sense. It is not specified what happens
+when smaller values are used, but should still result in a loop nest that
+executes each logical iteration once.
+ }];
+}
+
+def OpenMP_SizesClause : OpenMP_SizesClauseSkip<>;
+
//===--===//
// V5.2: [10.1.2] `num_threads` clause
//===--===//
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
index bbcfb87fa03c6..5ad4e4b5b61d1 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
@@ -38,6 +38,44 @@ def OpenMP_MapBoundsType : OpenMP_Type<"MapBounds",
"map_bounds_ty"> {
let summary = "Type for representing omp map clause bounds information";
}
+//===-===//
+// OpenMP Canonical Loop Info Type
+//===-===//
+
+def CanonicalLoopInfoType : OpenMP_Type<"CanonicalLoopInfo", "cli"> {
+ let summary = "Type for representing a reference to a canonical loop";
+ let description = [{
+A variable of type CanonicalLoopInfo refers to an OpenMP-compatible
+canonical loop in the same function. Values of this type are not
+available at runtime and therefore cannot be used by the program itself,
+i.e. an opaque type. It is similar to the transform dialect's
+`!transform.interface` type, but instead of implementing an interface
+for each transformation, the OpenMP dialect itself defines possible
+operations on this type.
+
+A value of type CanonicalLoopInfoType (in the following: CLI) value can be
+
+1. created by omp.new_cli.
+2. passed to omp.canonical_loop to associate the loop to that CLI. A CLI
+ can only be associated once.
+3. passed to an omp loop transformation operation that modifies the loop
+ associated with the CLI. The CLI is the "applyee" and the operation is
+ the consumer. A CLI can only be consumed once.
+4. passed to an omp loop transformation operation to associate the cli with
+ a result of that transformation. The CLI is
[llvm-branch-commits] [flang] [llvm] [openmp] [Flang] Add standalone tile support (PR #160298)
https://github.com/Meinersbur updated
https://github.com/llvm/llvm-project/pull/160298
>From bfe9c6b642ebc01f113dbf0a574e424e83f7162a Mon Sep 17 00:00:00 2001
From: Michael Kruse
Date: Tue, 23 Sep 2025 15:33:52 +0200
Subject: [PATCH 1/3] [flang] Add standalone tile support
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp| 13 +
flang/lib/Lower/OpenMP/ClauseProcessor.h | 2 +
flang/lib/Lower/OpenMP/OpenMP.cpp | 360 --
flang/lib/Lower/OpenMP/Utils.cpp | 23 +-
flang/lib/Lower/OpenMP/Utils.h| 7 +
.../lib/Semantics/check-directive-structure.h | 7 +-
flang/lib/Semantics/check-omp-structure.cpp | 8 +-
flang/lib/Semantics/resolve-directives.cpp| 16 +-
flang/test/Lower/OpenMP/tile01.f90| 58 +++
flang/test/Lower/OpenMP/tile02.f90| 88 +
.../loop-transformation-construct02.f90 | 5 +-
flang/test/Parser/OpenMP/tile-fail.f90| 32 ++
flang/test/Parser/OpenMP/tile.f90 | 15 +-
flang/test/Semantics/OpenMP/tile01.f90| 26 ++
flang/test/Semantics/OpenMP/tile02.f90| 15 +
flang/test/Semantics/OpenMP/tile03.f90| 15 +
flang/test/Semantics/OpenMP/tile04.f90| 38 ++
flang/test/Semantics/OpenMP/tile05.f90| 14 +
flang/test/Semantics/OpenMP/tile06.f90| 44 +++
flang/test/Semantics/OpenMP/tile07.f90| 35 ++
flang/test/Semantics/OpenMP/tile08.f90| 15 +
llvm/include/llvm/Frontend/OpenMP/OMP.td | 3 +
openmp/runtime/test/transform/tile/intfor.f90 | 31 ++
.../runtime/test/transform/tile/intfor_2d.f90 | 53 +++
.../transform/tile/intfor_2d_varsizes.F90 | 60 +++
25 files changed, 841 insertions(+), 142 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/tile01.f90
create mode 100644 flang/test/Lower/OpenMP/tile02.f90
create mode 100644 flang/test/Parser/OpenMP/tile-fail.f90
create mode 100644 flang/test/Semantics/OpenMP/tile01.f90
create mode 100644 flang/test/Semantics/OpenMP/tile02.f90
create mode 100644 flang/test/Semantics/OpenMP/tile03.f90
create mode 100644 flang/test/Semantics/OpenMP/tile04.f90
create mode 100644 flang/test/Semantics/OpenMP/tile05.f90
create mode 100644 flang/test/Semantics/OpenMP/tile06.f90
create mode 100644 flang/test/Semantics/OpenMP/tile07.f90
create mode 100644 flang/test/Semantics/OpenMP/tile08.f90
create mode 100644 openmp/runtime/test/transform/tile/intfor.f90
create mode 100644 openmp/runtime/test/transform/tile/intfor_2d.f90
create mode 100644 openmp/runtime/test/transform/tile/intfor_2d_varsizes.F90
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index a96884f5680ba..55eda7e3404c1 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -431,6 +431,19 @@ bool ClauseProcessor::processNumTasks(
return false;
}
+bool ClauseProcessor::processSizes(StatementContext &stmtCtx,
+ mlir::omp::SizesClauseOps &result) const {
+ if (auto *clause = findUniqueClause()) {
+result.sizes.reserve(clause->v.size());
+for (const ExprTy &vv : clause->v)
+ result.sizes.push_back(fir::getBase(converter.genExprValue(vv,
stmtCtx)));
+
+return true;
+ }
+
+ return false;
+}
+
bool ClauseProcessor::processNumTeams(
lower::StatementContext &stmtCtx,
mlir::omp::NumTeamsClauseOps &result) const {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h
b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 324ea3c1047a5..9e352fa574a97 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -66,6 +66,8 @@ class ClauseProcessor {
mlir::omp::LoopRelatedClauseOps &loopResult,
mlir::omp::CollapseClauseOps &collapseResult,
llvm::SmallVectorImpl &iv) const;
+ bool processSizes(StatementContext &stmtCtx,
+mlir::omp::SizesClauseOps &result) const;
bool processDevice(lower::StatementContext &stmtCtx,
mlir::omp::DeviceClauseOps &result) const;
bool processDeviceType(mlir::omp::DeviceTypeClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 5681be664d450..7812d9fe00be2 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1984,125 +1984,241 @@ genLoopOp(lower::AbstractConverter &converter,
lower::SymMap &symTable,
return loopOp;
}
-static mlir::omp::CanonicalLoopOp
-genCanonicalLoopOp(lower::AbstractConverter &converter, lower::SymMap
&symTable,
- semantics::SemanticsContext &semaCtx,
- lower::pft::Evaluation &eval, mlir::Location loc,
- const ConstructQueue &queue,
- ConstructQueue::const_iterator item,
- llvm::ArrayRef ivs,
- llvm::omp::Directive directive)
[llvm-branch-commits] [mlir] [mlir][omp] Add omp.tile operation (PR #160292)
https://github.com/Meinersbur updated
https://github.com/llvm/llvm-project/pull/160292
>From ff4eccb41e2973e1179734dd455f1e797e89d9be Mon Sep 17 00:00:00 2001
From: Michael Kruse
Date: Tue, 23 Sep 2025 14:45:45 +0200
Subject: [PATCH] Add omp.tile operation
---
.../mlir/Dialect/OpenMP/OpenMPClauses.td | 29 ++
.../mlir/Dialect/OpenMP/OpenMPOpBase.td | 69 +++-
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 63 ++-
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 387 +++---
.../OpenMP/OpenMPToLLVMIRTranslation.cpp | 42 ++
.../Dialect/OpenMP/cli-canonical_loop.mlir| 127 --
mlir/test/Dialect/OpenMP/cli-tile.mlir| 138 +++
.../Dialect/OpenMP/cli-unroll-heuristic.mlir | 28 +-
mlir/test/Dialect/OpenMP/invalid-tile.mlir| 119 ++
.../test/Target/LLVMIR/openmp-cli-tile01.mlir | 101 +
.../test/Target/LLVMIR/openmp-cli-tile02.mlir | 190 +
mlir/test/mlir-tblgen/op-format-invalid.td| 2 +-
.../tools/mlir-tblgen/AttrOrTypeFormatGen.cpp | 1 +
mlir/tools/mlir-tblgen/FormatGen.cpp | 2 +-
mlir/tools/mlir-tblgen/OpFormatGen.cpp| 1 +
15 files changed, 1157 insertions(+), 142 deletions(-)
create mode 100644 mlir/test/Dialect/OpenMP/cli-tile.mlir
create mode 100644 mlir/test/Dialect/OpenMP/invalid-tile.mlir
create mode 100644 mlir/test/Target/LLVMIR/openmp-cli-tile01.mlir
create mode 100644 mlir/test/Target/LLVMIR/openmp-cli-tile02.mlir
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index 1eda5e4bc1618..8e43c4284d078 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -995,6 +995,35 @@ class OpenMP_NumTeamsClauseSkip<
def OpenMP_NumTeamsClause : OpenMP_NumTeamsClauseSkip<>;
+//===--===//
+// V5.1: [10.1.2] `sizes` clause
+//===--===//
+
+class OpenMP_SizesClauseSkip<
+bit traits = false, bit arguments = false, bit assemblyFormat = false,
+bit description = false, bit extraClassDeclaration = false
+ > : OpenMP_Clause {
+ let arguments = (ins
+Variadic:$sizes
+ );
+
+ let optAssemblyFormat = [{
+`sizes` `(` $sizes `:` type($sizes) `)`
+ }];
+
+ let description = [{
+The `sizes` clauses defines the size of a grid over a multi-dimensional
+logical iteration space. This grid is used for loop transformations such as
+`tile` and `strip`. The size per dimension can be a variable, but only
+values that are not at least 2 make sense. It is not specified what happens
+when smaller values are used, but should still result in a loop nest that
+executes each logical iteration once.
+ }];
+}
+
+def OpenMP_SizesClause : OpenMP_SizesClauseSkip<>;
+
//===--===//
// V5.2: [10.1.2] `num_threads` clause
//===--===//
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
index bbcfb87fa03c6..5ad4e4b5b61d1 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td
@@ -38,6 +38,44 @@ def OpenMP_MapBoundsType : OpenMP_Type<"MapBounds",
"map_bounds_ty"> {
let summary = "Type for representing omp map clause bounds information";
}
+//===-===//
+// OpenMP Canonical Loop Info Type
+//===-===//
+
+def CanonicalLoopInfoType : OpenMP_Type<"CanonicalLoopInfo", "cli"> {
+ let summary = "Type for representing a reference to a canonical loop";
+ let description = [{
+A variable of type CanonicalLoopInfo refers to an OpenMP-compatible
+canonical loop in the same function. Values of this type are not
+available at runtime and therefore cannot be used by the program itself,
+i.e. an opaque type. It is similar to the transform dialect's
+`!transform.interface` type, but instead of implementing an interface
+for each transformation, the OpenMP dialect itself defines possible
+operations on this type.
+
+A value of type CanonicalLoopInfoType (in the following: CLI) value can be
+
+1. created by omp.new_cli.
+2. passed to omp.canonical_loop to associate the loop to that CLI. A CLI
+ can only be associated once.
+3. passed to an omp loop transformation operation that modifies the loop
+ associated with the CLI. The CLI is the "applyee" and the operation is
+ the consumer. A CLI can only be consumed once.
+4. passed to an omp loop transformation operation to associate the cli with
+ a result of that transformation. The CLI is the "generatee" and the
+ operatio
[llvm-branch-commits] [clang] [analyzer] Revert #115918, so empty base class optimization works again (#157480) (PR #160450)
https://github.com/Xazax-hun approved this pull request. https://github.com/llvm/llvm-project/pull/160450 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] simplify placeholder type deduction for constant template parameters (PR #160439)
https://github.com/mizvekov created
https://github.com/llvm/llvm-project/pull/160439
This makes the deduction for dependent types operate in more similar ways to
the non-dependent one, such as when matching template template parameters,
making errors in those generate similar diagnostics to the non-dependent ones.
This also removes some superfluous implicit casts, simplifying the resulting
AST a little bit.
>From 87c83594790c3a5f0d9188e02a12c4b21eaa53fc Mon Sep 17 00:00:00 2001
From: Matheus Izvekov
Date: Wed, 24 Sep 2025 00:21:01 -0300
Subject: [PATCH] [clang] simplify placeholder type deduction for constant
template parameters
This makes the deduction for dependent types operate in more similar ways
to the non-dependent one, such as when matching template template parameters,
making errors in those generate similar diagnostics to the non-dependent ones.
This also removes some superfluous implicit casts, simplifying the resulting
AST a little bit.
---
clang/docs/ReleaseNotes.rst | 3 +-
clang/lib/Sema/SemaTemplate.cpp | 68 +--
clang/lib/Sema/SemaTemplateDeduction.cpp | 32 -
.../SemaTemplate/temp_arg_template_p0522.cpp | 10 +--
4 files changed, 52 insertions(+), 61 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 70c82b090107a..1932135ceed1b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -292,7 +292,8 @@ Improvements to Clang's diagnostics
"format specifies type 'unsigned int' but the argument has type 'int', which
differs in signedness [-Wformat-signedness]"
"signedness of format specifier 'u' is incompatible with 'c'
[-Wformat-signedness]"
and the API-visible diagnostic id will be appropriate.
-
+- Clang now produces better diagnostics for template template parameter
matching
+ involving 'auto' template parameters.
- Fixed false positives in ``-Waddress-of-packed-member`` diagnostics when
potential misaligned members get processed before they can get discarded.
(#GH144729)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index f051a246f954f..5a48ba0c344b7 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7068,22 +7068,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param,
QualType ParamType,
// If the parameter type somehow involves auto, deduce the type now.
DeducedType *DeducedT = ParamType->getContainedDeducedType();
- if (getLangOpts().CPlusPlus17 && DeducedT && !DeducedT->isDeduced()) {
-// During template argument deduction, we allow 'decltype(auto)' to
-// match an arbitrary dependent argument.
-// FIXME: The language rules don't say what happens in this case.
-// FIXME: We get an opaque dependent type out of decltype(auto) if the
-// expression is merely instantiation-dependent; is this enough?
-if (DeductionArg->isTypeDependent()) {
- auto *AT = dyn_cast(DeducedT);
- if (AT && AT->isDecltypeAuto()) {
-SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false);
-CanonicalConverted = TemplateArgument(
-Context.getCanonicalTemplateArgument(SugaredConverted));
-return Arg;
- }
-}
-
+ bool IsDeduced = DeducedT && !DeducedT->isDeduced();
+ if (IsDeduced) {
// When checking a deduced template argument, deduce from its type even if
// the type is dependent, in order to check the types of non-type template
// arguments line up properly in partial ordering.
@@ -7112,17 +7098,21 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl
*Param, QualType ParamType,
// along with the other associated constraints after
// checking the template argument list.
/*IgnoreConstraints=*/true);
- if (Result == TemplateDeductionResult::AlreadyDiagnosed) {
-return ExprError();
- } else if (Result != TemplateDeductionResult::Success) {
-if (const auto *NTTP = dyn_cast(Param)) {
- Diag(Arg->getExprLoc(),
- diag::err_non_type_template_parm_type_deduction_failure)
- << Param->getDeclName() << NTTP->getType() << Arg->getType()
- << Arg->getSourceRange();
+ if (Result != TemplateDeductionResult::Success) {
+ParamType = TSI->getType();
+if (StrictCheck || !DeductionArg->isTypeDependent()) {
+ if (Result == TemplateDeductionResult::AlreadyDiagnosed)
+return ExprError();
+ if (const auto *NTTP = dyn_cast(Param))
+Diag(Arg->getExprLoc(),
+ diag::err_non_type_template_parm_type_deduction_failure)
+<< Param->getDeclName() << NTTP->getType() << Arg->getType()
+<< Arg->getSourceRange();
+ NoteTemplateParameterLocation(*Param);
+ return ExprError();
}
-NoteTemplateParameterLocation(*Param);
-
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
@@ -3664,6 +3690,30 @@ struct MapInfoData : MapInfosTy {
MapInfosTy::append(CurInfo);
}
};
+
+enum class TargetDirective : uint32_t {
+ None = 0,
+ Target = 1,
+ TargetData = 2,
+ TargetEnterData = 3,
+ TargetExitData = 4,
+ TargetUpdate = 5
+};
TIFitis wrote:
Nit: Rename to something like `TargetDirectiveTy` or `TargetDirectiveEnumTy`
for clarity.
Also, should this be enclosed in a namespace?
https://github.com/llvm/llvm-project/pull/119589
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (PR #160573)
llvmbot wrote:
@llvm/pr-subscribers-flang-fir-hlfir
Author: Krzysztof Parzyszek (kparzysz)
Changes
---
Patch is 39.71 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/160573.diff
16 Files Affected:
- (modified) flang/include/flang/Parser/openmp-utils.h (-2)
- (modified) flang/include/flang/Parser/parse-tree.h (+8-2)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+6-8)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+3-15)
- (modified) flang/lib/Parser/unparse.cpp (+2-2)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+124-121)
- (modified) flang/lib/Semantics/check-omp-structure.h (-3)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+11-16)
- (modified) flang/lib/Semantics/resolve-names.cpp (+34-43)
- (modified) flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 (+16-12)
- (modified) flang/test/Parser/OpenMP/declare-target-to-clause.f90 (+8-6)
- (modified) flang/test/Parser/OpenMP/declare_target-device_type.f90 (+93-15)
- (modified) flang/test/Parser/OpenMP/enter-automap-modifier.f90 (+7-4)
- (modified) flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 (+5-4)
- (modified) flang/test/Semantics/OpenMP/blank-common-block.f90 (+1)
- (modified)
flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
(+1-1)
``diff
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index 4b8fe6a5b49f0..bf54f970a7d3a 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -41,7 +41,6 @@ struct ConstructId {
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
-MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -97,7 +96,6 @@ struct DirectiveNameScope {
} else if constexpr (std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
return MakeName(std::get(x.t).source, ConstructId::id);
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index be30a95763208..e7593d9875097 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4961,10 +4961,16 @@ struct OmpDeclareTargetSpecifier {
std::variant u;
};
+// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207],
+// [6.0:346-348]
+//
+// declare-target-directive -> // since 4.5
+//DECLARE_TARGET[(extended-list)] |
+//DECLARE_TARGET clause-list
struct OpenMPDeclareTargetConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclareTargetConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple t;
};
// OMP v5.2: 5.8.8
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index d2e865b3e1d0c..1cb3335abbd06 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(
static void getDeclareTargetInfo(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
-const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct,
+const parser::OpenMPDeclareTargetConstruct &construct,
mlir::omp::DeclareTargetOperands &clauseOps,
llvm::SmallVectorImpl &symbolAndClause) {
- const auto &spec =
- std::get(declareTargetConstruct.t);
- if (const auto *objectList{parser::Unwrap(spec.u)}) {
-ObjectList objects{makeObjects(*objectList, semaCtx)};
+
+ if (!construct.v.Arguments().v.empty()) {
+ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
symbolAndClause, /*automap=*/false);
- } else if (const auto *clauseList{
- parser::Unwrap(spec.u)}) {
-List clauses = makeClauses(*clauseList, semaCtx);
+ } else {
+List clauses = makeClauses(construct.v.Clauses(), semaCtx);
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index 0085576292ff5..bd080386c0aea 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1773,23 +1773,11 @@
TYPE_PARSER(sourced(construct(
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
Parser{}))
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (PR #160573)
llvmbot wrote:
@llvm/pr-subscribers-flang-semantics
@llvm/pr-subscribers-flang-parser
Author: Krzysztof Parzyszek (kparzysz)
Changes
---
Patch is 39.71 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/160573.diff
16 Files Affected:
- (modified) flang/include/flang/Parser/openmp-utils.h (-2)
- (modified) flang/include/flang/Parser/parse-tree.h (+8-2)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+6-8)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+3-15)
- (modified) flang/lib/Parser/unparse.cpp (+2-2)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+124-121)
- (modified) flang/lib/Semantics/check-omp-structure.h (-3)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+11-16)
- (modified) flang/lib/Semantics/resolve-names.cpp (+34-43)
- (modified) flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 (+16-12)
- (modified) flang/test/Parser/OpenMP/declare-target-to-clause.f90 (+8-6)
- (modified) flang/test/Parser/OpenMP/declare_target-device_type.f90 (+93-15)
- (modified) flang/test/Parser/OpenMP/enter-automap-modifier.f90 (+7-4)
- (modified) flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 (+5-4)
- (modified) flang/test/Semantics/OpenMP/blank-common-block.f90 (+1)
- (modified)
flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
(+1-1)
``diff
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index 4b8fe6a5b49f0..bf54f970a7d3a 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -41,7 +41,6 @@ struct ConstructId {
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
-MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -97,7 +96,6 @@ struct DirectiveNameScope {
} else if constexpr (std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
return MakeName(std::get(x.t).source, ConstructId::id);
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index be30a95763208..e7593d9875097 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4961,10 +4961,16 @@ struct OmpDeclareTargetSpecifier {
std::variant u;
};
+// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207],
+// [6.0:346-348]
+//
+// declare-target-directive -> // since 4.5
+//DECLARE_TARGET[(extended-list)] |
+//DECLARE_TARGET clause-list
struct OpenMPDeclareTargetConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclareTargetConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple t;
};
// OMP v5.2: 5.8.8
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index d2e865b3e1d0c..1cb3335abbd06 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(
static void getDeclareTargetInfo(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
-const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct,
+const parser::OpenMPDeclareTargetConstruct &construct,
mlir::omp::DeclareTargetOperands &clauseOps,
llvm::SmallVectorImpl &symbolAndClause) {
- const auto &spec =
- std::get(declareTargetConstruct.t);
- if (const auto *objectList{parser::Unwrap(spec.u)}) {
-ObjectList objects{makeObjects(*objectList, semaCtx)};
+
+ if (!construct.v.Arguments().v.empty()) {
+ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
symbolAndClause, /*automap=*/false);
- } else if (const auto *clauseList{
- parser::Unwrap(spec.u)}) {
-List clauses = makeClauses(*clauseList, semaCtx);
+ } else {
+List clauses = makeClauses(construct.v.Clauses(), semaCtx);
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index 0085576292ff5..bd080386c0aea 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1773,23 +1773,11 @@
TYPE_PARSER(sourced(construct(
IsDirective(llvm::omp::Directive::OMPD_decl
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
@@ -275,9 +275,21 @@ class MapInfoFinalizationPass return mapTypeFlag; mapFlags flags = mapFlags::OMP_MAP_TO | - (mapFlags(mapTypeFlag) & - (mapFlags::OMP_MAP_IMPLICIT | mapFlags::OMP_MAP_CLOSE | - mapFlags::OMP_MAP_ALWAYS)); + (mapFlags(mapTypeFlag) & mapFlags::OMP_MAP_IMPLICIT); + +// Descriptors for objects will always be copied. This is because the +// descriptor can be rematerialized by the compiler, and so the address +// of the descriptor for a given object at one place in the code may +// differ from that address in another place. The contents of the +// descriptor (the base address in particular) will remain unchanged +// though. +// TODO/FIXME: We currently cannot have MAP_CLOSE and MAP_ALWAYS on TIFitis wrote: This TODO/FIXME reads to me like a TODO for the Flang semantics/ MLIR op verifier? Or am I missing something? https://github.com/llvm/llvm-project/pull/119589 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
@@ -0,0 +1,35 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// This tests the replacement of operations for `declare target to` with the
+// generated `declare target to` global variable inside of target op regions
when
+// lowering to IR for device. Unfortunately, as the host file is not passed as
a
+// module attribute, we miss out on the metadata and entry info.
+
+module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu =
true, omp.is_target_device = true} {
+ // CHECK-DAG: @_QMtest_0Ezii = global [11 x float] zeroinitializer
+ llvm.mlir.global external @_QMtest_0Ezii() {addr_space = 0 : i32,
omp.declare_target = #omp.declaretarget} : !llvm.array<11 x f32> {
+%0 = llvm.mlir.zero : !llvm.array<11 x f32>
+llvm.return %0 : !llvm.array<11 x f32>
+ }
+
+ // CHECK-DAG: define weak_odr protected amdgpu_kernel void @{{.*}}(ptr
%{{.*}}) {{.*}} {
TIFitis wrote:
Nit: Should this be a `CHECK-LABEL` followed by `CHECK-DAGs`?
https://github.com/llvm/llvm-project/pull/119589
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
@@ -0,0 +1,30 @@ +! Test `declare target to` interaction with an allocatable with a non-default TIFitis wrote: Nit: The `to` clause doesn't appear in the test. https://github.com/llvm/llvm-project/pull/119589 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
https://github.com/TIFitis commented: LGTM overall. I've added some nits below. https://github.com/llvm/llvm-project/pull/119589 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
@@ -0,0 +1,44 @@ +! Test that checks an allocatable array can be marked `declare target to` and +! functions without issue. +! REQUIRES: flang, amdgpu + +! RUN: %libomptarget-compile-fortran-run-and-check-generic +module test +implicit none +integer, allocatable, dimension(:) :: alloca_arr +!$omp declare target(alloca_arr) + end module test + + program main +use test +implicit none +integer :: cycle, i + +allocate(alloca_arr(10)) + +do i = 1, 10 +alloca_arr(i) = 0 +end do + +!$omp target data map(to:alloca_arr) + + do cycle = 1, 2 + +!$omp target +do i = 1, 10 +alloca_arr(i) = alloca_arr(i) + i +end do +!$omp end target + +! NOTE: Technically doesn't affect the results, but there is a +! regression case that'll cause a runtime crash if this is +! invoked more than once, so this checks for that. +!$omp target update from(alloca_arr) TIFitis wrote: Nit: Indentation seems off. https://github.com/llvm/llvm-project/pull/119589 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Greedy: Merge VirtRegMap queries into one use (NFC) (PR #160485)
llvmbot wrote:
@llvm/pr-subscribers-backend-systemz
@llvm/pr-subscribers-backend-x86
Author: Matt Arsenault (arsenm)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/160485.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/RegAllocGreedy.cpp (+3-2)
``diff
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp
b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index dc23ab3ce9d2b..6957548ac6c7a 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2502,8 +2502,10 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
do {
Reg = RecoloringCandidates.pop_back_val();
+MCRegister CurrPhys = VRM->getPhys(Reg);
+
// This may be a skipped register.
-if (!VRM->hasPhys(Reg)) {
+if (!CurrPhys) {
assert(!shouldAllocateRegister(Reg) &&
"We have an unallocated variable which should have been handled");
continue;
@@ -2512,7 +2514,6 @@ void RAGreedy::tryHintRecoloring(const LiveInterval
&VirtReg) {
// Get the live interval mapped with this virtual register to be able
// to check for the interference with the new color.
LiveInterval &LI = LIS->getInterval(Reg);
-MCRegister CurrPhys = VRM->getPhys(Reg);
// Check that the new color matches the register class constraints and
// that it is free for this live range.
if (CurrPhys != PhysReg && (!MRI->getRegClass(Reg)->contains(PhysReg) ||
``
https://github.com/llvm/llvm-project/pull/160485
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (PR #160573)
https://github.com/kparzysz updated
https://github.com/llvm/llvm-project/pull/160573
>From 525f12fa0da6c22dded6c19e2338b6bcc3c2da6f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek
Date: Wed, 24 Sep 2025 07:59:16 -0500
Subject: [PATCH 1/3] [flang][OpenMP] Use OmpDirectiveSpecification in
DECLARE_TARGET
---
flang/include/flang/Parser/openmp-utils.h | 2 -
flang/include/flang/Parser/parse-tree.h | 10 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 14 +-
flang/lib/Parser/openmp-parsers.cpp | 18 +-
flang/lib/Parser/unparse.cpp | 4 +-
flang/lib/Semantics/check-omp-structure.cpp | 245 +-
flang/lib/Semantics/check-omp-structure.h | 3 -
flang/lib/Semantics/resolve-directives.cpp| 27 +-
flang/lib/Semantics/resolve-names.cpp | 77 +++---
.../OpenMP/declare-target-indirect-tree.f90 | 28 +-
.../OpenMP/declare-target-to-clause.f90 | 14 +-
.../OpenMP/declare_target-device_type.f90 | 108 ++--
.../Parser/OpenMP/enter-automap-modifier.f90 | 11 +-
.../OpenMP/openmp6-directive-spellings.f90| 9 +-
.../Semantics/OpenMP/blank-common-block.f90 | 1 +
...lare-target-function-name-with-symbols.f90 | 2 +-
16 files changed, 319 insertions(+), 254 deletions(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h
b/flang/include/flang/Parser/openmp-utils.h
index 4b8fe6a5b49f0..bf54f970a7d3a 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -41,7 +41,6 @@ struct ConstructId {
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
-MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
@@ -97,7 +96,6 @@ struct DirectiveNameScope {
} else if constexpr (std::is_same_v ||
std::is_same_v ||
std::is_same_v ||
- std::is_same_v ||
std::is_same_v ||
std::is_same_v) {
return MakeName(std::get(x.t).source, ConstructId::id);
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index be30a95763208..e7593d9875097 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4961,10 +4961,16 @@ struct OmpDeclareTargetSpecifier {
std::variant u;
};
+// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207],
+// [6.0:346-348]
+//
+// declare-target-directive -> // since 4.5
+//DECLARE_TARGET[(extended-list)] |
+//DECLARE_TARGET clause-list
struct OpenMPDeclareTargetConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
+ WRAPPER_CLASS_BOILERPLATE(
+ OpenMPDeclareTargetConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple t;
};
// OMP v5.2: 5.8.8
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index d2e865b3e1d0c..1cb3335abbd06 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(
static void getDeclareTargetInfo(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
-const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct,
+const parser::OpenMPDeclareTargetConstruct &construct,
mlir::omp::DeclareTargetOperands &clauseOps,
llvm::SmallVectorImpl &symbolAndClause) {
- const auto &spec =
- std::get(declareTargetConstruct.t);
- if (const auto *objectList{parser::Unwrap(spec.u)}) {
-ObjectList objects{makeObjects(*objectList, semaCtx)};
+
+ if (!construct.v.Arguments().v.empty()) {
+ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
symbolAndClause, /*automap=*/false);
- } else if (const auto *clauseList{
- parser::Unwrap(spec.u)}) {
-List clauses = makeClauses(*clauseList, semaCtx);
+ } else {
+List clauses = makeClauses(construct.v.Clauses(), semaCtx);
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
diff --git a/flang/lib/Parser/openmp-parsers.cpp
b/flang/lib/Parser/openmp-parsers.cpp
index 0085576292ff5..bd080386c0aea 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1773,23 +1773,11 @@
TYPE_PARSER(sourced(construct(
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
Parser{})))
-// declare-target with list
-TYPE_PARSER(sourced(construct(
-parenth
