Treat -E/-S/-fsyntax-only as compile-only, not link - #11
Merged
Conversation
After a successful compile, invoke ${HIP_PATH}/bin/chip-kernel-verify on the
output to detect entry points dropped by IGC (intel-graphics-compiler#403).
Env overrides: HIPCC_VERIFY=0 disables, HIPCC_VERIFY=warn prints but never
fails. Default is controlled at build time by HIPCC_VERIFY_DEFAULT from the
parent chipStar CMake.
Without this guard, hipcc invocations during chipStar's own bootstrap build (when the install tree does not yet contain the verifier) fail with sh exit code 127, breaking the build. access(X_OK) lets the hook silently no-op when the binary is absent — running the verifier is best-effort.
-c/-dc/-E/-S outputs carry partial pre-link offload bundles that the SPIR-V extractor was not designed to parse. Running the verifier on those (CTest: TestSeparateCompilation, TestRDCWithMultipleHipccCmds, TestStaticLibRDC) was segfaulting in extractSPIRVModule's bundle-walking path. Final SPIR-V is produced at link time anyway, so verification on link-final outputs covers the real surface; verifying intermediates was never meaningful.
processArgs() set compileOnly for -c, --genco, -dc and -M/-MM but not for
-E, -S or -fsyntax-only, so the driver treated those as link invocations.
Two consequences:
* HIPLDFLAGS were appended, producing spurious "-lCHIP: 'linker' input
unused" style warnings on every preprocess-only run.
* The post-link chip-kernel-verify pass ran on non-final output. Its
guard is written as !opts.compileOnly and its comment already states
the intent to exclude -c/-dc/-E/-S, but -E and -S never reached it.
Running the verifier on `hipcc -E` output crashed it: preprocessed
HIP is a *textual* offload bundle whose delimiter comments contain
the literal string __CLANG_OFFLOAD_BUNDLE__, which the SPIR-V
extractor mistakes for the binary bundle magic and then parses ASCII
as a bundle header.
The crash surfaced only where chip-kernel-verify gets past its ocloc
availability check, i.e. Intel GPU hosts.
pvelesko
added a commit
to CHIP-SPV/chipStar
that referenced
this pull request
Jul 29, 2026
computeHiprtcCacheKey() keyed on the raw HIP source, so it never saw the
content of headers pulled in by #include, in particular headers resolved
from -I filesystem paths. Editing such a header did not change the key, so
a stale, previously cached SPIR-V was served silently.
When the source may include headers, preprocess it and key on the
preprocessed translation unit. A conservative scan skips the preprocess for
self-contained sources, where the raw source is already a complete key.
Fixing this exposed three latent bugs that had to be resolved for it to
work at all:
* hipcc never set compileOnly for -E/-S/-fsyntax-only, so it treated them
as link invocations: it appended link flags and ran the post-link
chip-kernel-verify pass on output that is not a final image.
Preprocessed HIP is a *textual* offload bundle whose delimiter comments
contain the literal __CLANG_OFFLOAD_BUNDLE__, which the SPIR-V
extractor mistook for the binary bundle magic and then parsed as a
bundle header, crashing. Only hosts with ocloc got far enough to see
it, which is why this looked like a compiler bug on the Intel runners.
* extractSPIRVModule() walked the bundle descriptors using counts and
sizes read out of the buffer with no bound on the buffer itself. It now
takes an optional size and rejects out-of-range descriptors, and
chip-kernel-verify skips textual bundles outright.
* processOptions() ran only on the cache-miss path, but it is also what
records "warning: ignored option" in the program log. On a cache hit
hiprtcGetProgramLog() therefore came back empty, making the log depend
on cache state (TestHiprtcOptions passed against a cold cache and
failed on every run after). It is now called once, before the cache
lookup, which also stops the preprocess pass from logging the same
warning twice.
Tests: TestHiprtcCacheIncludes asserts that -I header content participates
in the key (miss / hit / miss on edit / hit on revert).
TestHiprtcCacheProgramLog asserts the program log is identical on cache hit
and miss and that diagnostics are not duplicated. Both run through a
wrapper that provisions a guaranteed-empty cache per run.
Requires the HIPCC submodule bump in this commit (CHIP-SPV/HIPCC#11,
now merged to HIPCC main) for the -E/-S fix.
Fixes #1335
Co-authored-by: Paulius Velesko <pvelesko@pglc.io>
pvelesko
added a commit
to CHIP-SPV/chipStar
that referenced
this pull request
Jul 30, 2026
computeHiprtcCacheKey() keyed on the raw HIP source, so it never saw the
content of headers pulled in by #include, in particular headers resolved
from -I filesystem paths. Editing such a header did not change the key, so
a stale, previously cached SPIR-V was served silently.
When the source may include headers, preprocess it and key on the
preprocessed translation unit. A conservative scan skips the preprocess for
self-contained sources, where the raw source is already a complete key.
Fixing this exposed three latent bugs that had to be resolved for it to
work at all:
* hipcc never set compileOnly for -E/-S/-fsyntax-only, so it treated them
as link invocations: it appended link flags and ran the post-link
chip-kernel-verify pass on output that is not a final image.
Preprocessed HIP is a *textual* offload bundle whose delimiter comments
contain the literal __CLANG_OFFLOAD_BUNDLE__, which the SPIR-V
extractor mistook for the binary bundle magic and then parsed as a
bundle header, crashing. Only hosts with ocloc got far enough to see
it, which is why this looked like a compiler bug on the Intel runners.
* extractSPIRVModule() walked the bundle descriptors using counts and
sizes read out of the buffer with no bound on the buffer itself. It now
takes an optional size and rejects out-of-range descriptors, and
chip-kernel-verify skips textual bundles outright.
* processOptions() ran only on the cache-miss path, but it is also what
records "warning: ignored option" in the program log. On a cache hit
hiprtcGetProgramLog() therefore came back empty, making the log depend
on cache state (TestHiprtcOptions passed against a cold cache and
failed on every run after). It is now called once, before the cache
lookup, which also stops the preprocess pass from logging the same
warning twice.
Tests: TestHiprtcCacheIncludes asserts that -I header content participates
in the key (miss / hit / miss on edit / hit on revert).
TestHiprtcCacheProgramLog asserts the program log is identical on cache hit
and miss and that diagnostics are not duplicated. Both run through a
wrapper that provisions a guaranteed-empty cache per run.
Requires the HIPCC submodule bump in this commit (CHIP-SPV/HIPCC#11,
now merged to HIPCC main) for the -E/-S fix.
Fixes #1335
Co-authored-by: Paulius Velesko <pvelesko@pglc.io>
pvelesko
added a commit
to CHIP-SPV/chipStar
that referenced
this pull request
Jul 30, 2026
computeHiprtcCacheKey() keyed on the raw HIP source, so it never saw the
content of headers pulled in by #include, in particular headers resolved
from -I filesystem paths. Editing such a header did not change the key, so
a stale, previously cached SPIR-V was served silently.
When the source may include headers, preprocess it and key on the
preprocessed translation unit. A conservative scan skips the preprocess for
self-contained sources, where the raw source is already a complete key.
Fixing this exposed three latent bugs that had to be resolved for it to
work at all:
* hipcc never set compileOnly for -E/-S/-fsyntax-only, so it treated them
as link invocations: it appended link flags and ran the post-link
chip-kernel-verify pass on output that is not a final image.
Preprocessed HIP is a *textual* offload bundle whose delimiter comments
contain the literal __CLANG_OFFLOAD_BUNDLE__, which the SPIR-V
extractor mistook for the binary bundle magic and then parsed as a
bundle header, crashing. Only hosts with ocloc got far enough to see
it, which is why this looked like a compiler bug on the Intel runners.
* extractSPIRVModule() walked the bundle descriptors using counts and
sizes read out of the buffer with no bound on the buffer itself. It now
takes an optional size and rejects out-of-range descriptors, and
chip-kernel-verify skips textual bundles outright.
* processOptions() ran only on the cache-miss path, but it is also what
records "warning: ignored option" in the program log. On a cache hit
hiprtcGetProgramLog() therefore came back empty, making the log depend
on cache state (TestHiprtcOptions passed against a cold cache and
failed on every run after). It is now called once, before the cache
lookup, which also stops the preprocess pass from logging the same
warning twice.
Tests: TestHiprtcCacheIncludes asserts that -I header content participates
in the key (miss / hit / miss on edit / hit on revert).
TestHiprtcCacheProgramLog asserts the program log is identical on cache hit
and miss and that diagnostics are not duplicated. Both run through a
wrapper that provisions a guaranteed-empty cache per run.
Requires the HIPCC submodule bump in this commit (CHIP-SPV/HIPCC#11,
now merged to HIPCC main) for the -E/-S fix.
Fixes #1335
Co-authored-by: Paulius Velesko <pvelesko@pglc.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
processArgs() set
compileOnlyfor-c/--genco/-dc/-M, but not for-E/-S/-fsyntax-only, so hipcc treated those as link invocations: it appended HIPLDFLAGS (spurious "linker input unused" warnings) and ran the post-linkchip-kernel-verifyon output that is not a final image.That crashed on
hipcc -E, whose output is a textual offload bundle containing the literal__CLANG_OFFLOAD_BUNDLE__, which the SPIR-V extractor parses as a binary bundle header. Only hosts with ocloc reach it. The existing guard already names-c/-dc/-E/-Sin its comment; the parser just never set the flag.Note: main is 6 commits behind what chipStar already pins (1f2628f), so this PR includes that pre-existing HIPCC_VERIFY series plus the one new commit.
Needed by CHIP-SPV/chipStar#1375.