[SandboxVec][LoadStoreVec] Move legality checks to LegalityAnalysis (NFC) (#234783)
Up until now the LoadStoreVec was using a custom legality checker. This
patch is the first step towards unifying and sharing the legality checks
across the passes.
[flang] Do not hoist loop-like operations in LICM (#236056)
Hoisting a loop out of the loop it is nested in changes how it is
scheduled relative to the iterations of the enclosing loop. For example,
an inner loop of an OpenACC parallel loop that ends up outside of the
parallel loop is no longer executed by every iteration of it, and can
then be mapped to parallel dimensions on its own and compute wrong
results.
Skip operations implementing LoopLikeOpInterface, including when they
are nested in a hoistable operation.
[offload][OpenMP][NFC] Add a default-grid run to the no-loop tests
Add a run without OMP_NUM_TEAMS and OMP_TEAMS_THREAD_LIMIT to show the
kernels are promoted with the runtime's default grid as well.
[NFC] Change strided loop name
Changes strided loop to be named grid-stride loop instead for less
ambiguity as stride describes the jump distance in general.
[clang][OpenMP] Add strided-loop SPMD kernel promotion
A target teams distribute parallel for is only promoted when every
iteration is guaranteed a thread. Without the oversubscription
assumptions, or with a num_teams clause, it is emitted as nested
worksharing loops, while Flang runs the same region as a grid-stride
loop.
Promote these kernels too, so the loop body strides across the grid,
and tag them SPMD_STRIDED_LOOP so the launch can be told apart from
plain SPMD. This allows teams loop and target teams loop to always get
optimized. Since those can carry lastprivate(conditional:), the
promoted path has to track it.
[SCEV] Avoid predicate switch (NFC) (#236157)
The logic is basically the same in all four cases, implement it
once using getNonStrictPredicate + getSwappedPredicate.
[DAGCombiner] Fold extract + scalar2vec at lane 0 (#233856)
When extracting a scalar at index 0 from a vector and immediately
creating a new fixed-length vector with one lane only, we can just fold
that pattern into an extract_subvector pattern, given that the vector
element types align.
This removes redundant moves for vector reductions when the return is
handled as a one element vector.
These moves are not required when the result is in lane 0 already.
I used codex to generate the test cases.
[clang][OpenMP] Extend no-loop promotion to the split teams loop
Widen the no-loop promotion to apply not only to the fused target teams
distribute parallel for but include the same region written as separate
directives, other directives promotable to parallel for, and regions
carrying a schedule clause that asks for a mapping a no-loop kernel
already provides.
Use the SPMD_NO_LOOP kernel tag to carry the promotion decision, based
on whether the kernel can get fully promoted to a no-loop kernel. This
eliminates the previous discrepancy where a clause got the tag but not
the promotion.
[IndVarSimplify][NFC] Add tests for loop-invariant samesign compares (#236092)
Add tests for replacing a samesign compare of an IV with a
loop-invariant value by its value on loop entry.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[SCEV] Drop samesign in getLoopInvariantPredicate (#236093)
SCEV's `getLoopInvariantPredicate` tries to replace a comparison of an
IV against a loop-invariant value with the comparison value on loop
entry.
For that it tries to prove that the comparison is:
- (A) monotonic: i.e. if `c_i` is true, then `c_{i+1}` is true,
- (B) guards the backedge: the backedge is taken only if `c_i` is true.
Then each `c_i` may be replaced with `c_0`.
It works for the `icmp` instruction without the `samesign` flag.
With the `samesign` flag, however, the comparison is poison when its
operands have different signs.
To prove the backedge guard (B), we may rely on picking that poison as
true, while proving the monotonicity (A) may need the same poison to be
[28 lines not shown]
[clang][OpenMP] Emit lastprivate final copies in no-loop kernels
Promotion rejected lastprivate because the no-loop branch leaves the
worksharing path before it privatizes or copies out, so the clause would
have been silently dropped.
Privatize the non-counter variables in the parallel region and copy them
out under the last iteration that applyWorkshareLoop publishes, forcing
the exit barrier the copy reads through. Loop counters stay at the
distribute level and reach EmitOMPSimdFinal.
[AMDGPU] Take the VGPR and AVGPR maximum pressure from one point
max() of two GCNRegPressure values takes the VGPR and AVGPR counts from the operand with the larger sum of both. It does the same for the VGPR and AVGPR tuple weights. The SGPR and AGPR components still take the maximum of each component.
dumpMaxRegPressure() resets the maximum of the tracker before each instruction. It now compares the pressure of single instructions and does not depend on how max() combines two values.
Fix the expectations of the GCNRegPressureTest tests for this case. Add sched-max-pressure-different-points.mir and update the checks of the affected tests. rewrite-vgpr-mfma-to-agpr-spill-multi-store-mir.mir now uses the basic register allocator, as its sibling .ll test does since #226913.
[AMDGPU][NFC] Add unit tests for the maximum of GCNRegPressure over a block
The tests run GCNDownwardRPTracker and GCNUpwardRPTracker over one block and check the accumulated maximum pressure. In the block, an AV register is live first and a VGPR is live after it, so only one vector register is live at any point. The tests use 32-bit registers, and 64-bit registers for the tuple weights. The expectations show the current results, with a FIXME: the maximum adds the AV peak to the VGPR peak.
[ConstantFold] Use isImpliedByMatchingCmp() (NFC) (#236149)
Instead of reimplementing it, badly. The non-strict cases had some
incorrect entries (e.g. ule does not imply that ult is true). We got
away with this because those predicates are never returned by
evaluateICmpRelation().
[InstCombine] Remove redundant fold for shift of add of zexts (NFCI) (#236141)
The earlier `(X + Y) / 2 --> (X & Y) iff (X u<= 1) && (Y u<= 1)` fold
subsumes this special case where X/Y are zext of i1.
[MLIR][MathToXeVM][NFC] Remove a dead lit.local.cfg (#232911)
The lit.local.cfg in test/Conversion/MathToXeVM excludes
native-spirv-builtins.mlir when the SPIRV target is not built. #189494
deleted that test, so the file now excludes nothing. Remove it.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[clang][Lex] Skip to the end of directive after diagnosing 'defined' in an #embed parameter (#235934)
The `EvaluatedDefined` error path in `LexEmbedParameters` returned
without
discarding the rest of the directive, the only error path in the
function that didn't.
With any token following the parameter's closing paren, e.g.
#embed <f> limit(defined(x)),
`HandleEmbedDirective` hit its "expected success or to be at the end of
the directive"
assertion (a no-assert build would resume lexing mid-directive).
Discard the remaining tokens like the neighboring error paths do, and
add coverage
for both the `#embed` and `__has_embed` forms.
Fixes #212075
[clang] Fix acceptance of redefinition of a struct with different bit-field width (#235265)
The bug comes from `IsStructurallyEquivalent(Context,
Field1->getBitWidth(), Field2->getBitWidth())`
returning true when both `Field1->getBitWidth()` and
`Field2->getBitWidth()` are ConstantExpr types. Two bit fields were
treated as structurally equivalent even though their widths are
different.
This PR makes sure that two bit-fields with different bit-field width
are treated as structurally unequivalent under `-std=c23`.
Fixes #232748.