[SSAF][PointerFlow] Change unsafe-buffer reachability analysis back to simple graph search
Because of commit 30cd4297b, we no longer need unsafe-buffer
reachability analysis to "uncompress" pointer flow graphs. It can go
back to simple DFS. Since it deals with large data, simplicity is
important.
In addition, unit tests for the "compressed" pointer flow graphs are
moved to lit tests because they are no longer suitable as WPA unit
tests. As lit tests, they are end-to-end tests where the extractor is
involved and is responsible for generating "uncompressed" graphs.
Final step of
rdar://183529483
[SSAF][PointerFlow] A pointer assignment may yield more than one edge (#218207)
This commit is a redesign of #198889, which introduced a non-termination
bug.
Problem:
The current pointer-flow graph has exactly one edge corresponding to an
assignment in the source code. For example, a pointer assignment p = q;
results in an edge `(p, i) -> (q, j)` for some pointer levels i and j.
In unsafe buffer propagation, the edge encodes the meaning that if `p`
is bounded, so must `q` be; additionally, if `*p (or p[x])` is bounded,
so must `*q (or q[y])` be; and so on until the maximum pointer level of
`p` or `q` is reached.
Therefore, during the graph search (WPA phase), a node `(p, i+1)` can
reach `(q, j+1)` through the edge `(p, i) -> (q, j)`. This is correct
ONLY when `p` and `q` have compatible types, which is true for most
cases due to type checking. However, this assumption does not hold in
the presence of reinterpreting casts—a pointer assignment `a = (T)b`
[31 lines not shown]
[MCParser] Share identifier character set with isMacroArgChar (#219084)
Move the predicate to the header so that it can be used by the macro
argument name checker. Replace the incorrect local-sensitive isalnum()
with ASCII-only llvm::isAlnum(). Identifier character set accepting '?'
is a MC extension: https://reviews.llvm.org/D1978
While here, fix some minor bound checking related minor issues.
LLM-aided
[unittests][IR] Fix VPIntrinsicTest after removal of trivial VP intrinsics (#219454)
ad9138f6b784 removed llvm.vp.{add,sub,mul,and,or,xor,ashr,lshr,shl} but
didn't update VPIntrinsicTest.cpp, which still declared/used them. The
test still passes today only because UpgradeCallsToIntrinsic silently
erases these now-unregistered bare declarations during parsing (no call
sites to rewrite), so the test never actually exercises them. Drop them
from BinaryIntOpcodes and switch llvm.vp.mul to llvm.vp.sdiv in
CanIgnoreVectorLength/VPReductions.
---------
Co-authored-by: Claude Sonnet 5 <noreply at anthropic.com>
[SSAF][EntityPointerLevel] Add an intermediate data structure DeclPointerLevel (#218196)
This is the first of three patches aimed at solving a non-termination
problem when using DFS in the pointer-flow graph.
Problem & context:
Currently, the pointer-flow graph creates exactly one edge corresponding
to an assignment in the source code. For example, a pointer assignment
`p = q;` results in an edge `(p, i) -> (q, j)` for some pointer levels
`i` and `j`. In unsafe buffer propagation, this edge encodes the meaning
that if `p` is bounded, `q` must also be bounded. Additionally, if
`*p/p[x]` is bounded, `*q/q[y]` must be bounded, and so on until the
maximum pointer level of `p` or `q` is reached.
Because of this, during DFS, a node `(p, i+1)` can reach `(q, j+1)`
through the edge `(p, i) -> (q, j)`. This logic is correct only when `p`
and `q` have compatible types, which is true for most cases due to
standard type checking. However, this assumption breaks down with
pointer casts. A cast like `a = (T)b` contributes an edge `(a, x) -> (b,
[25 lines not shown]
[ORC] Have ProxySpec call callWrapperAsync directly (#219673)
ProxySpec now drives shared::WrapperFunction<SPSSigT>::callAsync itself,
supplying a Caller that forwards to ExecutionSession::callWrapperAsync,
rather than going through ExecutionSession::callSPSWrapperAsync (which
does the same thing internally). This is a step towards removing
callSPSWrapperAsync (and other SPS-specific call APIs) from
ExecutionSession, so that callWrapperAsync remains the only core call
primitive and SPS is not baked into the core APIs.
[mlir][SparseTensor] Fix crash demapping alloc_tensor with a copy operand (#219319)
`TensorAllocDemapper` reconstructs demapped level sizes for a
`bufferization.alloc_tensor`/`tensor.empty` by pairing each dynamic
result
dimension with an entry from the op's `dynamic_sizes` operand list,
popping via
`ValueRange::front()`.
When an `alloc_tensor` has a `copy` operand instead of explicit dynamic
sizes,
`dynamic_sizes` is legitimately empty — the op's own verifier requires
that the
sizes are implied by the copy operand and must not be specified — so
`front()`
was called on an empty range and asserted:
```
llvm/include/llvm/ADT/STLExtras.h:1253: Assertion `!empty() && "expected non-empty range"' failed.
[20 lines not shown]
[VPlan] Compute SCEV for SDiv with non-negative operands. (#219715)
If both operands of an SDiv are known non-negative, it is equivalent to
an UDiv, mirroring ScalarEvolution's handling in createSCEV.
Adds m_SDiv to VPlanPatternMatch.
Alive2 Proof: https://alive2.llvm.org/ce/z/NYa6Vd
[LLVM][NFC] Make metadata-number checks robust (#219610)
These checks care about the metadata attached to an instruction or
reported in a diagnostic, not the incidental numeric slot assigned while
printing. Match metadata slot numbers with FileCheck patterns so
numbering changes do not require unrelated test updates.
[SLP]Recognize interchangeable cmp predicates with boundary constants
Treat boundary comparisons canonicalized to eq/ne (e.g. x <u 1 became
x == 0) as interchangeable with the rest of the bundle by adjusting
the compared constant, emitting a single vector compare.
Fixes #190505
Reviewers: RKSimon, bababuck
Pull Request: https://github.com/llvm/llvm-project/pull/218237
[clang-tools-extra] Add separate CLANG_TOOLS_EXTRA_INCLUDE_TESTS option (#215761)
clang-tools-extra tests depend on the llvm-bcanalyzer CMake target,
which exists in LLVM's CMake project but is not visible when Clang is
built separately from LLVM. This causes CMake errors when
CLANG_INCLUDE_TESTS is ON but the LLVM tools are not available.
This patch introduces CLANG_TOOLS_EXTRA_INCLUDE_TESTS as a separate
CMake option to control clang-tools-extra tests independently, allowing
users to build Clang with tests enabled (CLANG_INCLUDE_TESTS=ON) while
disabling clang-tools-extra tests (CLANG_TOOLS_EXTRA_INCLUDE_TESTS=OFF)
when building Clang separately from LLVM.
For backwards compatibility, CLANG_INCLUDE_TESTS=OFF continues
to turn off clang-tools-extra tests as well.
[analyzer] Fix handling of zero-sized elements in ArrayBound (#218712)
Previously the `security.ArrayBound` checker mishandled the following C
code under non-windows platforms where `sizeof(struct Empty) == 0`:
```c
struct Empty {};
struct Empty Array[10];
struct Empty foo(void) { return Array[5]; }
```
Here the checker produced a false positive with explanation "Access of
'Array' at byte offset 0, while it holds only 0 byte" -- that is, the
checker said that this accesses the past-the-end pointer, which is
usually invalid.
This commit suppresses this false positive by saying that accessing a
zero-sized object starting at the past-the-end pointer is valid.
This is implemented by adding an `AlsoAcceptEquality` flag for
`checkBounds`. This flag will also be useful for implementing checkers
[4 lines not shown]
[lld][WebAssembly] Do not coalesce segments with differing flags in -r (#219606)
In PR #210747 (commit 162d9f09299d), `addInputSegment` was changed to
union segment linking flags (`linkingFlags |= inSeg->flags`) so that
flags like `RETAIN` and `STRINGS` are preserved in `--relocatable`
output.
However, coalescing segments with differing linking flags by name alone
forces one chunk's semantics onto another:
- Clang emits ordinary string literals (`STRINGS`) and string literals
containing embedded null characters (non-`STRINGS`) into sections
named `.rodata..L.str`. When coalesced, non-mergeable segments
received the `STRINGS` flag, causing downstream links to split and
corrupt them.
- Similarly, coalescing a chunk with `RETAIN` and a chunk without
`RETAIN` forces the un-retained chunk to inherit `RETAIN`, preventing
`--gc-sections` from discarding it if it is unused.
Fix this by distinguishing segments by their linking flags in
[3 lines not shown]