[ConstraintElim] Bound non-increasing header IVs by start value. (#217921)
Generalize addLowerBoundsForHeaderInductions to also support bounding
decrementing IVs: if the IV gets decremented w/o wapping in the signed
sense, it will never exceed the start value and we can add PN s<=
StartValue.
This helps to remove a number of branches in real-world workloads:
https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/984
Note that in a few instances (found 2), the removed branches result in
flags dropped. We should be able to recover those (and more) by using
info from ConstrantElimination to strengthen flags.
Alive2 Proof: https://alive2.llvm.org/ce/z/7t_xHX
PR: https://github.com/llvm/llvm-project/pull/217921
[libunwind] Make Apple OS version XFAILs robust to patch-level versions (#218125)
We are seeing some failures since some of the Apple CI runners have been
updated to 26.5.2. That was caused by the regular expressions not
matching patch level version bumps.
[EarlyIfConversion] Extend data dependent analysis across multiple blocks (#180623)
This extends the new data dependent analysis for branches to cover loads
which feed conditions which are not within the same Machine Basic Block.
To still try to catch loads which are "close in program time" we
limit on the number of instructions between the branch and the
load. We also bail out if we detect a function call or loop between the two
instructions.
[mlir][SCF] Skip dynamic peeling for non-index loops (#217909)
`scf-for-loop-peeling` constructs an `affine.apply` on its dynamic path
to compute the split bound. However, `affine.apply` requires `index`
operands, while `scf.for` also permits signless integer induction
variables and bounds.
Skip the dynamic peeling path when the loop induction variable is not
`index`. The existing constant-bounds path remains unchanged, so
constant integer loops can still be peeled.
Add a regression test for a loop with dynamic `i32` bounds, verifying
that the pass leaves it unchanged rather than producing invalid IR.
Fixes #216631.
Co-authored-by: Purnima Shrivastava <purnimashrivastava05@.com>
[mlir][scf] Do not read non-constant loop bounds when unrolling (#217392)
`loopUnrollByFactor` asserts `expected constant loop bound`
(`SCF/Utils/Utils.cpp`) when the loop bounds are not constant.
`getStaticTripCount` takes the constant path whenever
`constantTripCount` answers, but `constantTripCount` answers on three
shapes where the bounds themselves are **not** constant:
- `lb == ub` (same `Value`), giving 0 iterations,
- `lb == 0` and `ub == step`, giving 1 iteration,
- `ub` a constant offset from a non-constant `lb`, via
`computeUbMinusLb` under `nsw`.
In all three the code then reads the bounds as constants and asserts.
The fix takes the constant path only when `lb`, `ub` and `step` are all
constant, and otherwise falls through to the dynamic path that already
handles them. The other two callers of `getStaticTripCount` in that file
use only the count, never the bounds, so the defect is confined to this
[4 lines not shown]
[CIR] Emit lifetime markers for automatic variables (#206695)
### summary
This is a follow up of : #199599
Per the consensus from the PR #199599, this implements lifetime-marker
emission in ClangIR that closely follows classic CodeGen.
Emit lifetime markers (cir.lifetime.start/end) for automatic variables
in ClangIR.
- Gated by shouldEmitLifetimeMarkers (optimized builds or
ASan-use-after-scope/
HWASan/MSan/MemtagStack), like classic CodeGen.
- start at the decl; end as a NormalEHLifetimeMarker cleanup (after the
destructor);
both target the underlying alloca. Wired through the EH stack so they
don't force
[6 lines not shown]
[mlir][tensor][bufferization] Preserve memory space for tensor.concat (#213528)
## Summary
- Use the buffer type selected for the destination `alloc_tensor` when
bufferizing `tensor.concat`.
- Pass that type to `ToBufferOp` instead of reconstructing a
default-memory-space `MemRefType`.
- Use the same type for the destination subviews, preserving its memory
space and layout.
- Add an encoding-based regression test for a non-default destination
memory space.
## Motivation
While investigating `tensor.concat` bufferization with a non-default
memory space, I reproduced a mismatch between the destination allocation
type and the type requested by `ToBufferOp`.
[40 lines not shown]
[git-clang-format] Don't format the line preceding a deletion (#215946)
`git diff -U0` renders a pure deletion as `@@ -3,3 +2,0 @@`: no new
lines,
anchored at the preceding line. extract_lines coerces that zero count to
one, so clang-format reformats a line the deletion never touched.
Skip such hunks, matching clang-format-diff.py. start_line is 0 only for
deletions at the start of a file, so that check goes away as well.
Aided by Claude Opus 5
[RISCV][NFCI] Introduce Base for Pseudo Expansion Passes (#218170)
This introduces a base class for the Pseudo Instruction Expansion Pass
Implementations, which shares the boiler plate that ensures the function
size estimate does not grow during expansion.
This also makes many of those methods `const`, to more clearly
illustrate how the Impl class works - that per-instruction info is
mostly passed as parameters and not stored in the class members.
This is used to simplify all four of the Pseudo Instruction Expansion
passes. Additionally, many static functions in the Atomic Expand pass
are moved onto the Impl class, so they can directly access the subtarget
and instruction info.
Assisted-by: AI
[clang-repl] Don't double-remove extern "C" decls from the IdResolver (#218129)
Regression was introduced in https://github.com/llvm/llvm-project/pull/178648
This is required for the 23 release; the downstream tools CppInterOp & Cppyy will fail otherwise.
[clang][Driver] Fix libc++ include path on FreeBSD (#212725)
`clang++` defaults to `-stdlib=libc++` on FreeBSD. When building with
both `clang` and `libcxx` included, the freshly built `clang++` uses the
system version of the `libc++` headers. However, this is from the
bundled `libc++` 19.1.7, thus inconsistent with the `libc++` being
built.
Similarly to the NetBSD case, FreeBSD has its own version of
`addLibCxxIncludePaths` which just includes `/usr/include/c++/v1`.
This patch removes `FreeBSD::addLibCxxIncludePaths` in favour of the
generic version in `Gnu.cpp`.
Tested on `amd64-pc-freebsd15.1`.
[Verifier] Prevent insertion/extraction of scalable vectors into/from fixed vectors (#215647)
Per LangRef:
> Scalable vectors can only be inserted into other scalable vectors.
> (...)
> Scalable vectors can only be extracted from other scalable vectors.
Add checks to enforce these rules for `llvm.vector.insert` and
`llvm.vector.extract` intrinsics.
[DomTree] Prepend children instead of appending (#218178)
Follow-up to #176409: `AppendPtr` exists only to keep a node's children
in the order they are added, and a lot of code depends on the order.
Implement an altrenative: in `attachNewSubtree`, create nodes in DFS
order and then link them in reverse. Trees built from scratch are
unchanged. Two tests that print an updated tree are adjusted.
[flang][test] Link designator-path test with FortranParser (#218204)
This is the missing build dependency that wasn't added to
https://github.com/llvm/llvm-project/pull/211606.
It should resolve a some of the build bot failures that have been
reported there.
[clang][bytecode] Use a SmallPtrSet in collectBlocks() (#218192)
Not sure why I used a SetVector here, but switch it to a SmallPtrSet
(this also gets rid of an additional include when #186045 gets merged).
[MLIR][Python] Don't throw in PyDenseArrayIterator dunderNext (#218193)
`PyDenseArrayIterator::dunderNext` signaled iterator exhaustion by
throwing `nanobind::stop_iteration()`. Raising a C++ exception to signal
`StopIteration` incurs stack-unwinding cost on every loop over a dense
array attribute.
#175377 replaced this pattern with `PyErr_SetNone(PyExc_StopIteration)`
(return a null object after setting the Python error indicator) for the
other iterators in the bindings. `PyDenseArrayIterator` was missed in
that change and still throws. This PR applies the same conversion to
`PyDenseArrayIterator::dunderNext`.
Assisted by: Claude
[FoldingSet] Invalidate iterators on mutation (#218179)
Tighten FoldingSet's iterator contract so that, like DenseMap (#199369)
and StringMap (#202237), mutating the set invalidates iterators obtained
before the call. insert / remove (successful) / clear / move bump the
epoch, so a stale iterator fails under LLVM_ENABLE_ABI_BREAKING_CHECKS.
LLM-aided
Reapply "[llc] Register pass plugin callbacks with the new pass manager" (#217727) (#218163)
Reapplies #217727 (aa8d1afeed37), reverted in #218119 (91b04b4d45d9).
The test hardcoded Clang's spelling of an anonymous namespace in
--print-pipeline-passes output. The pass name comes from getTypeName(),
which scrapes __PRETTY_FUNCTION__; that spells anonymous namespaces as
"(anonymous namespace)" under Clang but "{anonymous}" under GCC. Relax
the FileCheck pattern so it is compiler-agnostic.