Skip to content

LLVM and SPIRV-LLVM-Translator pulldown (WW36 2026) - #23091

Draft
iclsrc wants to merge 2082 commits into
syclfrom
llvmspirv_pulldown
Draft

LLVM and SPIRV-LLVM-Translator pulldown (WW36 2026)#23091
iclsrc wants to merge 2082 commits into
syclfrom
llvmspirv_pulldown

Conversation

@iclsrc

@iclsrc iclsrc commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

labath and others added 30 commits August 19, 2026 10:01
…ture (#216931)

This makes the test libraries use the same patterns as the regular libc
code. This includes using dot-separated names of libraries and explicit
dependency tracking (although this patch does not make use that yet).

Since this changes the name of the libraries anyway, I took the
opportunity to rename some of them: libraries containing only a single
file now have the same name as that file.

This also resolves the dependency issues in hermetic tests, as
everything now gets packaged into the same .a library (the library
itself could also be removed, but I'm saving that for another patch).

Other changes include:
- moving the C test framework to a separate library, to avoid it getting
pulled in (and causing undefined references) when not used
- moving sched_test's static_assert into a TEST, as the test framework
requires having at least one test. The trick with overriding main() no
longer works because overlay tests no longer create a .a file for the
test frameworks.
- for the same reason, I have removed the main function from
testfilter_test.cpp
- for the same reason, avoid compiling LibcDeathTestExecutors.cpp when 
  subprocess tests are not enabled
Enable strict property assembly format mode for the NVVM dialect and
update custom assembly formats to expose property dictionaries explicitly.

Refresh NVVM tests so inherent operation properties are printed and
parsed through the property dictionary while non-property attributes
remain in the attribute dictionary.

Assisted-by: Codex
Dynamic VGPR mode is expressed via an attribute, not a subtarget
feature. We had some transitional code that looked for both, but we've
migrated to using only the attribute long ago, so cleaning it up
shouldn't affect anything.
…7205)

Fix loss of ABS64 and other types during relocation expansion.
Expand MIR test to provide full coverage of all expansions and expected
results.
We currently end up with vplan recipes like this when materialising the
VFxUF value:

```
  %vscale = call i64 @llvm.vscale()
  %vf = mul i64 %vscale, 4
  %vfuf = mul i64 %vf, 2
```

whereas it would be better to fold the two together:

```
  %vscale = call i64 @llvm.vscale()
  %vfuf = mul i64 %vscale, 8
```

Even though the cse and simplifyRecipes passes are run after
materialisation, we still end up with

```
  %vscale = call i64 @llvm.vscale()
  %vf = shl i64 %vscale, 2
  %vfuf = shl i64 %vf, 1
```

That's because simplifyRecipes is not invoked iteratively like
instcombine and so on the first pass we can only do one of:

1. Canonicalise the muls to shifts, or
2. Combine the two muls into one mul.

It's much cleaner to generate the best vplan recipes in the first place,
which this PR tries to do. As can be seen in the tests changed by this
PR, one advantage of folding the two muls into a single mul is that it
would then make it simpler to optimise other cases. For example, instead
of looking for patterns like

```
  sub(x, urem(x, shl(shl(vscale, 2), 2))
```

we can just look for

```
  sub(x, urem(x, shl(vscale, 4)))
```

which can ultimately be transformed into

```
  and(x, mul(vscale, -16))
```

if you can prove that shl(vscale, 4) will not overflow.
…template parameters (#216729)

The initial implementation of concept template parameter piggy-backed on
UnresolvedLookupExpr, because it did _mostly_ what we wanted and I was
lazy (it led to some akwardness in a few places)

However, to implement template pack indexing we need to store a
TemplateName rather than a template decl.

So this PR adds this new node, as preparatory work for P3670.

---

Opus 5 was used to make the initial version of this PR, with quite a bit
of cleaning after.
…ias templates (#207478)

When a type alias template's aggregate deduction guide could not be
resolved, `DeclareAggregateDeductionGuideFromInitList` would fall
through to the `ClassTemplateDecl` code path, which unconditionally
casts the template's underlying decl to `CXXRecordDecl`. For alias
templates this is a `TypeAliasDecl`, causing an assertion failure
(or SIGSEGV in non-assertions builds).

The sibling function `DeclareImplicitDeductionGuides` handles this
correctly, it always returns after the alias template branch and
uses `dyn_cast_or_null` instead of `cast` for the non-alias path.
This patch adds the missing `return nullptr` to match that pattern.

Likely related to #176389 (same crash site, could not reproduce
locally).

Fixes #206994
…#216951)

This extends the code added in #213606 to look through an unmerge, as
can be found after type legalization on AArch64. It looks for
G_SEXT_INREG(G_ZEXT(G_UNMERGE(G_ZEXT))), converting it to
G_SEXT(G_UNMERGE(G_SEXT)). The apply code uses c++ as it needs to create
new temporary virtual registers.
SelectionDAGBuilder no longer uses it to query if it needs expanded now
that we have dedicated ISD::CTTZ_ELTS[_ZERO_POISON] nodes that can be
expanded during DAG legalization. It's only used for target specific
costing which can just be inlined.

We have to use isOperationCustom on AArch64 since
isOperationLegalOrCustom also checks if the type is legal, which isn't
the case for fixed predicate vectors.
…ocks (#192291)

WalkPatternRewriteDriver's ErasedOpsListener incorrectly flagged
erasures of ops/blocks that were created during the current pattern
application. Since those ops were never in the walk schedule, erasing
them is safe.

Track newly inserted ops and blocks per visited op; skip the erasure
check for them. Also fix the TestPatterns CloneRegionBeforeOp pattern
to wrap op->setAttr() in modifyOpInPlace so the rewriter observes the change.

Add a focused walk-driver regression that creates and erases an
operation and a block during one pattern application, and checks that
listener notifications are still forwarded.

Fix some failures present with
MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS=ON.

Assisted-by: Codex

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…s as non-returning (#215691)

When a temporary object with a [[noreturn]] destructor is constructed
conditionally (e.g., inside a branch of a ternary operator), Clang's CFG
inserts a TemporaryDtorsBranch decision block before dispatching to the
destructor block.

Thread Safety Analysis previously treated this block as a generic join
point. Because the path through the temporary construction terminates in
the destructor, and dropped held locks on the continuation path. This
premature join resulted in spurious lockset mismatch warnings

Teach neverReturns() to recognize when a block's single successor is a
TemporaryDtorsBranch whose temporary was constructed in that block and
whose destructor branch is noreturn.

Assisted-by: Antigravity:gemini
… (#217200)

It turns out that its only client VarTemplateSpecializationDecl has
stopped copying template arguments since 2024, see
1202837
Checking for NUW is cheaper to check and should be equivalent to
checking extended expression: https://alive2.llvm.org/ce/z/_VxSSD

Compile-time impact:
 * stage1-O3: -0.09%
 * stage1-ReleaseThinLTO: -0.07%
 * stage1-ReleaseLTO-g: -0.10%
 * stage1-aarch64-O3: -0.10%
 * stage2-O3: -0.09%
 * stage2-clang: -0.23%
 


https://llvm-compile-time-tracker.com/compare.php?from=e432cb12962f1619bc73c50a2dc4d2ad5ac6b44c&to=6e11321bd7308202d7973656dee8dc03ac6a4686&stat=instructions:u

PR: llvm/llvm-project#212508
The test looks like it was originally added to check that operand
bundles were preserved, but the libcall is constant folded away and made
dead. Later PRs may end up removing this, see the conversation in
llvm/llvm-project#212968 (comment)
…s known never poison/undef as well (#217030)

We're starting to hit cases where we've used AND/ANDNP masking to zero
out vector elements, but SimplifyDemandedElts assumes the element is
unused, folds to poison and then later folds AND(poison,0) -> poison.

This needs a more thorough cleanup of a number of x86 folds that do this
(similar to #215538), but that would result in a great deal of churn,
and it looks like a #214388 fix requires backporting to 23.x.

So initially I'm taking the approach that @xyyy1420 found so we can get
this backported and I can then address the issue more thoroughly in
trunk. I'm not convinced that this will address all poison cases, but
I'm reluctant to attempt a larger backport patch.

Fixes #214388
The SiFive CLIC interrupt values may be combined with each other and
with the machine value, but the interrupt attribute previously accepted
at most two arguments.

This commit allows three arguments for the combination of machine,
SiFive-CLIC-preemptible, and SiFive-CLIC-stack-swap.

Fixes #216138
…. (#148263)

This is similar to llvm/llvm-project#147950 but
for declare mapper function.
We ended up calling getAllocatedNumVGPRBlocks with the arguments in the
wrong order - it should take the number of VGPRs first, and then the
size of a dynamic VGPR block.

Assisted-by: Claude
Since clspv properly handles denorm with
google/clspv#1616
we should rely on the generic implementation of subnormal_config.
- Keep non-power-of-two X86 integer division vectorized when constant
extracts collectively demand every result lane.
- Preserve the existing scalarization path for partial-lane and
variable-index extracts to avoid scalarization regressions.

Non-power-of-two vector returns are legalized as scalar extracts. The
existing DAG combine treated any extract-only use set as partial demand,
causing operations like <7 x i32> and <2 x i8> divisions to expand into
scalar divide instructions. Tracking the extracted lane set
distinguishes legalization/ABI extraction from genuinely partial demand,
allowing widened vector lowering to proceed.

Fixes #215061.

## AI assistance disclosure

ChatGPT/Codex was used to assist with code investigation,
implementation, test authoring, and test execution. The contributor has
reviewed and understands the submitted change and remains fully
accountable for it.
…e memset with variable fill (#217224)

A one-byte memset does not require replicating the fill byte into a
wider integer value. Allow a nonconstant i8 fill value to be stored
directly when the memset length is one.

Keep the existing constant-fill handling for lengths 1, 2, 4 and 8.
Preserve volatility and unordered atomic ordering on the generated
store.

This is the InstCombine prerequisite for #213027.

Assisted-by: GPT-5
…wn to fit in fewer bits (#206592)

When both operands of a wide vector USUBSAT are known (via KnownBits
analysis) to fit within a narrower type, reinterpret the operation as a
narrower saturating subtract instead. x86 has native vpsubusb/vpsubusw
instructions but no vpsubusd/vpsubusq, so wide USUBSAT on i32/i64 lanes
is currently emulated with vpmaxu* + vsub*, requiring two instructions.

- The transformation searches for the smallest power-of-2 narrow width
(starting at 8) where both operands are proven to fit via
computeKnownBits. Both operands are then bitcast to the narrow vector
type and a single vpsubusb/vpsubusw is emitted — no mask, no extra
constant, strictly fewer instructions on every target.

For example, llvm.usub.sat.v8i32 where both LHS and RHS are masked to 8
bits:

```
Before:

vpmaxud  ymm0, ymm0, ymm1
vpsubd   ymm0, ymm0, ymm1

After:

vpsubusb ymm0, ymm0, ymm1
```
- This is implemented as a generic combine in DAGCombiner::visitSUBSAT,
gated on the narrow type being legal or custom for USUBSAT on the
target. The case where only the LHS is narrow (requiring an OR-mask on
the RHS) is left as a potential follow-up.

Fixes #195462

This patch was developed with Claude (Anthropic) as a learning aid to
understand LLVM's SelectionDAG lowering and KnownBits infrastructure.
Eliminate the roundabout and expensive zero extend expressions, and use
the wrap flags on the expression directly.

Proof: https://alive2.llvm.org/ce/z/-NnV2C
Enable strict properties-in-assembly-format mode for Bufferization.

Update the remaining test case that spelled the read_only inherent
attribute through attr-dict so it uses the declarative keyword form.

Assisted-by: Codex
Enable the strict properties assembly format mode for the Async dialect.
Spell call argument/result attribute arrays and runtime reference counts
directly in assembly formats so they are not parsed from attr-dict in
strict mode.

Assisted-by: Codex
Daedie-git and others added 27 commits August 20, 2026 11:43
…ty_queue (#217241)

`std::queue`, `std::stack`, and `std::priority_queue` expose the
underlying container as a protected member named `c`. That name is
required by the standard
([queue.defn](https://eel.is/c++draft/queue.defn),
[stack.defn](https://eel.is/c++draft/stack.defn),
[priqueue.overview](https://eel.is/c++draft/priqueue.overview)), so one
synthetic frontend covers libc++, libstdc++, and MSVC STL.

libc++ already registered this frontend for the inline-namespace regex.
This also registers it for the un-inlined `std::` names used by
libstdc++ and MSVC STL, and moves the frontend to GenericQueue.cpp as
GenericContainerAdaptorFrontEndCreator.

Tests extend the generic queue suite to libstdc++
(queue/stack/priority_queue) and MSVC STL (Windows).

Part of #24834

Assisted-by: Grok 4.6

---------

Co-authored-by: Bjorn Schobben <bjorn.schobben@aimsport.com>
…:addPacks` (#215235)

`getDepthAndIndex` assumes its parameter never refers to a function
parameter pack. Bail out before calling it for function parameter packs.

Fix #28877. Fix #213760.
…stexpr Type Ordering (#216462)

This patch implements a __builtin_type_order intrinsic to support the
implementation of
[P2830R10](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2830r10.html)
Constexpr Type Ordering.

The `__builtin_type_order` builtin returns a `std::strong_ordering` to
match GCC's behavior. Similar to GCC, we establish a total order over
all types by doing lexicographical comparisons over the mangled type
names. This may yield different orderings with different ABIs.

Resolves llvm/llvm-project#146838
We already assert Ptr.isBlockPointer() above.
Convert some simple cases away from getVRegDef + opcode
checks which don't require new matchers.

Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
…216678)

The spirv64-amd-amdhsa target unions every GPU's features in its feature
map so it can report builtins as available. The CodeGen doesn't have
any use of the target-features. Putting it into the IR just results
in an annoying to update test every time a new feature is added. The
ultimate SPIRV codegen doesn't do anything with it, and if it did
survive to AMDGPU codegen, it would be actively harmful.

This isn't an ideal solution. The target-features spam is also
noisy and useless in the AMDGPU case, but solving that is more
intricate because we do currently rely on this for some features,
most notably the wavesize.

Co-authored-by: Claude (Claude-Opus-4.8)
…3930)

Emit UniformId as OpDecorateId with a Scope id operand instead of a
plain OpDecorate literal, preserve id-based decorations through the -r
round trip (SPIRVEntry only walked Decorates, not DecorateIds), and
require SPIR-V 1.6 when UniformDecoration capability is selected

Inspired by related SPIR-V backend change
llvm/llvm-project#207958

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@efb07dde9c90a0c
Declares the error handling kind in the public `LLVMSPIRVOpts.h` and
carries it on `TranslatorOpts`, so an embedder can select the non fatal
behaviour without redeclaring library internals. The default stays
`Exit`, so nothing changes for callers that do not ask.

Two further fixes were needed to make `Ignore` usable: `parseSPT()` held
the error log by value, so `getError()` lost the reason, and `Ignore`
wrote to stderr unconditionally. `llvm-spirv` gains
`--spirv-error-handling`, which the new test uses.

Validated on the `llvm_release_220` branch against LLVM 22.1.0, where
the test fails before the change and passes after, with the rest of the
suite unaffected (1017 passed, 0 unexpected failures).
The patch applies to `main` with identical added and removed lines.

Fixes #3939

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@1e5eb1f97d5a1bb
Reverse translation mangled `OpUMulExtended`'s operands with signed
suffixes (e.g. `ll` for i64) instead of unsigned (`mm`), causing
undefined-reference errors for consumers expecting the unsigned name.

AI-assisted: Claude Sonnet 5 (commercial SaaS)

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@468ac916877e634
The badge links used a free-text `actions?query=workflow:"..."` search,
whose results can lag the real run history by weeks.

Link to `actions/workflows/<file>.yml?query=event:schedule` instead,
since that page reads run data directly and always reflects the latest
scheduled run.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@6c1a75ba86a62fd
itaniumDemangle returns a malloc'd buffer that the caller must free, but
its result was assigned directly to a StringRef, so the buffer was never
released.
This leaked on every internal FP4/FP8/int4 conversion builtin
processed by transFunctionDecl and transDirectCallInst.

The demangled name is simply the length-prefixed identifier already
present in the mangled name, so extract it as a substring of Name (the
same pattern used by the other demanglers above) instead of calling
itaniumDemangle.
This removes the allocation entirely, so there is nothing to leak.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@c18063630e33cce
llvm/llvm-project#215790 removed the backend's Volatile parameter
decoration
derived from `!kernel_arg_type_qual`, so the `llc` legs can no longer
share
`CHECK-SPV-IR` with the translator legs, which still expect it.

Give them a `CHECK-BACKEND` prefix matching current output, keeping the
cross-compilation coverage from #3564. Fixes the nightly `main` failure.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@f30f8157d87aced
Per SPIR-V spec it's invalid to call EntryPoint from another EntryPoint

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@e8fc0e9772968d4
LLVMSPIRVLib provides a public API through headers like LLVMSPIRVLib.h,
LLVMSPIRVOpts.h, and LLVMSPIRVExtensions.inc. Any target that links to
LLVMSPIRVLib and calls its functions must include these headers.

Currently, the include directory is marked PRIVATE, which prevents CMake
from automatically propagating include paths to downstream targets. This
forces consumers to manually add the include directories.

This commit makes the include directory PUBLIC with BUILD_INTERFACE,
following standard CMake practice for libraries with public APIs. This
allows targets linking to LLVMSPIRVLib to automatically get the correct
include paths, which is necessary for in-tree consumers like
opencl-clang.

Changes:
- lib/SPIRV/CMakeLists.txt: Move ${LLVM_SPIRV_INCLUDE_DIRS} from PRIVATE
to PUBLIC with $<BUILD_INTERFACE:...> generator expression
- tools/llvm-spirv/CMakeLists.txt: Remove redundant explicit include
since it's now automatically propagated via CMake target propagation

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@ab0c969d80948f9
Currently, the `DESTINATION` arguments to `install()` all contain
absolute paths prefixed with `${CMAKE_INSTALL_PREFIX}/`.

This PR gets rid of such prefixes as they are redundant (CMake already
prepends it as needed) and advised against by CMake documentation (see
`cmake-commands(7)` or [this
link](https://cmake.org/cmake/help/latest/command/install.html#common-options)).

Passing absolute destinations to `install()` breaks situations where
`cmake --install` is given the `--prefix` option, and also when
specifying `CMAKE_STAGING_PREFIX` for cross-builds since it would get
ignored in favor of the absolute path.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@de0bb2ad43bbf45
Fix the in-tree failure by temporarily disabling llc runs in
builtin_vars_different_type.ll.

From llvm/llvm-project#212685, LLC now requires
`SPV_EXT_long_vector` to be enabled when a non-standard vector size is
present; additionally, LLC outputs `OpTypeVectorIdEXT` (5288) which
isn't supported by the Reader now.

I have a pending PR #3951 which adds support for `OpTypeVectorIdEXT` in
the Reader. These LLC run can be re-enabled once #3951 is merged.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@d916d6b34ee5093
upstream commit fa23198 replaced llvm::Any with a tagged IRUnitRef.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Upstream commit 4a8b939 ("[Clang][Sema] Fix lambda attribute
processing order with clang optimize off") added a check for an
always_inline lambda declared in the initializer of a namespace-scope
variable under `#pragma clang optimize off`.

intel/llvm intentionally diverges from upstream in
Sema::getCurrentMangleNumberContext(): commit 478c205 ("[SYCL] Fix
Lambda Mangling in Namespace-Scope Variable Initializers", #20176)
cherry-picks community PR llvm/llvm-project#159115, which mangles the
the closure type with a closure-prefix for the enclosing variable.

CMPLRLLVM-77788

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

(partially cherry picked from commit 9c508e7)
Update ComparePointers.cl, type-scavenger/ptr-abuse.ll to expect
PtrEqual/PtrNotEqual instead of ConvertPtrToU+IEqual/INotEqual.

Update spirv_param_decorations_quals.ll CHECK-BACKEND to expect both
Volatile and NoAlias decorations (the upstream commit removing Volatile
from the backend is not yet in our merge range).

Remove XFAIL from instructions/ptrcmp.ll since the OpPtrEqual fix makes
it pass now.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@iclsrc iclsrc added the disable-lint Skip linter check step and proceed with build jobs label Sep 3, 2026
@jsji jsji closed this Sep 5, 2026
@jsji jsji reopened this Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disable-lint Skip linter check step and proceed with build jobs

Projects

None yet

Development

Successfully merging this pull request may close these issues.