[WebKit checkers] Ignore a lambda variable discarded with a cast to void (#235151)
webkit.UncountedLambdaCapturesChecker and related checkers reported a
lambda stored in a local variable when the variable was referenced in a
cast to void, as in UNUSED_VARIABLE(lambda) which expands to
"(void)lambda", even though a lambda which is only called is not
reported.
A cast to void never invokes a user-defined conversion function nor
copies its operand, so it can't let the lambda escape. Ignore such a
reference to the variable as done for a call to the lambda.
Co-authored with Claude.
[AMDGPU] Use addressable arch VGPR count for CFI
emitPrologueEntryCFI assumed 1024 arch VGPRs on targets with VGPR
MSBs, regardless of wave size. In wave64 only 512 are addressable, and
VGPRs above that have no DWARF number. Use
getAddressableNumArchVGPRs, as whole wave function handling already
does.
No upstream target with VGPR MSBs supports wave64. NFC.
Change-Id: Ic65c4bb284e8583395bbe98ceeccd0f46b877538
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[AMDGPU] Derive addressable VGPRs from encoding width (#235332)
The addressable VGPR count is bounded by both the operand encoding width
and the register file size.
Compute it as the smaller of the two instead of listing per-target
values. Wave64 on targets with VGPR MSBs was already `min(1024, 512)`.
NFC.
[clang][Modules] Refactor modulemap lookup & parse functions, NFCI
* Split `lookupModule` into seperable functions to isolate parsing from
loading of a module.
* Do the same for `parseAndLoadModuleMapFile` functionality.
* Clarify related docstrings.
This is in effort to lookup modules without ever loading the full module
definition, which will be introduced in a follow up patch leveraging
lazy module map searching.
[Hexagon] Lower 4 IEEE HVX conversions to a call (#232862)
This patch adds a runtime-call lowering for four HVX IEEE conversion
intrinsics that have no QFloat
instruction with matching rounding behavior on v79: V6_vcvt_h_hf,
V6_vcvt_b_hf, V6_vcvt_ub_hf and
V6_vcvt_uh_hf round to nearest even in IEEE, but the closest QFloat
instructions round toward zero. Each is lowered to a call to
__qf_convert_hf_to_{h,b,ub,uh}_rne, with a new -hexagon-qf-fast-convert
flag selecting a faster __qf_fast_convert_hf_to_*_rne variant for
callers that can accept reduced accuracy.
V6_vcvt_b_hf and V6_vcvt_ub_hf take two vector operands; the call
argument list is built by iterating over all of them, not just the
first, since the second operand is otherwise silently dropped from the
generated call.
Co-authored-by: Sumanth Gundapaneni <sgundapa at qti.qualcomm.com>
[Sink][AMDGPU] Avoid sinking into postdominators
Add an avoid-postdominators option to the Sink pass and enable it in
the AMDGPU pre-ISel pipeline.
Sinking an instruction into a block that postdominates it saves no
execution, since the destination runs whenever the source block does.
It only moves the computation, which can extend the live ranges of the
instruction's operands.
With the option, Sink skips such a move when the operand bits it would
keep live exceed the result bits it frees. On targets with divergent
branches only divergent values are counted, since uniform values live
in scalar registers and do not affect VGPR pressure or occupancy. Moves
into blocks that do not postdominate the source are unaffected, and the
default behavior of the pass is unchanged.
[mlir][acc] Decide reduction atomics by destination instead of by partitioning (#235099)
A reduction combine became atomic only if the reduction's parallel dims
named a
block dimension, so the choice rested entirely on how the reduction was
partitioned. Partitioning answers whether a merge is needed at all.
Whether that
merge has to be atomic should depend instead on how many blocks can
reach the
destination, which is a property of the launch. A thread-only reduction
shows
the difference: it names no block dimension, yet every block still
combines its
own partial into the same shared slot, so the combine stayed non-atomic,
leaving
those updates open to a data race.
An array accumulate partitioned only across threads avoided emitting
that
[85 lines not shown]
[lldb] Fix a race in PlatformAppleSimulator::GetSDKFilepath (#235098)
Target::SetExecutableModule creates dependent modules in parallel, and
each one can reach GetSDKFilepath. Its lazy initialization was
unguarded. That was benign while m_sdk was a StringRef, but #199141 made
it a std::string, so concurrent assignments double free.
Initialize m_sdk with std::call_once.
rdar://190273717
[NVPTX] Avoid nonlocal MachineCSE of special register reads. (#228303)
Special hardware registers for information that remain static throughout
a kernels execution (e.g. warpID, gridID) are bad candidates for CSE
because they are cheap to recompute and therefore may unnecessarily
increase register live ranges. This marks such registers as cheap so the
compiler can decided that it is not profitable to extend their live
ranges.
[TableGen] Assert that RecordVal values are never null (#235077)
A RecordVal always has a value: it starts as an UnsetInit and is only
ever set to another non-null value. Replace the dead null cases in
RecordVal::setValue and TGParser::SetValue with assertions, document the
invariant on RecordVal::getValue, and remove the redundant null checks
on RecordVal values in TableGen and in LLVM and MLIR backends. NFC.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply at anthropic.com>
[CGData][GMF] Don't parameterize callees in ptrauth-calls functions (#234008)
`GlobalMergeFunctions` can merge two functions that differ only in a
direct callee by passing the callee as a parameter, which turns the call
into an indirect call. In a function with the `"ptrauth-calls"`
attribute every indirect call is expected to carry a ptrauth bundle, so
the merged body ends up with an unauthenticated `blr`.
Signing the parameter would cost a signed-pointer materialization in
every thunk, which works against the size win the pass is after, so
decline the parameterization, as is already done for calls that carry a
ptrauth bundle. Functions that differ elsewhere still merge.
Found by inspection and reproduced with `-enable-global-merge-func` on
arm64e.
Assisted-by: Claude
[LSR] Return null from `getExactSDiv` for a zero divisor (#226703)
Fixes #226063
`getExactSDiv` in LSR assumed its divisor is never zero, which holds for
the strides SCEV hands out directly since `{X,+,0}` folds to `X`. But
`CollectInterestingTypesAndFactors` sign-extends the strides of narrower
IVs before pairing them with wider ones, and that extension can fold to
a constant zero when SCEV knows the narrow stride is a multiple of the
narrow type's modulus. In the reproducer the i64 IV steps by `-4 * %v`
where `%v` is known to be `2^30`, and a truncated i32 copy of the same
value steps by `4 * trunc(%v)`. SCEV keeps that symbolic in i32, but
once widened it re-truncates `%v` to i30, sees only zero bits, and folds
the whole stride to `0`, so `getExactSDiv` recursed into the constant of
the i64 stride and did `-4 srem 0`. Nothing in LSR changed here
recently, by the way; the bug is old, trunk just started handing LSR the
unfolded constant chain that exposes it.
`getExactSDiv` now returns null when the divisor is zero, the same
[3 lines not shown]
[AArch64][RuntimeDyld] Handle far external symbols in COFF JIT code (#229719)
External symbols on Windows can be more than 4 GiB from JIT allocations
and therefore outside ADRP's signed 21-bit page range. RuntimeDyld
currently truncates the relocation, producing an invalid address without
reporting the error.
For an external address materialised with an ADRP+ADD pair, we now
create a pointer slot in the section's stub area and rewrite the ADD to
an LDR from that slot. This leaves non-zero addends and other
instruction patterns unchanged. We then report any remianing ADR/ADRP
relocation overflows instead of silently truncating them.
Also added `llvm-rtdyld` coverage and a WoA MLIR ExecutionEngine test
that tests this by placing JIT allocations more than 4 GiB from external
symbols.
This PR is related to #173269 which mentions a similar AArch64 ADRP
range failure. It's just that it's scoped to fix COFF external-symbol
[2 lines not shown]
[AMDGPU] Enable SlotIndexes compaction by default
Add TargetRegisterInfo::shouldCompactSlotIndexes() so targets can opt
in to dropping dead SlotIndexes entries before greedy allocation, one
target at a time. An explicit -greedy-compact-slot-indexes still
overrides the target. Enable it for AMDGPU, where the leftover entries
skew live range priorities enough to cause heavy spilling.
[Mem2Reg] Don't handle indirect lifetime markers (#235740)
Nowadays lifetime markers must directly reference the alloca, having a
bitcast/addrspacecast/gep-0 in between is not allowed. Drop the related
handling.
This is implemented in a non-NFC way: We also don't support the case of
unused addrspacecasts or droppable-users-only bitcast/gep-0. This is on
the premise that such no-op instructions are expected to be optimized
away before Mem2Reg runs (or not even created in the first place).
[AArch64] Support FP atomic stores with memory hints
This patch extends the atomic-store-hint pseudos to accept preserved
floating-point atomic stores. It adds an FPR16 pseudo family and direct
half, bfloat, float, and double patterns for the supported addressing
modes.
The pseudos expand relaxed stores to STR and RCPC3 release and
sequentially consistent stores to STLUR, retaining memory hints without
cross-register-bank copies.
The existing AArch64::ATOMIC_STORE_HINT_H is renamed to
AArch64::ATOMIC_STORE_HINT_HH and AArch64::ATOMIC_STORE_HINT_H now means
FP16 instead of it's old association with integer half-word.
TableGen: Skip disjoint register classes before intersecting them (#234803)
inferCommonSubClass intersects the member lists of a register class
with every other class, and most pairs are disjoint. Check that with
the member bit vectors first, which avoids loading the members and
allocating the intersection.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 576 346 111
After 573 (-0.6%) 343 (-0.7%) 110 (-0.6%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Compute register sizes once for the sub-register size check (#234802)
checkSubRegIndexSizes found the size of each register by scanning every
register class for one containing it, about 18 million class membership
tests for AMDGPU. Compute the size of all registers in one pass over
the members of each register class instead, and pass it in.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 578 355 113
After 576 (-0.2%) 345 (-2.8%) 110 (-2.4%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Test register sub-classes with the member bit vectors (#234801)
computeSubClasses checks whether one register class contains another
for most pairs of classes, by walking both sorted member lists. That
reads every member register, which is slow for AMDGPU's 913 classes.
Each class already has a bit vector of its members, so compare those
instead.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 596 365 117
After 577 (-3.1%) 353 (-3.4%) 112 (-3.7%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Skip redundant addComposite calls for secondary sub-registers (#234800)
computeSecondarySubRegs calls addComposite for every index of every new
sub-register, and almost all of these calls repeat a composition that
is already known. For AMDGPU, only about 15000 of 29.8 million calls add
anything. Skip the call if the composition is known and its result has
an offset in every mode, since it would do nothing.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 603 367 116
After 595 (-1.3%) 362 (-1.2%) 115 (-1.0%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Store super-register class sets as bit vectors (#234798)
extendSuperRegClasses adds the super-register classes of each register
class's super-classes to its own, by merging their sets. The sets were
DenseSets, so most of the time went to hashing classes that were already
present.
Store the sets as bit vectors instead, so merging is a bitwise or. They
are indexed by a new CreationIndex, since EnumValue isn't assigned until
all classes have been inferred.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 700 435 135
After 622 (-11.1%) 381 (-12.5%) 120 (-11.2%)
---------
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
TableGen: Index registers by sub-register index enum value when inferring sub-classes (#234799)
inferSubClassWithSubReg groups the members of a register class by each
of their sub-register indices, and looked up every index of every member
in a std::map. Sub-register indices are numbered densely, so use a
vector indexed by enum value instead. Also count the members once
instead of once per index.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 622 380 120
After 604 (-3.0%) 367 (-3.4%) 115 (-3.7%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[AMDGPU] Use addressable arch VGPR count for CFI
emitPrologueEntryCFI assumed 1024 arch VGPRs on targets with VGPR
MSBs, regardless of wave size. In wave64 only 512 are addressable, and
VGPRs above that have no DWARF number. Use
getAddressableNumArchVGPRs, as whole wave function handling already
does.
No upstream target with VGPR MSBs supports wave64. NFC.
Change-Id: Ic65c4bb284e8583395bbe98ceeccd0f46b877538
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[AMDGPU] Derive addressable VGPRs from encoding width
The addressable VGPR count is bounded by both the operand encoding
width and the register file size. Compute it as the smaller of the two
instead of listing per-target values. Wave64 on targets with VGPR MSBs
was already min(1024, 512). NFC.
Change-Id: Ia0e030a9005fb2e915ef09e4ac7fd5ded22ab9b2
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[AMDGPU] Rename 1024AddressableVGPRs to VGPRMSBs. NFC (#235331)
Most users of this feature ask whether the target has VGPR MSBs:
`S_SET_VGPR_MSB`, VGPR encoding lowering, MSB decoding and inline asm
register classes. 1024 follows from an 8-bit operand field plus 2 MSBs.
Name the feature after the capability so VGPR counts can be derived from
the encoding width. NFC.