java-topology/defects/llvm/unit/LlvmTest.java
russell@unturf.com d0cb5fa834 llvm-0006: PartialInlining IsSingleExit BlockList is_contained O(N^2)
CWE-407: is_contained(BlockList, Succ) inside nested for loops in
computeOutliningColdRegionsInfo. Fix: SmallPtrSet for O(1) membership.
GCC deep scan: CLEAN (bitmaps/hash_sets throughout).
2026-03-30 10:34:02 -04:00

77 lines
2.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import java.util.*;
/**
* CWE-407 unit tests for LLVM defects (new: llvm-0006).
*
* llvm-0006: PartialInlining IsSingleExit — is_contained(BlockList, ...) O(N²)
*
* (llvm-0001 through llvm-0005 have separate unit tests or are covered
* by LlvmAliasSetTest.java, LlvmDomConditionCacheTest.java, etc.)
*/
public class LlvmTest {
// ---------------------------------------------------------------
// llvm-0006: PartialInlining IsSingleExit BlockList membership
// is_contained(BlockList, Succ) inside nested for loops → O(N² × S)
// ---------------------------------------------------------------
/** Defective: linear scan for block list membership */
static int isSingleExitDefective(int blockCount) {
List<Integer> blockList = new ArrayList<>();
for (int i = 0; i < blockCount; i++) blockList.add(i);
int ops = 0;
for (int block : blockList) {
// Each block has ~2 successors
int[] successors = { block + 1, block + blockCount / 3 };
for (int succ : successors) {
// Linear scan: is_contained(BlockList, Succ)
for (int b : blockList) {
ops++;
if (b == succ) break;
}
}
}
return ops;
}
/** Fixed: SmallPtrSet for block list membership */
static int isSingleExitFixed(int blockCount) {
Set<Integer> blockSet = new HashSet<>();
for (int i = 0; i < blockCount; i++) blockSet.add(i);
int ops = 0;
for (int block = 0; block < blockCount; block++) {
int[] successors = { block + 1, block + blockCount / 3 };
for (int succ : successors) {
ops++; // O(1) hash lookup
blockSet.contains(succ);
}
}
return ops;
}
// ---------------------------------------------------------------
// Test runner
// ---------------------------------------------------------------
static void check(String name, boolean cond) {
System.out.println((cond ? "PASS" : "FAIL") + " " + name);
if (!cond) System.exit(1);
}
public static void main(String[] args) {
// llvm-0006: PartialInlining IsSingleExit
{
int N = 500;
int defectOps = isSingleExitDefective(N);
int fixedOps = isSingleExitFixed(N);
double ratio = (double) defectOps / fixedOps;
System.out.printf("llvm-0006: defect=%d fixed=%d ratio=%.1fx%n", defectOps, fixedOps, ratio);
check("llvm-0006-quadratic", defectOps > fixedOps * 10);
check("llvm-0006-fixed-linear", fixedOps <= N * 3);
}
System.out.println("ALL PASS");
}
}