Skip to content

Don't promote PromoteSubByte's own replacement instructions - #450

Open
maleadt wants to merge 1 commit into
intel:masterfrom
maleadt:fix-promote-sub-byte-visit
Open

maleadt wants to merge 1 commit into
intel:masterfrom
maleadt:fix-promote-sub-byte-visit

Conversation

@maleadt

@maleadt maleadt commented Oct 10, 2026 •

Copy link
Copy Markdown

PromoteSubByte::run visits the module with an InstVisitor while promoting it. Promotion can recurse through a loop PHI to its back-edge value later in the block, inserting replacement instructions ahead of the visitor. The visitor then promotes those replacements again and records them in promotedValuesCache. cleanUp() erases them while other replacements still use them, leaving poison operands and incorrect results.

Visit a snapshot of the instructions that existed before promotion started. The snapshot is taken after function promotion so cloned bodies are included; instructions are only erased during cleanup.

The new LIT test i1/phinodes-loop-carried.ll reproduces the failure: %w = icmp ne i1 %v, %u becomes icmp ne i8 poison, ... without the fix.

Found while investigating JuliaGPU/oneAPI.jl#678. The fix has been backported in JuliaPackaging/Yggdrasil#15068 (libigc_jll 2.34.4+3) and validated on Intel Iris Xe with Julia 1.12 and bounds checks enabled: the original reduction reproducer is correct, the standalone kernel goes from 256 incorrect work-items to zero, and the minimal driver-compiled kernel no longer contains undefined operands after PromoteSubByte.

Validation: all 38 current i1/ test files pass through a standalone build of this pass and FileCheck; the new regression fails without the fix. This standalone harness uses LLVM 16 and header shims, so it does not replace a full IGC LIT run and does not cover the GenISA int4 intrinsics.

The Julia-side regression is in JuliaGPU/oneAPI.jl#679. Its equal-input check fails with libigc_jll 2.34.4+2 and passes with +3.

PromoteSubByte visits the module with an InstVisitor while promoting it.
Promoting an instruction can promote instructions further down its block
(a PHI node's back-edge value, for example), inserting their replacements
ahead of the visitor. The visitor then promotes those replacements again,
which records them in the promotion cache, and cleanUp() erases them while
other replacements still use them. Their users end up with undef operands:
a loop that carries an i1 through a PHI node loses the value.

Visit only the instructions that existed before promotion started.

Signed-off-by: Tim Besard <tim.besard@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant