java-topology/defects/llvm/patch/llvm-0001-dagcombiner-visitTokenFactor-SmallVector-is_contained-O-N2.patch

39 lines
1.7 KiB
Diff

# 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;