[analyzer] Reject non-symbolic iterator offsets in alpha iterator checkers (#232622)
`evalBinOp()` can return a concrete value for a constrained iterator
offset. Storing `getAsSymbol()` from that result leaves a null offset in
the model, which is later dereferenced.
Return failure for non-symbolic results and let `++`/`--` fall back to a
fresh offset, preserving the container and the old position for postfix
results.
[Loads] Require step to be a multiple of alignment in isDereferenceable. (#237759)
Add missing check ensuring Step is also a multiple of the alignemnt in
isDereferenceableAndAlignedInLoop. Otherwise the loads in the loop may
not have the required alignment in all iterations.
[compiler-rt][Darwin] Split SANITIZER_IOS into SANITIZER_IOSLIKE and SANITIZER_IOS
SANITIZER_IOS is now TARGET_OS_IOS (iOS only), while the previous
meaning (TARGET_OS_IPHONE, iOS and iOS-like) is renamed SANITIZER_IOSLIKE.
Assisted-By: Claude
rdar://191534752
[Clang][OpenMP] Fix crashes on a `braced-init-list` in the `init` or increment of a loop (#233248)
Fixes #202562
The loop analysis kept the braced-init-list of `int i = {0}` (and of `i
+= {1}`) as the bound or step as written. The loop transformations copy
the trip count through a `TreeTransform`, which rebuilds a list without
a type, so `{0} - 1` fails to build and the transform asserts. Pointer
and aggregate-iterator counters hit a related assert even under plain
`omp for`, and the IRBuilder path crashed on a braced step.
The analysis now never keeps a bare list: a list wrapping one expression
becomes that expression, an empty or class-type list becomes the
`T{...}` node Sema builds for a functional cast. The IRBuilder loop path
uses the same helper for its step.
Assisted-by : LLM tools, reviewed and tested by me.
[CopyProf] Intercept new/delete and track per-object cost.
This intercepts the C++ `new` and `delete` operators, so that all
heap memory owned by a copy is tracked.
Using per-object state tracking, reports now tell the user how much
accumulated memory a copy is worth and whether it allocated.
This is useful for filtering of reports.
RFC: https://discourse.llvm.org/t/rfc-copysanitizer-csan-detecting-unneccessary-object-copies-at-runtime/91038
[CopyProf] Intercept C heap functions.
A copy that owns heap memory is only unnecessary if that memory is not
modified either. This intercepts the libc heap functions and routes them
to the CopyProf allocator, which marks memory allocated while copying as
copy, and checks the shadow memory of memory freed during destruction.
Memory allocated inside a d'tor is marked as copy as well, so that
freeing temporaries does not suppress reports.
Now that `malloc` is intercepted, `strndup` and `realpath` are
intercepted as well.
RFC: https://discourse.llvm.org/t/rfc-copysanitizer-csan-detecting-unneccessary-object-copies-at-runtime/91038
[CopyProf] Add standalone allocator.
Detecting modifications of heap memory owned by a copy requires hooking
all (de)allocations and knowing allocation sizes. This adds a CopyProf
specific allocator based on the sanitizer_common allocator.
It provides surrogates for the libc heap functions, which are hooked up
to interceptors in a subsequent patch.
RFC: https://discourse.llvm.org/t/rfc-copysanitizer-csan-detecting-unneccessary-object-copies-at-runtime/91038
Previous PR: #232851
[CopyProf] Add libc interceptors.
A copy is reported as unnecessary if neither the object nor any memory
it owns is modified before it is destroyed. So far, writes by
uninstrumented code, most importantly library functions (e.g. `memcpy`,
`memset`, etc.), are not accounted for, which leads to false positives.
Interceptors make these writes visible.
Additionally, objects constructed inside a d'tor are now marked as copy,
so that destroying temporaries (e.g. a string built for a log message)
does not suppress reports.
Note that `strndup` and `realpath` are not intercepted yet, as their
interceptors allocate memory via the `malloc` interceptor, which is only
added in a subsequent patch.
RFC:
https://discourse.llvm.org/t/rfc-copysanitizer-csan-detecting-unneccessary-object-copies-at-runtime/91038
Previous PR: #225905
[VPlan] Compute branch costs in VPlan. (#234377)
Compute the costs of branches in VPlan, replacing the legacy logic in
precomputeCost. We now compute the cost of branches in replicate regions
directly in VPRegionBlock::cost and VPBranchOnMaskRecipe::cost,
including the cost of the unconditional branches from the conditionally
execute block, as well between plain VPBBs (this is currently not used,
but in preparation for computing scalar costs + supporting conditional
blocks in plans).
The cost changes in tests are because we previously
* missed replicate regions (e.g. tail-folding in a loop without any
branches),
* overcounted conditional branches (e.g. because replicate regions could
be merged in VPlan, chains of conditional branches resulting in a single
replicate region)
PR: https://github.com/llvm/llvm-project/pull/234377
[ControlFlowHub] Do not replace undef with poison in reconnectPhis (#237407)
When every value moved from a PHI into the new PHI in the first guard
block is undef or poison, reconnectPhis uses a constant instead of
creating the PHI. Since #103013 that constant has always been poison,
which is wrong when some of the values are undef: the program becomes
less defined. For example, "and i32 %p, 0" is 0 for an undef %p but
poison for a poison %p.
Use poison only if all the moved values are poison, and undef otherwise,
as before #103013.
This affects both FixIrreducible and UnifyLoopExits. The second test in
FixIrreducible/undef-phis.ll is not affected by this change yet, but
guards against fixing the self-loop handling in reconnectPhis (#232399)
without this fix: that would make all of %p's moved values undef and
replace them with poison.
Fixes #235378.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[NFC][Attributor] Reach fixpoint in call site AACallEdges for direct calls
A direct call whose callee has no callback metadata only calls its callee, so
its call site AACallEdges cannot change after initialization. Add the edge in
initialize and reach a fixpoint there, instead of updating the attribute twice
to find out. AACallEdgesFunction already skips the call site attribute for such
calls since #232616; both now share getOnlyCallee().
Other attributes still create call site AACallEdges for direct calls, e.g.,
AAInterFnReachability and the AMDGPU attributor. On a generated module with
2,001 functions and 15,986 calls, this removes all updates of call site
AACallEdges. The total number of updates goes from 304,263 to 272,291 with
-passes=attributor, from 207,815 to 175,843 with -passes=attributor-light, and
from 35,977 to 16,005 with -passes=amdgpu-attributor. The wall time does not
change measurably on that module, because these updates are cheap.
This PR was assisted by AI but I reviewed all the changes.