[PowerPC] fix SPE offset miscompilation (#233220)
The SPE doubleword load and store (evldd and evstdd) have a 5-bit field
for the offset, which is scaled by 8. the logic checked that the
displacement fit in a u16, but for these instructions it should use a
stricter check.
https://godbolt.org/z/Ev7nGq74b
```llvm
declare void @use(ptr)
define void @f(double %x) "target-features"="+spe" {
%d = alloca double, align 8
%a = alloca [256 x i8], align 8
%big = alloca [32768 x i8], align 8
store i8 0, ptr %a, align 8
store double %x, ptr %d, align 8
call void @use(ptr %big)
[42 lines not shown]
AMDGPU: Remove kill flags on virtual registers from MIR tests
Soon the verifier will disallow this. Delete redundant tests which
only differed from others by kill flag uses. twoaddr-bundle.mir relied
on the input kill flags in TwoAddressInstruction, so compute
LiveIntervals first as the real pipeline does.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Support mixed-type store vectorization of arbitrary values
vectorizeStores() only handled chains whose stored values were all
consecutive loads or all constants. Any other chain, e.g., storing
function arguments or computed values, was left alone.
Pack such values into a vector with createPack(). For a chain of mixed
types the vector has integer lanes, so each value is first
reinterpreted (bitcast / ptrtoint) as the lanes it occupies with
Reinterpret::reinterpretValue(), and a value spanning several lanes is
inserted lane by lane. The pack is placed right before the vector
store, where every stored value is available. Whether this pays off is
left to the existing cost check in acceptOrRevert().
Chains storing a non-integral pointer are left alone.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Vectorize store chains whose loads have external uses
vectorizeStores() used to give up on a load-store chain if any of the
loads had a user other than its store. Now that loads of mixed types
can be unpacked from a vector load, vectorize such chains as well: the
loads become a single vector load, and the external users are fed from
the lanes each load occupies, cast back to the load's type if needed.
The unpacking loop of vectorizeLoads() is factored out into
unpackLoads() (along with the canUnpackLoads() check) and shared by
both paths. Chains with a non-integral pointer load that has external
users are still left alone.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Move contiguity check into canVectorizeLSV() (NFC)
Both vectorizeStores() and vectorizeLoads() (via createVectorLoad())
checked that the bundle is consecutive before calling canVectorize().
Move that check into LegalityAnalysis::canVectorizeLSV(), reporting
ResultReason::NotConsecutive, which mirrors how canVectorize() checks
consecutive loads and stores for BundleVec.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Support mixed-type load vectorization
Remove the restriction that every load in a top-level load chain must
have the vector's element type. A chain of mixed types such as
{i32, float} or {double, i32, i32} is loaded as a vector of integers
(as chosen by VecUtils::getCombinedVectorTypeFor()), each original load
is unpacked from the lanes it occupies, and then reinterpreted back to
its own type with Reinterpret::reinterpretValue().
Chains involving a non-integral pointer are left alone, since such a
pointer cannot be recovered from an integer lane.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Add Reinterpret helper for same-size type casts
Replace getEquivalentConstantWithType() with a Reinterpret utility that
reinterprets the bits of a value as another type of the same size. It
builds a chain of ptrtoint / bitcast / inttoptr casts, and applies it
either to a constant (folding) or to a runtime value (inserting casts).
The runtime form will be used to unpack mixed-type vector loads and to
pack mixed-type store operands.
Also add VecUtils::isNonIntegralPtr(). A non-integral pointer has no
stable integer representation, so it is no longer packed into an
integer lane. Previously only a non-integral destination type was
rejected (via an assert), while a non-integral source such as
'ptr addrspace(5) null' was silently converted with ptrtoint.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Add LLVM_ABI annotations to Reinterpret
Export the out-of-line static members of Reinterpret, as reported by
the LLVM_ABI annotation check. getCastChain() is private but is called
from the inline canReinterpret(), so it needs to be exported too.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[SandboxVec][LoadStoreVec] Move contiguity check into LegalityAnalysis (NFC) (#236636)
Both `vectorizeStores()` and `vectorizeLoads()` checked that the bundle
is consecutive before calling `canVectorize()`. Move that check into
`LegalityAnalysis::canVectorizeLSV()`, reporting
`ResultReason::NotConsecutive`, which mirrors how
`LegalityAnalysis::canVectorize()` checks consecutive loads and stores
for BundleVec.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[MachineSink] Track use/def when shouldPostRASink() is false (#236267)
In `tryToSinkCopy()`, it currently is missing a call to
`LiveRegUnits::accumulateUsedDefed()` when `shouldPostRASink()`
is false. This can cause a COPY to be sunk past a user
because it looks like the COPY def doesn't have any users in
the block.
I don't have a lit test because there are currently no in-tree
targets that exercise this path.
[SandboxVec][LoadStoreVec] Don't pack non-integral pointer constants
getEquivalentConstantWithType() only rejected a non-integral pointer
destination type (via an assert), while a non-integral source such as
'ptr addrspace(5) null' was silently converted with ptrtoint. A
non-integral pointer has no stable integer representation, so it cannot
be packed into an integer lane.
Add VecUtils::isNonIntegralPtr() and return nullptr from
getEquivalentConstantWithType() when either type is a non-integral
pointer, which makes createConstantVector() give up on the bundle.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[libc][math] Optimize exp10 to share evaluations with exp and exp2.
- Refactor double precision exp10 into exp10_double_eval.h and share evaluations with exp and exp2.
- Optimize range reduction using fp-bitwise operations.
Assisted by: Gemini for analysis and refactoring
[CIR][CMake] Add missing MLIR tablegen dependencies to CIR libraries (#235185)
ClangIR libraries include MLIR and CIR headers that need
tablegen-generated `.inc` files, but nothing makes their objects wait
for those files. These libraries list `MLIRIR` and friends under a bare
`LINK_LIBS`, so the generated headers have to come from `DEPENDS`, and
the existing `DEPENDS` lists are incomplete.
In a cold build (no `.ninja_deps`), this is a race. A parallel build can
compile these objects before the headers exist:
```
fatal error: mlir/IR/BuiltinTypeInterfaces.h.inc: No such file or directory
```
It is rarely seen because incremental builds remember the header
dependency, and a full `ninja` usually generates the headers in time
through other libraries that do depend on them. It started showing up on
a ccache'd downstream bot after ClangIR was enabled by default
(#221291).
[23 lines not shown]
[Flang][Clang][OpenMP][OpenMPIRBuilder] Implement has_attach_ptr TODO and tidy now deadcode
This patch is 3/3 for adding has_attach_ptr lowering to Flang, it removes the dependence on
a catch all boolean that was added previously in place of the has_attach_ptr mechanism that
was added a little later, allowing Flang to synch a little more closely to Clang.
Most of the machinary for actually setting has_attach_ptr is in the Flang frontend, this PR
mainly forwards the information from MLIR to the OMPIRBuilder, and then remove the old boolean
that's no longer requried. We also remove the boolean setting from Clang for it hence the Clang
tag.
Otherwise we also add/tweak a few tests that are dependent on all pieces being in place.
use the size of the buffer instead of NAME_MAX and strlcpy since there is
no format. fixes:
__builtin___snprintf_chk' specified bound 511 exceeds destination size 16
[-Werror=stringop-overflow=]
[NVPTX] Select reciprocal for full division with unit numerator (#236502)
Select `rcp.approx.f32` for `llvm.nvvm.div.full(1.0, x)` and
`rcp.approx.ftz.f32` for its FTZ counterpart, matching the existing
selection for ordinary division at Full precision.
This matches the existing selection for ordinary division at Full
precision and preserves FTZ behavior.
Add positive tests for both variants and negative coverage for non-unit
numerators and accurately rounded division.
Tested with `check-llvm-codegen-nvptx`.
[ConstraintElim] Look for row proving Op <= Max - Slack. (#233851)
The constraint system does not record the upper bounds of variables
based on the type, so we often fail to prove that a variable Op <= some
upper bound in doesHoldInRange.
In practice, we frequently have other constraints involving Op and
another variable W, which we can use to prove Op is below some bound.
To check if `Op <= MaxValue - Slack`, we scan the whole constraint
system, looking for rows of the form `Op <= W - Slack`. If W's
bitwidth is <= Op's bitwidth, `W <= MaxValue`.
Similar reasoning is also applied for `Op >= MinValue + Slack`.
This triggers quite widely in practice
(5339 files changed in
https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/1762),
while compile-time impact is in the noise, with a small increase in
[8 lines not shown]
AtomicExpand: Use C int width for atomic libcall ordering argument
The memory order argument of the __atomic_* libcalls is an int, so
it is i16 on 16-bit targets. This now matches the RuntimeLibcalls
signature.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[clang] Fix constant evaluation of strchr (#230869)
Modified both `ExprConstant.cpp` and `InterpBuiltin.cpp` to remove the
casting check. The check evaluated whether the input value provided to
`strchr()` changed its value or not after being converted to a char. This
approach isn't correct as if it is a signed char of 8 bits, an input of
128 would interpreted as -128 which would result in the check being
false. However, the byte representation of both values is still the same
(0x80) which is what should be searched for. (The standard says to
search for the value after converting the int to a char.)
Closes #229810
Note: LLM assistance was used to scope the issue and find the
implementation used in the standard.
RISCV: Remove kill flags on virtual registers from MIR tests (#236922)
Soon the verifier will disallow these. Delete cases which differ from
another only in kill flag use.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[SPIR-V] Require SPIR-V 1.3 or SPV_KHR_storage_buffer_storage_class for StorageBuffer (#236904)
Do not require the extension when the minimum version is met