[AMDGPU] Form VOPD3 pairs with pair-local literal moves
This PR lets GCNCreateVOPD form a VOPD3 pair when its components use one
distinct non-inline constant. VOPD3 cannot encode literal operands, but src0
can read scalar registers, so we move the value to a free SGPR. If both
components use the same value, one move serves both.
We reject pairs that need two values because two moves add more instructions
than one fusion removes. We also reject functions without tracked liveness and
functions optimized for size.
We use one reverse liveness walk to find an SGPR that is free over each
pair-local range. We exclude reserved registers and VCC. Disjoint selected
pairs can reuse the same SGPR, and each accepted pair adds at most one
S_MOV_B32 for the one instruction removed by fusion.
When overlapping candidates form the same number of pairs, we prefer the set
that needs fewer scalar moves. We keep pair count as the primary objective.
[2 lines not shown]
[NFC][AMDGPU] Separate VOPD candidate selection
This PR separates VOPD candidate matching from selection without changing
generated code.
GCNCreateVOPD used to choose a pair as soon as tryMatchVOPDPair found one.
That made matching and selection one operation: the first match consumed both
instructions before later work could decide whether the pair was usable.
We now record matches in program order, collect every adjacent candidate, and
select the same greedy non-overlapping set in a separate step.
This gives later changes a place to reject or rank a candidate without hiding
an overlapping pair that uses its second instruction.
[bazel][libc][test] Allow LLVM-libc tests to be run in full-build mode (#219262)
This PR makes the required changes to run LLVM-libc full build tests in
Bazel. After this PR, most tests pass:
```
bazel test @llvm-project//libc/test/... --config=ci --@llvm-project//libc:build_mode=full --keep_going
Executed 760 out of 970 tests: 760 tests pass and 210 fail to build.
```
Follow on changes will fix specific tests that are failing (some missing
deps etc).
Specifically, this PR:
- Propagates the correct dependencies and compiler/linker options from
[`add_libc_hermetic`](https://github.com/llvm/llvm-project/blob/4098f568c46e06b6df470111868b4c165dd80f4d/libc/cmake/modules/LLVMLibCTestRules.cmake#L750).
- Adds `crt1.o` and hermetic utils as deps for all full-built tests.
- Fixes some build deps to be full-build compatible.
[SeparateConstOffsetFromGEP] Rebuild GEP indices at their definition point (#223546)
When a constant offset is split out of a GEP index, the rebuilt index
replaces the original one. Rebuilding the index immediately before the
GEP amounts to sinking the index computation, increasing live ranges and
register pressure. This change attempts to rebuild the index at the
definition point of the original index instead. The same insertion point
is used for the `idxprom` cast created by
`canonicalizeArrayIndicesToIndexSize` too.
[CIR] Verify cir.ptr_mask's mask width instead of resizing it
A mismatch is a producer bug, so reject it rather than convert it.
Assisted-by: Cursor / claude-opus-5
[lld][COFF] Refactor ICF section equality checks, NFC (#206562)
In the context of #205456 , this seemed like a reasonable refactoring.
The template specialization might be overkill, but I figured it would
ensure there was no performance regression.
Change string type of StackFrameRecognizer module names (#222810)
The majority of these come from FileSpec filenames (which are no longer
ConstStrings). Instead of putting them into the StringPool, the
StackFrameRecognizerManager can just hold onto the name in the
RegisteredEntry.
[WinEH] Only emit the async-EH nop after EH_LABEL on x86 (#219275)
Under `-fasync-exceptions`, `AsmPrinter::emitFunctionBody()` emits a nop
after an `EH_LABEL` whose next instruction can fault, so that the
faulting instruction opening an EH region does not share an address with
the return address of the call before it.
`EH_LABEL` is a meta-instruction and reports a size of zero, so that nop
is invisible to `getInstSizeInBytes()` and to everything that sums it.
On AArch64 that undercounts block offsets, `AArch64CompressJumpTables`
picks a one-byte jump table entry that does not fit, and the assembler
rejects it with `value evaluated as 258 is out of range`. That is how
this was found, building OpenCV's bundled protobuf for
`aarch64-pc-windows-msvc` with clang-cl `/EHa`. `BranchRelaxation` sums
the same sizes and has the same hole.
Only x86 needs the padding. On Arm64 the unwinder already backs the PC
up over a call when it knows there was one, which is exactly the case
the nop protects against, So gate the nop on x86 triples. That also
[9 lines not shown]
[mlir][LLVM] Use a disjoint scope domain when inlining noalias
This matches recent changes to the LLVM inliner.
AI disclosure: Claude wrote the code, I wrote the commit message and
have done initial review.
[mlir][LLVM] Add disjointScopes to AliasScopeDomainAttr
This also updates the MLIR-side inliner to clone disjoint domains
while cloning alias scopes, matching changes to LLVM.
AI disclosure: Claude wrote the code, I wrote the commit message and
looked at the code.
[AMDGPU] Use a disjoint scope domain for merged LDS structs
When lowering LDS values, all the values are mutually disjoint, so we
can use the newly-added disjoint scopes feature to simplify the IR.
AI disclosure: Claude wrote this and I reviewed it and wrote the
commit message
[AMDGPU] Use a disjoint scope domain for noalias kernel arguments
All noalias arguments of a kernel are disjoint with each other, so we
can use a disjoint scope to save on metadata construction.
AI disclosure: Claude wrote this, I looked at it and wrote this
message.
[Inliner] Use a disjoint scope domain for noalias arguments
InlineFunction creates alias.scope/noalias metadata to represent the
set of `noalias` arguments to a function. We don't need the `!noalias`
now that we have the ability to use disjoint scopes, saving us IR size
and metadata bloat.
TODO move these to a previous commit.
Also changes InstCombine to not drop the experimental.noalias.scope.decl
for disjoint scopes even if they're not mentioned in a `!noalias`, but
do still delete them if they're not used.
[IR] Add alias scope domains with disjoint scopes
See RFC at
https://discourse.llvm.org/t/rfc-disjoint-scope-alias-scope-noalias-domains/91537
This commit adds support for declaring an alias scope domain disjoint.
Disjoint domains are ones where each scope is implicitly `!noalias`
with each other scope in the domain. This is represented by adding an
`i1` into the scope's domain as the second argument, with `i1 true`
representing disjoint scopes and `i1 false` representing the old
non-disjoint behavior. AutoUpgrade mechanisms have been added to add
in the missing `i1 false` to existing metadata.
This commit updates alias analysis to know about disjoint scopes and
updates the function cloner to also clone the alias domain if it's
disjoint (since, as a herd of LLMs discovered, you don't want the old
IR to be noalias with a clone of itself).
Commits to migrate passes to use disjoint scopes where that's an
[4 lines not shown]