[OpenMP][offload] Apply the low-trip rule to no-loop kernels (#234660)
Use the same low-trip logic for no-loop that we're also using for
regular SPMD loops.
That means in particular that we try to use the preferred number of
blocks and trade threads for blocks if there are not enough loop
iterations.
The default #blocks for an MI200 would be 4*#CUs, aka 416. If we have a
loop with 256 threads/block but only a tripcount of 512, we use the
minimal #threads/block, aka 32 and then choose #blocks accordingly.
This is an upstream port of the corresponding downstream.
Claude assisted with this patch.
[AMDGPU] Guard image intrinsics with image-insts feature. (#238123)
The llvm.amdgcn.image.* intrinsics, other than the already guarded BVH
ones, did not require any target feature. On subtargets without image
instructions, such as gfx942, gfx950, gfx1250, gfx1251 and the generic
targets, they reached instruction selection and either asserted, failed
with a fatal "cannot select" error, or silently produced image
instructions that the assembler rejects for that subtarget.
Require image-insts so that both SelectionDAG and GlobalISel diagnose
them instead. This also rejects zero-dmask image intrinsics that
instruction selection would otherwise drop as no-ops.
Assisted by: Opus 5.5
[VPlan] Strip bad TODO for VPI::execute (NFC) (#237928)
The TODO does not make sense, as unrolled parts for all recipes are
uniformly handled by VPlanUnroll. The remaining comment for VPI::execute
doesn't add value either.
[libc] Implement sigsuspend in signal (#237223)
Add the standard POSIX function sigsuspend to <signal.h>:
- Add low-level rt_sigsuspend system call wrapper in
libc/src/__support/OSUtil/linux/syscall_wrappers/rt_sigsuspend.h.
- Add public header declaration in libc/src/signal/sigsuspend.h.
- Implement sigsuspend entrypoint in
libc/src/signal/linux/sigsuspend.cpp.
- Declare sigsuspend in libc/include/signal.yaml.
- Register entrypoint for Linux (x86_64, aarch64, riscv) in architecture
config files.
- Update CMakeLists.txt files across syscall wrappers, signal sources,
and tests.
- Add unit tests in libc/test/src/signal/sigsuspend_test.cpp.
Part of #236167
[AMDGPU] llvm.amdgcn.*.buffer.load.format.d16.ll - regenerate checks (#238285)
Clean up work for the topological sorting patch to make codegen diffs
more obvious
[mlir][affine] Add arith.subi support to memref to affine raise (#222880)
This PR adds support for `arith.subi` to `toAffineExpr` to e.g. allow
matching expressions like `i-1` which appear with one-indexed arrays.
[clang] Fix extra error message (#235427)
When auto* is used in a structured binding, Clang reports an error
because this declaration is not allowed. However, it also reports
another error about the initializer type, which is unnecessary.
This change removes the invalid pointer from the declarator instead of
marking the declaration as invalid, allowing Clang to continue type
deduction and keep the structured bindings usable in subsequent code.
Added test cases for different invalid auto declarations.
Used LLM to identify the issue and understand the code.
Fixes #222605
[SCEV] Don't recurse into isKnownPredicate from IsKnownPredicateViaAddRecStart
isKnownViaNonRecursiveReasoning is meant to use non-recursive checks, but
one of them, IsKnownPredicateViaAddRecStart, proves a predicate on two
AddRecs by calling isKnownPredicate on the AddRecs start values.
The start values may themselves be AddRecs of another loop.
For example, when a loop's IV starts at the exit value of the previous loop's IV.
Then that query recurses into every loop of such a chain, and each level
tries several proofs, so the number of queries grows exponentially with
the length of the chain.
Now prove the predicate on the start values with
isKnownViaNonRecursiveReasoning too, instead of isKnownPredicate.
This is less precise.
Before, isKnownPredicate could also prove the query by splitting the predicate,
and by induction.
[3 lines not shown]
[SLP]Credit single-use operand chains of extracted sub-fields
Shifts and truncations that feed only the extracted fields die with
them, so their scalar cost is credited back as well.
Assisted-by: Cursor
Reviewers:
Pull Request: https://github.com/llvm/llvm-project/pull/238293
[LoopPeel] Peel last iteration to enable load widening
In loops that contain multiple consecutive small loads (e.g., 3 bytes
loading i8's), peeling the last iteration makes it safe to read beyond
the accessed region, enabling the use of a wider load (e.g., b32) for
all other N-1 iterations.
Patterns such as:
```
%a = load i8, ptr %p
%b = load i8, ptr %p+1
%c = load i8, ptr %p+2
...
%p.next = getelementptr i8, ptr %p, 3
```
Can be transformed to:
```
%wide = load b32, ptr %p ; Read 4 bytes
[19 lines not shown]
[flang] Fix build on MacOS (#238284)
```
flang/lib/Lower/Support/ReductionProcessor.cpp:1134:31: error: use 'template' keyword to treat 'lookupSymbol' as a dependent template name
01:06:39 1134 | builder.getModule().lookupSymbol<OpType>(reductionName)) {
01:06:39 | ^
01:06:39 | template
01:06:39 1 error generated.
```
I instead split the expression to match other code in the file.
[SCEV] Don't recurse into isKnownPredicate from IsKnownPredicateViaAddRecStart
isKnownViaNonRecursiveReasoning is meant to use non-recursive checks, but
one of them, IsKnownPredicateViaAddRecStart, proves a predicate on two
AddRecs by calling isKnownPredicate on the AddRecs start values.
The start values may themselves be AddRecs of another loop.
For example, when a loop's IV starts at the exit value of the previous loop's IV.
Then that query recurses into every loop of such a chain, and each level
tries several proofs, so the number of queries grows exponentially with
the length of the chain.
Now prove the predicate on the start values with
isKnownViaNonRecursiveReasoning too, instead of isKnownPredicate.
This is less precise.
Before, isKnownPredicate could also prove the query by splitting the predicate,
and by induction.
[3 lines not shown]
[GlobalISel] Combine shifted power-of-two division and nonnegative signed div/rem (#236601)
Fold unsigned division by a shifted power-of-two constant into a logical
right shift. Convert signed division and remainder to unsigned
operations when both operands are known nonnegative.
Add MIR regression coverage and update AMDGPU assembly checks.
Fixes #236481
Assisted by: Claude Opus 5.5
[CIR] Fix complex promoted division for double (#234289)
While working on long double format attribute, I wanted to make sure CIR
passes pick up and use the info correctly, however the possible affected
place where we figure out long double type on the fly was always
hardcoded to use `long_double<double>` type. It should use targetinfo's
long double instead, taking `-mlong-double` options into account.
Assisted-by: claude
[X86] combineKSHIFT - move kshiftr(extract_subvector(X,C1),C2) handling to SimplifyDemandedVectorElts (#237324)
The combineKSHIFT fold didn't ensure that we retain zero in the
upper/shifted elements - we're better off handling this in
SimplifyDemandedVectorElts where we can still fold if we don't need the
zero'd elements
Fixes #235657
[AArch64] Make all fixed-width masked loads/stores legal on SVE targets (#232757)
The loop vectoriser already generates calls to illegal fixed-width
masked loads and stores regardless of whether the TTI hook says
they are legal or not. Presumably it's because this is preferrable
to manually scalarising the operation at the IR level by introducing
blocks and control flow. However, it does mean that when SVE is
available the code quality is poor, particularly for wider-than-legal
types such as <32 x i8>. This patch returns true from the TTI hook
for all fixed-width types to prevent the ScalarizeMaskedMemIntrin
pass prematurely scalarising the masked operations when we can
use SVE instead.
This PR also makes it easier for us to use SVE in future for
wide masked loads with deinterleaving or wide masked stores with
interleaving. In such cases we should be able to lower the IR to
the SVE masked ld2/st2/etc instructions.
[IndVarSimplify][NFC] Add a test for a predicate on AddRec starts
Add a test where a predicate on two AddRecs of an inner loop
is implied from the predicate on their start values,
which are IVs of the outer loop, and that predicate can
be proven by induction over the outer loop.
Assisted-By: Claude
[SPIR-V] Emit ID decorations on function parameters as OpDecorateId (#229089)
Reuse the global decoration path so parameters get `<id>` operands too
Depends on #229056 and #229058
[Offload][Omp] Use libomptarget values to initialize the Device Environment (#238271)
Use the values for total devices and device id from the libomptarget
side instead of the Plugin Interface.
With this not only we remove another usange of the Plugin Interface, but
make it more correct. As those values were only correct if only one RTL
was being used (probably 99.9% of the cases). This is a likely a
leftover of when it was initialized on the
Plugin side.
New test created by Claude.
[Offload][Omp] Replace usages of Plugin getName (#237269)
Create a new class `PlatformTy` to add liboffload platform related
operations. Add a new `getName` method and use it substitute lingering
and already substituted `GenericPluginTy::getName` usages.
The new method also fixes a bug where we were printing an extra `NULL`
character with the platform name.
Assisted by Claude.