undf: assign 768-770; stamp minio patches
This commit is contained in:
parent
cb853893e5
commit
79a77db4f8
28 changed files with 176 additions and 18 deletions
|
|
@ -0,0 +1,39 @@
|
|||
# UNDF: UNDF-2026-000000152
|
||||
# UNDF: (leave blank)
|
||||
# CWE-407: DAGCombiner::visitTokenFactor uses is_contained(TFs, ...) O(N²)
|
||||
#
|
||||
# In visitTokenFactor, the TFs worklist (SmallVector<SDNode*, 8>) deduplicates
|
||||
# entries using llvm::is_contained(), which is O(N) per check. The outer loop
|
||||
# iterates over TFs as it grows, yielding O(T²) where T is the number of
|
||||
# inlined token factors (bounded by TokenFactorInlineLimit, default 2048).
|
||||
#
|
||||
# Meanwhile, the Ops dedup already uses SmallPtrSet<SDNode*, 16> (SeenOps).
|
||||
# The fix is to add a SmallPtrSet for TFs membership checking, mirroring the
|
||||
# existing SeenOps pattern.
|
||||
#
|
||||
# Severity: MEDIUM — up to 2048² = 4M linear scans during DAG combining,
|
||||
# which runs on every function compiled. In practice bounded by
|
||||
# TokenFactorInlineLimit but quadratic within that bound.
|
||||
#
|
||||
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
|
||||
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
|
||||
@@ -2246,6 +2246,7 @@
|
||||
SmallVector<SDNode *, 8> TFs; // List of token factors to visit.
|
||||
SmallVector<SDValue, 8> Ops; // Ops for replacing token factor.
|
||||
SmallPtrSet<SDNode*, 16> SeenOps;
|
||||
+ SmallPtrSet<SDNode*, 16> SeenTFs; // O(1) dedup for TFs worklist
|
||||
bool Changed = false; // If we should replace this token factor.
|
||||
|
||||
// Start out with this token factor.
|
||||
TFs.push_back(N);
|
||||
+ SeenTFs.insert(N);
|
||||
|
||||
// Iterate through token factors. The TFs grows when new token factors are
|
||||
// encountered.
|
||||
@@ -2280,7 +2282,7 @@
|
||||
case ISD::TokenFactor:
|
||||
- if (Op.hasOneUse() && !is_contained(TFs, Op.getNode())) {
|
||||
+ if (Op.hasOneUse() && SeenTFs.insert(Op.getNode()).second) {
|
||||
// Queue up for processing.
|
||||
TFs.push_back(Op.getNode());
|
||||
Changed = true;
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# UNDF: (leave blank)
|
||||
# CWE-407: HotColdSplitting getOutliningPenalty Region membership O(R²)
|
||||
#
|
||||
# In getOutliningPenalty, Region is an ArrayRef<BasicBlock*>. Two nested
|
||||
# loops call is_contained(Region, ...) for successor/predecessor membership:
|
||||
#
|
||||
# 1) Line 322: for BB in Region → for SuccBB in successors(BB) →
|
||||
# is_contained(Region, SuccBB) → O(R² × S)
|
||||
#
|
||||
# 2) Line 340: for ExitBB → for PHI → for incoming →
|
||||
# is_contained(Region, getIncomingBlock) → O(E × P × V × R)
|
||||
#
|
||||
# Fix: build a SmallPtrSet<BasicBlock*> from Region once at function entry,
|
||||
# then use O(1) set lookups instead of O(R) linear scans.
|
||||
#
|
||||
# Severity: MEDIUM — cold regions in large functions can have hundreds of
|
||||
# blocks; HotColdSplitting runs as part of the default optimization pipeline.
|
||||
#
|
||||
--- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
|
||||
+++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
|
||||
@@ -299,6 +299,9 @@
|
||||
static int getOutliningPenalty(ArrayRef<BasicBlock *> Region,
|
||||
unsigned NumInputs, unsigned NumOutputs) {
|
||||
int Penalty = SplittingThreshold;
|
||||
+ // Build a set for O(1) region membership tests (was O(R) linear scan).
|
||||
+ SmallPtrSet<BasicBlock *, 16> RegionSet(Region.begin(), Region.end());
|
||||
+
|
||||
LLVM_DEBUG(dbgs() << "Applying penalty for splitting: " << Penalty << "\n");
|
||||
|
||||
// If the splitting threshold is set at or below zero, skip the usual
|
||||
@@ -321,7 +324,7 @@
|
||||
|
||||
for (BasicBlock *SuccBB : successors(BB)) {
|
||||
- if (!is_contained(Region, SuccBB)) {
|
||||
+ if (!RegionSet.count(SuccBB)) {
|
||||
NoBlocksReturn = false;
|
||||
SuccsOutsideRegion.insert(SuccBB);
|
||||
}
|
||||
@@ -340,7 +343,7 @@
|
||||
int NumIncomingVals = 0;
|
||||
for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i)
|
||||
- if (llvm::is_contained(Region, PN.getIncomingBlock(i))) {
|
||||
+ if (RegionSet.count(PN.getIncomingBlock(i))) {
|
||||
++NumIncomingVals;
|
||||
if (NumIncomingVals > 1) {
|
||||
++NumSplitExitPhis;
|
||||
Loading…
Add table
Add a link
Reference in a new issue