Skip to content

LLVM and SPIRV-LLVM-Translator pulldown (WW33 2026) - #22939

Draft
iclsrc wants to merge 3237 commits into
syclfrom
llvmspirv_pulldown
Draft

LLVM and SPIRV-LLVM-Translator pulldown (WW33 2026)#22939
iclsrc wants to merge 3237 commits into
syclfrom
llvmspirv_pulldown

Conversation

@iclsrc

@iclsrc iclsrc commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

timurgol007 and others added 30 commits August 4, 2026 11:09
…ate (#213640)

Variable templates are a bit nicer to read and improve compile times a
bit.
Also adds the place holders for other OS's as well as the structure for
cross platform code going forward.

Prefer sys calls as we can't be sure what runtime we may end up linking
with
Some features can be controlled via the kernel so this makes it easier
than relying on __cpuid for now.

The triples are now more accurate and include the os version on darwin. 

All results are a string that are passed in the default map with the key are llvm subtarget features valid strings
orc-rt.Executor.SubtargetFeatures

Adds a new process regression test as well, with a best effort
guess that the triple returned is correct.
PointerReplacer mutates PHI types when replacing an alloca with a
pointer in another address space. Mutating a value type in place can
invalidate existing users whose result types or operand constraints were
formed from the original pointer type.

For example:
```
%p = phi ptr addrspace(5) [ %a, %bb0 ], [ %b, %bb1 ]
%g = getelementptr i8, ptr addrspace(5) %p, i64 1
```

Changing `%p` to `ptr addrspace(4)` leaves the existing GEP result in
`AS5` while its pointer operand is now in `AS4`. (This is what exposed
the bug). This triggered:

https://github.com/llvm/llvm-project/blob/0bcff14b1740cf32f9e0983726238dcf353c6ac8/llvm/lib/IR/Operator.cpp#L129-L131

Create a new PHI when the replacement changes type so existing users
remain attached to the original well-typed graph while PointerReplacer
builds their replacements. Preserve in-place operand updates when the
PHI type is unchanged.

Assisted-by: Codex

---------

Signed-off-by: Keshav Vinayak Jha <keshavvinayakjha@gmail.com>
InstCombine converts the high-half addition of vector comparison masks
into an OR. Recognise the resulting trunc(or(setcc, setcc)) DAG and
reconstruct the canonical ADDHN pattern for the supported NEON types.
…ToStaticExpandShape) (#207241)

Fixes encoding drop in `tensor.*` canonicalizers.

Patterns that only refine a tensor's shape (never merge/combine data)
now propagate the encoding: `ConvertToStaticExpandShape`,
`PadOp::inferResultType` (and its callers `FoldSourceTensorCast`,
`FoldStaticPadding`). An encoding implementing
`VerifiableTensorEncoding` is re-verified against the refined shape and
dropped if invalid (e.g. sparse); an opaque encoding (no interface) is
propagated as-is.

Patterns that merge/combine tensors (`ConcatOp::inferResultType`,
`InferConcatOperandTypes`, `CollapseShapeOp::inferCollapsedType`) keep
the existing drop-encoding behavior - there's no static way to verify an
arbitrary encoding survives a merge or rank change when dynamic dims are
involved.

Documents this contract on `VerifiableTensorEncoding` in
`TensorEncoding.td`.

co-authored Claude Opus 4.7

Signed-off-by: Dmitrii Makarenko <dmitrii.makarenko@intel.com>
InstCombine converts vXi1 logic reductions to bitcasted scalar integer
ops - we should be testing that, not llvm.vector.reduce.and.v32i1 calls
Add support for `DenseResourceElementsAttr` in TOSA reshape folding.
Currently we copy construct `locale`s whenever we swap, which is quite
expensive for locales since that does atomic increments and decrements.
We can just swap the pointers instead.
The LangRef wording changed in 15bb4a9 ([IR] Make semantics of
strictfp consistent v2, #211769) is unfortunately incorrect. There are
some open questions around its semantics, but a simple revert should do
for the moment.

Reported-by: Ömer Sinan Ağacan <omer@osa1.net>
…onicalizers (#207239)

`InsertSliceOpConstantArgumentFolder` re-derives the refined source type
via `ExtractSliceOp::inferCanonicalRankReducedResultType`, which copies
the encoding of the passed-in "source template" - in this pattern,
`insertSliceOp.getDestType()`.
For a static, encoding-less destination this silently drops any encoding
the actual source carried, which downstream dialects can use for
mandatory metadata (upper bounds, layout, sparsity descriptors) lost
during `--canonicalize`.

Rebuild the refined source type carrying the original source's encoding.
If the encoding implements `VerifiableTensorEncoding`, re-verify it
against the refined shape and drop it if it no longer holds (e.g. a
rank-dependent sparse encoding); otherwise treat it as
opaque/shape-agnostic and propagate it unconditionally.
Shape refinement (the `?` -> static direction) is unchanged and still
satisfies `preservesStaticInformation`.

lit created with Claude Opus 4.7

Signed-off-by: Dmitrii Makarenko <dmitrii.makarenko@intel.com>
…(#213730)

These tests are never executed since they require C++20, and the C++03
frozen headers only run in C++03 mode.
…#213732)

The filter regex used `libcxx(abi?)`, which matches `libcxxab` and
`libcxxabi`, but never just `libcxx`.
Based on local measurements, the associative containers are by far the
slowest benchmarks to run. While there is value in benchmarking small
and large sizes, we can significantly cut down benchmark times by
stripping down to only 2 sizes (from 4).

With this patch, the benchmarks go from 3124s to 1766s across the
associative container benchmarks, which is -43% of their execution time,
and corresponds to ~15% of the entire benchmark suite.

Towards #173032
…d (#213923)

InstCombine converts vXi1 logic reductions to bitcasted scalar integer
ops - we should be testing that, not llvm.vector.reduce.or.v3i1 calls

Exposes some really poor scalarization on pre-AVX512 targets
olMemcpy currently disallows host-to-host copies with a queue, even
though that is a desirable use case (e.g. to copy a buffer as a
dependency for another operation)

This PR adds support for asynchronous host-to-host copies by adding
`GenericDeviceTy::dataMemcpy` and the corresponding required
`dataMemcpyImpl` plugin operation. Unlike `dataSubmit`, `dataRetrieve`,
and `dataExchange`, this operation does not assign a device direction to
either pointer:
- CUDA: Uses `cuMemcpyAsync`, which by itself determines the pointer
types and preserves stream ordering. Dynamic CUDA symbol declarations
and `_v2` lookup support are included.
- Level Zero: Uses the existing queue `memoryCopy` operation (backed by
`zeCommandListAppendMemoryCopy`), which appends a memory-copy command to
the command list.
- AMDGPU: No "enqueue a host-to-host copy" operation exists directly in
that API, so we enqueue a `std::memcpy` callback through
`pushHostCallback`.
- Host: Call `memcpy` directly.

The `olMemcpy` API documentation now states that queued host-to-host
copies are ordered with other work in the queue. The public function
signature is unchanged.

A new unit test executes an `h2d -> d2h -> h2h -> h2d -> d2h` operation
chain, which should fail if the queue order isn't respected.

Assisted-by: Codex
…gets (#200134)

I am working with a binary where some symbols are generated from linker
scripts. They end up identified as `eSymbolInvalid` when loaded in LLDB.
OpenOCD can try to fetch them.

Some might even be hard-coded data, not going through an address in the
binary (explaining the presence of the check and raw value
return).

Testing it showed that **GDB returns them despite them not being proper
addresses**.
These can also be generated by C++ static constexpr, such values could
be accessed by a qSymbol query.

358cf1e introduced a divergence between GDB and LLDB where LLDB
does not serve symbols of unknown type through GDB protocol command
`qSymbol`. Per commit description, this is an expected behavior on
MachO-based platforms, but it is not on ELF-based platforms, where LLDB
should follow GDB. The changes introduced by said commit are now gated
behind an architecture check.
… b, -0.0)

A copyable fmul absorbed into fmuladd(a, b, -0.0) does not appear in
the operand columns of its own node, so the operand scan never
released the schedule data of the copyable instruction itself and
scheduling ended with unscheduled bundles. Release it explicitly when
the copyable element shows up in no operand column.

Reviewers: 

Pull Request: llvm/llvm-project#213937
Do addrspace cast for allocas that live in address space different from
the datalayout's alloca address space, otherwise ASan will crash during
use replacement
…s. (#212800)

For SVE2 we can use top/bottom [S/U]ABAL[T/B] instruction. SVE2p3 can
use just [S/U]ABAL.
MrSidims and others added 26 commits August 13, 2026 02:57
Return early when the value has no decorations of its own and is not an
alloca of struct type.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@880cbb08c8d3c26
Temporarily add 2 opcodes back from old spec of
`SPV_INTEL_fp_conversions`, for backward compatibility of SPIRV Reader
only:
- `OpClampConvertFToFINTEL`: must translate to the same LLVM IR as
`OpFConvert` + `SaturatedToLargestFloat8NormalConversionEXT`
- `OpClampStochasticRoundFToFINTEL`: must translate to the same LLVM IR
as `OpStochasticRoundFToFINTEL` +
`SaturatedToLargestFloat8NormalConversionEXT`.

The Writer keeps unchanged and emits the current ops from latest spec.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@6734efd9e659963
validateWordCount() seeked the input stream to its end and back on every
module-scope instruction just to bounds-check the word count.

Cache the total stream size once in parseSPIRV() and bounds-check each
instruction with a single tellg().

AI-assisted: Claude Fable 5

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@ee776682e683e1f
This is a quick bug fix PR, as a follow-up of
KhronosGroup/SPIRV-LLVM-Translator#3777, which
didn't cover the early-out path in
SPIRVLowerBitCastToNonStandardType.cpp. As a consequence, if the pass
has vector with non-standard size as input but with only
`SPV_EXT_long_vector` enabled, it will crash later.

Also added missing coverage in SPIRVUtils.cpp when handling intrinsics.

The new tests simply mirror the ones in
`extensions/INTEL/SPV_INTEL_vector_compute`.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@4ace1857b99531c
Replace debug-only asserts in the SPIR-V decode path with runtime error
checks, so that malformed input modules are rejected gracefully instead
of causing crashes (null-deref / type-confusion) in release builds.

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

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@fa264644b16a2fa
According to
https://github.khronos.org/SPIRV-Registry/extensions/KHR/SPV_KHR_subgroup_rotate.html
both Delta and ClusterSize must be a scalar of integer type, whose
Signedness operand is 0.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@a37897185f29584
OpImageQuerySizeLod requires the image to have MS = 0, so size queries
on multisampled images must use OpImageQuerySize without a LOD operand

Inspired by the change in LLVM SPIR-V backend:
llvm/llvm-project#190767

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@2a28bf4a951835d
For backward compatibility of the SPIRV Reader only: older modules
emitted the `SPV_INTEL_float4` `Float4E2M1INTEL` type (6214) as the
`StochasticRoundFToFINTEL` result. Map it to the same builtin as the
current `SPV_EXT_ocp_microscaling_types` `Float4E2M1EXT` type (4225).

The Writer keeps unchanged and emits the EXT type.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@b888251df63666c
As apt packages for llvm 24 are not available yet, temporarily switch
the code style and in-tree build checks back to llvm 23.

Revert this commit once llvm 24 packages are available.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@ca6c23d351ddc63
#3879)

llvm/llvm-project#209232 fixed the SPIR-V
backend selectIToF to preserve signedness (sitofp i1 true was
miscompiled as 1.0 instead of -1.0), so the select now produces -1
rather than 1

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@9abcbf1d42609e3
In LLVM 23, {Optional,Required}PassInfoMixin became preferred for
creating passes instead of raw PassInfoMixin with isRequired. In LLVM
24, PassInfoMixin will be moved to a detail namespace, causing
compilation failures.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@25ec4c4cb760694
llvm.sincos(x) returns {sin(x), cos(x)}, but OpenCL sincos(x, &cos)
returns sin(x) and stores cos(x) via pointer. Bridge this by allocating
a Function-storage pointer for the cos output, calling OpenCL sincos,
loading the cos value, and constructing the result. Register llvm.sincos
in isKnownIntrinsic so
-spirv-allow-unknown-intrinsics does not erroneously treat it as
unknown.

Exposed by llvm/llvm-project@0e877fd1a637
("Reland '[InstCombine] Combine llvm.sin/llvm.cos libcall pairs into
llvm.sincos' (#194616)"), which caused llvm-spirv to reject the
intrinsic as unknown in our downstream tests.

Co-Authored-By: Claude Sonnet 4.6 (1M context)

---------

Co-authored-by: Jinsong Ji <jinsong.ji@intel.com>
Co-authored-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@541e7fce4bb46e4
As apt packages for llvm 24 are not available yet, temporarily switch
the code style check compile command db generation back to llvm 23.

Revert this commit once llvm 24 packages are available, together with
ca6c23d3 ("Temporarily resort to llvm 23 packages (#3914)", 2026-07-27).

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@25cd8232537fa74
handleCastInstructions materialized the bool operand as unsigned 0/1 for
both uitofp and sitofp, so sitofp i1 true was miscompiled as 1.0 instead
of -1.0

Inspired by llvm/llvm-project#209232

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@f01fca75c728192
…3927)

Numeric-named LLVM functions (e.g. @0) have no meaningful linkage name,
so LinkageAttributes for them is dropped

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@ed918a43b7053ed
The Base Type operand of an untyped access chain is the type being
indexed, not a pointer to it, so it must be used as is.

The patch addresses issues discovered during testing for
llvm/llvm-project#201233

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@706ad87af0c7f31
OpIMul requires integer scalar/vector operands

OpTypeBool is not considered an integer type and causes spirv-val
failure

Inspired by llvm/llvm-project#207388

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@3063fda0acb8f3c
This reverts commit 25cd8232537fa74d40b757e15d40aeaaea69321b as
llvm-24 snapshot apt packages are now available.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@527182f5ee2a86d
This reverts commit ca6c23d351ddc63c962df5897125dfa9f04aa5dc as
llvm-24 snapshot apt packages are now available.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@67ea45e3b701943
Further hardening of the translator against malformed input to prevent
crashes. Specifically, this PR:
- Reports an error and invalidates module in `SPIRVFunction::decode()`
for opcodes that don't belong in function scope.
- Adds null check with module invalidation and early exit after
`Decoder.getEntry()` in `SPIRVFunction::decodeBB()` because it can
return `nullptr` and it was otherwise dereferenced down the line.
- Reports an error and invalidates module for unknown extended
instruction set IDs.
- Reports an  error and invalidates module for truncated instructions.

5 new lit tests are added that were crashing before this patch. These
new tests are a bit special, they need to feed deliberately malformed
SPIR-V to the translator, including opcodes that don't exist,
instructions in the wrong scope or truncated streams. Since spirv-as
normally validates its input, the tests use its `!<integer>` syntax to
inject raw 32-bit words directly into the binary output, bypassing
validation. For example, `!75535` emits the raw word `(1<<16)|9999`,
which encodes a single-word instruction with unknown opcode 9999. Care
must be taken with placement: `!` words after variadic instructions
(like OpTypeFunction) get absorbed as extra operands rather than emitted
as standalone instructions.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@b9b29b6d956277e
`SPV_KHR_float_controls2` makes `FPFastMathMode` valid for all core
instructions, so this patch enables translation of fast math flags for
`OpFunctionCall`.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@e640c567d37eccc
- control_flow_conversion_pass.cpp: Replace Loop::Edge with LoopInfo::Edge
  and use LI->getExitEdges(*Loop, exitEdges) after upstream LoopInfo refactor
- uniform_reassociation_pass.cpp: LoopInfo::verify() no longer takes DT arg
- work_item_loops_pass.cpp: insertDeclare returns DbgRecord* directly now,
  use cast<DbgVariableRecord> instead of cast<DbgRecord*>
- pass_functions.cpp: Use llvm.loop.vectorize.disable metadata (single operand)
  instead of llvm.loop.vectorize.enable with i1 false (no longer valid)
- no-recursion.cpp: Update test expectations for new destructor recursion warning
@iclsrc iclsrc added the disable-lint Skip linter check step and proceed with build jobs label Aug 13, 2026
Similar to #207217

The RST-to-Markdown migration (#206181) converted the RST flag
`:numbered:` into `:numbered: true`.

MyST parses the toctree `numbered` option as `int_or_nothing`, so the
string `true` fails with:

```
'toctree': Invalid option value for 'numbered': true:
invalid literal for int() with base 10: 'true'
```

This breaks the `-W` (warnings-as-errors) `docs-clang-html` build. Make
`numbered` a valueless flag, which MyST accepts (equivalent to the
original RST behavior of numbering all levels).
@jsji

jsji commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

This is ready for review.

@intel/dpcpp-nativecpu-reviewers (1 commit)

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.