Repository navigation
fix(rocke): refuse buffer_rsrc operands its lowerings cannot take - #14842
Conversation
✅ All Checks Passed — Ready for Review
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🎉 All checks passed! This PR is ready for review. |
|
Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max PR #14842 — refuse buffer_rsrc operands its lowerings cannot take (cgmillette, AICK-2900) — 🟡 First-round: refusals sound; builtin claim inaccurate
Utility: 🟢 Positive — same-text refusals replace late llc errors and silent truncation; no emission change. Legend: 🔴 blocking · 🟠 should-fix · 🟡 minor nit · 🟢 info/good · ⚪ retracted First-round review: first pass by a local qwen3.6 model, verified by the orchestrator (Claude Opus 5.5). Checks: merge with develop, build + ctest, byte identity, goldens, both-engine tests, develop before/after, parity operand sweep, CI logs at head. Flags whether a closer look is needed; not an approval or rejection. |
CongMa13
left a comment
There was a problem hiding this comment.
No new issues found. I agree with the following existing comments:
- HIP refusal rationale overstates the builtin's
intsignature — cgmillette, #14842 (comment)
CongMa13
left a comment
There was a problem hiding this comment.
No new P0 or P1 issues were identified during this review. The changes are approved.
There was a problem hiding this comment.
🟡 Changes recommended
Remaining global-memory handlers in both engines hard-code address space 1 for constant-space parameters declared in address space 4, producing invalid LLVM IR.
1 open issue
What changed in this PR
Adds early buffer_rsrc operand validation to rocKE’s Python and C++ lowering engines, preventing invalid LLVM IR and silently truncated HIP descriptor bounds.
Changes:
- Reject unsupported pointer address spaces and byte-count widths.
- Add regression tests for rejected operands and supported forms across both engines.
- Document the LLVM and HIP operand constraints.
| File | Description |
|---|---|
dnn-providers/hip-kernel-provider/rocke/platform/tests/core/test_buffer_rsrc_operands.py |
Adds rejection, acceptance, and engine-parity tests. |
dnn-providers/hip-kernel-provider/rocke/platform/tests/core/future_intrinsic_lowering.cpp |
Adds C++ LLVM and HIP regression cases. |
dnn-providers/hip-kernel-provider/rocke/platform/python/rocke/core/lower_llvm.py |
Validates pointer address space and LLVM 20 byte-count width. |
dnn-providers/hip-kernel-provider/rocke/platform/python/rocke/core/lower_hip.py |
Rejects non-i32 byte counts before HIP emission. |
dnn-providers/hip-kernel-provider/rocke/platform/dsl_docs/reference/op_vocabulary.md |
Documents backend-specific operand rules. |
dnn-providers/hip-kernel-provider/rocke/platform/cpp/core/lower_llvm/mem.cpp |
Mirrors the Python LLVM operand checks. |
dnn-providers/hip-kernel-provider/rocke/platform/cpp/core/lower_hip/lower_hip_mem.cpp |
Mirrors the HIP byte-count restriction. |
Review effort: Max
|
Feedback addressed at b54101d:
|
|
Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max PR #14842 — refuse buffer_rsrc operands its lowerings cannot take (cgmillette, AICK-2900) — 🟠 Follow-up: copied check; CI-skipped tests
Utility: 🟢 Positive — same-text refusals replace late LLVM errors; constant-space loads now compile. Legend: 🔴 blocking · 🟠 should-fix · 🟡 minor nit · 🟢 info/good · ⚪ retracted Follow-up review: first pass by a local qwen3.6 model, verified by the orchestrator (Claude Opus 5.5). Checks: merge with develop, build + ctest, byte identity, goldens, both-engine op probe, LLVM verifier, parity census, CI logs at head, code quality. Flags whether a closer look is needed; not an approval or rejection. |
|
Re our review (#14842 (comment)): All items are addressed in 7425d42. N2 (one check, copies diverge): fixed in both engines.
N3 (cases no CI lane runs): fixed.
N4 (names and clause): fixed.
Open notes in the table:
Gates on 7425d42:
|
There was a problem hiding this comment.
🔵 Needs a closer look
The cross-engine global-memory lowering and public refusal-contract changes require maintainer CI/toolchain confirmation of byte identity, parity, and llc/hipcc acceptance.
No open issues 🎉
1 resolved since last review
Review effort: Max
|
Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max PR #14842 — refuse buffer_rsrc operands its lowerings cannot take (cgmillette, AICK-2900) — 🟠 Follow-up: rebase with one engine list
Utility: 🟢 Positive — one space check per engine; Python cases now run without the binding Legend: 🔴 blocking · 🟠 should-fix · 🟡 minor nit · 🟢 info/good · ⚪ retracted Follow-up review: first pass by a local qwen3.6 model, verified by the orchestrator (Claude Opus 5.5). Checks: merge-tree with develop; local merge with develop |
buffer_rsrc lowers to the p1 overload of llvm.amdgcn.make.buffer.rsrc, which names its pointer ptr addrspace(1). A pointer parameter declared addr_space="constant" is ptr addrspace(4) in the kernel header, so the call did not match the header and llc rejected the module. The LLVM lowering of both engines now refuses it with the text the global-pointer ops already use: buffer_rsrc ptr must be a global pointer, got ptr addrspace(4) (its parameter's addr_space) At llvm20 the intrinsic takes an i32 num_records, and the lowering printed any num_bytes operand as i32, so an i64 operand did not match its own definition. Both engines now refuse a num_bytes that is not i32 at llvm20: tile.buffer_rsrc num_bytes must be i32 at llvm20, got i64; the llvm20 make.buffer.rsrc takes an i32 num_records, so pass the byte count as i32 llvm22 and later still take an i32 (zero-extended) or an i64. The HIP lowering calls __builtin_amdgcn_make_buffer_rsrc, whose num_records is an int, and cast num_bytes to (int): an i64 byte count was silently truncated to 32 bits, at every LLVM version. The HIP lowering of both engines now refuses a num_bytes that is not i32: tile.buffer_rsrc num_bytes must be i32 in the HIP lowering, got i64; the HIP builtin takes an int num_records, so the byte count would be truncated at every LLVM version; pass it as i32 The HIP lowering keeps a constant-space pointer: its kernel signature declares every pointer parameter the same way whatever its addr_space, and the builtin takes a void*, so the source compiles and the descriptor is built from the right address. No IR or HIP source changes for a kernel that lowered before. Tests: tests/core/test_buffer_rsrc_operands.py checks every refusal in both engines with the exact text, that the accepted forms lower to the same IR in both engines at every flavor, and that both HIP lowerings keep an i32 num_bytes and a constant-space pointer; the C++ test future_intrinsic_lowering gains the same cases. op_vocabulary.md states the rules. Co-Authored-By: Claude <noreply@anthropic.com>
The HIP lowering refuses a buffer_rsrc num_bytes wider than i32. Its message and comments said the builtin takes an int num_records at every LLVM version, which is not true: newer clang declares num_records as a uint64_t. What truncates a wider byte count is the (int) cast the lowering emits, so the message, the comments and the op reference now say that, in both engines. The refusal itself is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
A pointer parameter declared addr_space="constant" keeps its global IR type, but the kernel header types it ptr addrspace(4). The global loads, stores, atomics, flag ops, cooperative store and global/LDS copies named it ptr addrspace(1) anyway, so LLVM rejected the module. The global loads now name the pointer's own type, so a kernel can read through a constant-space parameter; a flat or LDS pointer, which they also named ptr addrspace(1), is refused. Every other op that addresses global memory through the pointer refuses a constant-space parameter in the LLVM lowering of both engines, as buffer_rsrc and the global_ptr ops already do. The C++ global_store_async_from_lds and global_load_tr16_b128 lowerings now check the header type as the Python engine does. The shared pointer-space resolver's message says "op" rather than "intrinsic", since plain loads use it too. Co-Authored-By: Claude <noreply@anthropic.com>
The Python engine refuses a global-pointer op on a parameter whose header type is not ptr addrspace(1) with a TypeError. The C++ engine failed the same refusal with ROCKE_ERR_VALUE, and so did its global_store_async_from_lds and global_load_tr16_b128 pointer checks. It now fails them with ROCKE_ERR_TYPE, the status that matches TypeError. Co-Authored-By: Claude <noreply@anthropic.com>
… engine Every LLVM-lowering op that names its pointer in one fixed space now refuses any other header type through one helper per engine (_require_header_ptr / rocke_ll_require_header_ptr, with a global-pointer form), so the store, atomic, flag, prefetch, transposed-load, cluster-load and LDS-copy refusals share one text and one error type: TypeError in Python, ROCKE_ERR_TYPE in C++. The multi-space resolver the global loads, av_*_b128 and s_prefetch_* use refuses with the same type. The refusal names the op's builder (store_f16 rather than global_store, global_store rather than global_store_typed) and the operand, and blames the parameter's addr_space only when the override moved its header type. The engine-parity test helpers gain per-engine forms, which also check the C++ status against the expected exception type. The constant-space and buffer_rsrc tests run per engine, so their Python cases run in lanes that do not build the rocke_engine binding, and a new future_intrinsic_lowering CTest case checks a sample of the C++ side there. The comments on the HIP builtin now say that clang after ROCm 7.1 takes a 64-bit num_records (int64_t in LLVM 22, uint64_t after). Co-Authored-By: Claude <noreply@anthropic.com>
…refusals The buffer_rsrc byte-count refusals now name the builder (buffer_rsrc) rather than the op (tile.buffer_rsrc), and global_load_lds and global_load_async_to_lds name their pointer operand src_ptr, as their builders do. Both engines change together. The HIP lowering's comment now says the builtin takes an int64_t num_records in LLVM 22 and 23. Co-Authored-By: Claude <noreply@anthropic.com>
The per-engine helpers now check for the rocke_engine binding as soon as they are asked for the C++ engine, so a "cpp" case skips with the binding's reason in a lane that does not build it, rather than lowering with the Python engine first. available_engines() says when to use it, and the helpers' own argument errors name the bad value and what they expected. Co-Authored-By: Claude <noreply@anthropic.com>
7425d42 to
6efc600
Compare
|
Rebased onto develop and addressed the 11-04 follow-up review. N5 (conflict in N4 (refusals name what the caller called):
N1 leftover: the HIP lowering's comment and the PR description now say the builtin takes an Both-engine helpers and the status code: they still compare only the message. The module docstring says why: some older refusals do not yet report the same status as the Python exception type. The per-engine helpers this PR adds do check the status. Our review gate also changed the per-engine helpers in one way: a Checks:
|
|
Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max PR #14842 — refuse buffer_rsrc operands its lowerings cannot take (cgmillette, AICK-2900) — 🟡 Follow-up: items fixed; CI needs push
Utility: 🟢 Positive — refusals now name the builder and operand; one engine list Legend: 🔴 blocking · 🟠 should-fix · 🟡 minor nit · 🟢 info/good · ⚪ retracted Follow-up review: first pass by a local qwen3.6 model, verified by the orchestrator (Claude Opus 5.5). Checks: range-diff and replay of the rebase; merge with develop (build, ctest, byte identity llvm20–24, both goldens, changed tests at llvm22, installed lane); 35 files using the engine helpers, unforced, with and without the engine; saved probes N2 and N3; both engines on the third byte-count text; |
…e-gfx942-i64-cfvst-loader Resolve conflicts with #15024 (runtime kv head count) and #14842 (buffer_rsrc operand checks). The i64 cfvst V page offset and its C++ twin now use the runtime token stride. Re-bless gfx942_attention_tiled_2d cfg18/19 in the differential golden. Co-Authored-By: Claude <noreply@anthropic.com>
…4842) ## Motivation `buffer_rsrc(ptr, num_bytes)` lowers to `@llvm.amdgcn.make.buffer.rsrc`. Two operand forms reached the LLVM lowering of both engines unchecked, and the module they produced was then rejected by `llc` with an error that did not point at the op: - a pointer parameter declared `addr_space="constant"`: it is `ptr addrspace(4)` in the kernel header, but the call names its pointer `ptr addrspace(1)` (LLVM 20 `llc`: `'%X' defined with type 'ptr addrspace(4)' but expected 'ptr addrspace(1)'`); - an i64 `num_bytes` at llvm20: that flavor's intrinsic takes an i32 `num_records`, and the lowering printed any operand as `i32` (LLVM 20 `llc`: `'%n' defined with type 'i64' but expected 'i32'`). The HIP lowering has the same kind of bug for the byte count: it calls `__builtin_amdgcn_make_buffer_rsrc` with `num_bytes` cast to `(int)`, so an i64 byte count was silently truncated to 32 bits (hipcc emits `trunc i64 %n to i32` before the call), and the descriptor bounded a smaller range than asked. ROCm 7.1's builtin takes an `int` `num_records` and later clang a 64-bit one (`int64_t` in LLVM 22 and 23, `uint64_t` after); the truncation comes from the cast the lowering emits. The constant-space mismatch was not specific to `buffer_rsrc`. The global loads, stores, atomics, flag ops, cooperative store and global/LDS copies also named a constant-space parameter `ptr addrspace(1)`, and LLVM rejected the module. This PR refuses these forms up front, in both engines, with a message that says what is wrong, and lets the global loads read through a constant-space parameter. ## Technical Details - Both checks need the lowering's context (the parameter's header type, the LLVM flavor), so they sit in the LLVM lowering of each engine, at the same point: Python `_op_tile_buffer_rsrc` (`core/lower_llvm.py`), C++ `op_tile_buffer_rsrc` (`cpp/core/lower_llvm/mem.cpp`). The global-pointer ops (`global_ptr_add`, `global_ptr_offset`, `global_ptr_to_i64`) already refuse a constant-space parameter there, and `buffer_rsrc` now uses the same helper (`_require_global_header_ptr` / `rocke_ll_require_global_header_ptr`) and so the same text: ``` buffer_rsrc ptr must be a global pointer, got ptr addrspace(4) (its parameter's addr_space) ``` - At llvm20 a `num_bytes` that is not i32 is refused: ``` buffer_rsrc num_bytes must be i32 at llvm20, got i64; the llvm20 make.buffer.rsrc takes an i32 num_records, so pass the byte count as i32 ``` llvm22 and later still take an i32 (zero-extended) or an i64, unchanged. - The HIP lowering of both engines (Python `_op_tile_buffer_rsrc` in `core/lower_hip.py`, C++ `_op_tile_buffer_rsrc` in `cpp/core/lower_hip/lower_hip_mem.cpp`) refuses a `num_bytes` that is not i32, at every LLVM version, because it passes `num_records` cast to `(int)`: ``` buffer_rsrc num_bytes must be i32 in the HIP lowering, got i64; the HIP lowering casts num_records to (int), so a wider byte count would be truncated; pass it as i32 ``` An i64 byte count still lowers through LLVM at llvm22 and later. - The HIP lowering keeps a constant-space pointer: its kernel signature declares every pointer parameter the same way (`float* __restrict__ X`) whatever its `addr_space`, and the builtin takes a `void*`. A hipcc probe of that source compiles, and the descriptor is built from the kernel argument's address. - Other global-memory ops on a constant-space parameter, in the LLVM lowering of both engines: - `global_load_f16`, `global_load` and `global_load_vN` name the pointer's own type (a table of the accepted spaces, `_GLOBAL_LOAD_PTR_TYPES` / `ROCKE_LL_GLOBAL_LOAD_PTR_TYPES`, resolved by the existing pointer-space resolver). They read a constant-space parameter as `load addrspace(4)` and refuse a flat or LDS pointer, which they also used to name `ptr addrspace(1)`. The resolver's message now says "op" rather than "intrinsic". - The stores, atomics, flag ops, `cooperative_global_store`, `global_load_lds` and `global_load_async_to_lds` refuse a constant-space parameter with the `global_ptr_*` text. - One check per engine: every op that names its pointer in one fixed space (the ops above, `global_prefetch`, `flat_prefetch`, `global_store_async_from_lds`, `global_load_tr16_b128` and both cluster loads) calls `_require_header_ptr` / `rocke_ll_require_header_ptr`, whose global-pointer form is `_require_global_header_ptr` / `rocke_ll_require_global_header_ptr`. The C++ `global_store_async_from_lds` and `global_load_tr16_b128` lowerings used to check only the IR type; they now check the header type, as the Python engine already did. - Every one of these refusals, and the pointer-space resolver's, is a `TypeError` in Python and `ROCKE_ERR_TYPE` in C++. The text names the op's builder (`store_f16`, `global_store`, `global_load_f16`, `global_load`) and the builder's name for the operand (`src_ptr` for the copies into LDS), and says "(its parameter's addr_space)" only when the parameter's override moved its header type. The `buffer_rsrc` byte-count refusals also name the builder. - The portable IR route lowers through the C++ engine, so it refuses the LLVM forms too. - No emission changes for a kernel whose IR LLVM accepted before: byte identity is unchanged, no golden is re-blessed, and the HIP source of every parity kernel is unchanged. - `dsl_docs/reference/op_vocabulary.md` states the rules next to the buffer ops. ## Test Plan - `tests/core/test_buffer_rsrc_operands.py`: - both LLVM lowerings refuse a constant-space pointer at llvm20, llvm22, llvm23 and llvm24, and an i64 `num_bytes` at llvm20, with the exact text; - controls: an i32 `num_bytes` at every flavor and an i64 one at llvm22 and later lower to identical IR in both engines; - both HIP lowerings refuse an i64 `num_bytes` with the exact text, and lower an i32 `num_bytes` over a global or a constant-space pointer to the same source. - `tests/core/test_constant_space_global_ops.py`: each LLVM lowering reads through a constant-space parameter with each global load at every flavor, the result compiles with the host clang, and a flat or LDS pointer is refused; every other op listed above refuses a constant-space parameter with the exact text and type, an LDS parameter is refused without the addr_space clause, and `flat_prefetch` refuses a parameter moved to constant space. - Both test files run each case per engine (`rocke/tests/engines.py` gains per-engine helpers that also check the C++ status), so the Python cases run in lanes that do not build the `rocke_engine` binding; a C++ case there skips before either engine runs. Develop's `available_engines()` returns the same `ENGINES` list, or the Python engine alone when the binding is not built. - `tests/core/future_intrinsic_lowering.cpp` (ctest `rocke_future_intrinsic_lowering`): the C++ LLVM and HIP lowerings refuse the `buffer_rsrc` forms, with their status codes, and still lower the accepted ones; a `constant_space_global_ops` case checks a sample of the constant-space loads and refusals, so the C++ side also runs in those lanes. - HIP source of every parity-family config (95 families) for gfx942, gfx950 and gfx1201, before and after the change. - Build, ctest, byte identity at llvm20 / llvm22 / llvm23 / llvm24, golden checks, portable IR against a freshly built shared engine, the touched tests with both engines in strict mode, and the platform suite compared by failure name against develop. ## Test Result - Before the change (develop), both `buffer_rsrc` LLVM forms lowered without error and LLVM 20 `llc` rejected the result with the errors above; the HIP lowering of an i64 `num_bytes` compiled, and hipcc truncated the byte count to 32 bits. A global load through a constant-space parameter produced a module the host clang rejects. - HIP source (first revision): the Python HIP lowering's 3772 (config, arch) texts across the 95 parity families are identical to develop's; the later commits change the HIP lowering only in the refusal's text. - Byte identity GREEN at llvm20, llvm22, llvm23 and llvm24. - Golden checks with both engines at all four flavors: no blessed config changed. The report also lists the Python-only `barrier_fence` family as absent from the both-engine run, and configs not yet in the golden file. No golden file changed. - ctest: 45 run, all pass except `rocke_arch_domain_reproducibility`, which skips; this includes `rocke_future_intrinsic_lowering`. - The two new test files: 107 cases with both engines in strict mode; without the binding, 55 Python cases pass and the 52 C++ cases skip. - The 35 test files that use `rocke/tests/engines.py`, with both engines in strict mode: 5266 passed, 134 skipped. - Platform suite (`tests` and `python/rocke/tests`) with both engines in strict mode and no GPU visible: 11255 passed, 14 failed. All 14 also fail on develop: - `test_the_cpp_fallback_does_not_warn_twice` stubs the engine and fails only under `ROCKE_CPP_STRICT=1`; - four `test_installed_ctest_entries_get_scoped_environment_contracts` cases fail the same way on develop; - the nine interleaved-GEMM demo tests need a GPU. - Library golden tests: 93 passed. - pre-commit passes. ## Submission Checklist - [x] Look over the contributing guidelines at https://github.com/ROCm/TheRock/blob/main/GOVERNANCE.md#pull-requests. ISSUE ID : AICK-2900 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude <noreply@anthropic.com>
TheRock Submodule Bump ActivityNewest first
|

Motivation
buffer_rsrc(ptr, num_bytes)lowers to@llvm.amdgcn.make.buffer.rsrc. Two operand forms reachedthe LLVM lowering of both engines unchecked, and the module they produced was then rejected by
llcwith an error that did not point at the op:
addr_space="constant": it isptr addrspace(4)in the kernelheader, but the call names its pointer
ptr addrspace(1)(LLVM 20llc:'%X' defined with type 'ptr addrspace(4)' but expected 'ptr addrspace(1)');num_bytesat llvm20: that flavor's intrinsic takes an i32num_records, and the loweringprinted any operand as
i32(LLVM 20llc:'%n' defined with type 'i64' but expected 'i32').The HIP lowering has the same kind of bug for the byte count: it calls
__builtin_amdgcn_make_buffer_rsrcwithnum_bytescast to(int), so an i64 byte count wassilently truncated to 32 bits (hipcc emits
trunc i64 %n to i32before the call), and thedescriptor bounded a smaller range than asked. ROCm 7.1's builtin takes an
intnum_recordsand later clang a 64-bit one (
int64_tin LLVM 22 and 23,uint64_tafter); the truncation comes fromthe cast the lowering emits.
The constant-space mismatch was not specific to
buffer_rsrc. The global loads, stores, atomics,flag ops, cooperative store and global/LDS copies also named a constant-space parameter
ptr addrspace(1), and LLVM rejected the module.This PR refuses these forms up front, in both engines, with a message that says what is wrong, and
lets the global loads read through a constant-space parameter.
Technical Details
Both checks need the lowering's context (the parameter's header type, the LLVM flavor), so they
sit in the LLVM lowering of each engine, at the same point: Python
_op_tile_buffer_rsrc(
core/lower_llvm.py), C++op_tile_buffer_rsrc(cpp/core/lower_llvm/mem.cpp). Theglobal-pointer ops (
global_ptr_add,global_ptr_offset,global_ptr_to_i64) already refuse aconstant-space parameter there, and
buffer_rsrcnow uses the same helper(
_require_global_header_ptr/rocke_ll_require_global_header_ptr) and so the same text:At llvm20 a
num_bytesthat is not i32 is refused:llvm22 and later still take an i32 (zero-extended) or an i64, unchanged.
The HIP lowering of both engines (Python
_op_tile_buffer_rsrcincore/lower_hip.py, C++_op_tile_buffer_rsrcincpp/core/lower_hip/lower_hip_mem.cpp) refuses anum_bytesthat is noti32, at every LLVM version, because it passes
num_recordscast to(int):An i64 byte count still lowers through LLVM at llvm22 and later.
The HIP lowering keeps a constant-space pointer: its kernel signature declares every pointer
parameter the same way (
float* __restrict__ X) whatever itsaddr_space, and the builtin takes avoid*. A hipcc probe of that source compiles, and the descriptor is built from the kernelargument's address.
Other global-memory ops on a constant-space parameter, in the LLVM lowering of both engines:
global_load_f16,global_loadandglobal_load_vNname the pointer's own type (a table ofthe accepted spaces,
_GLOBAL_LOAD_PTR_TYPES/ROCKE_LL_GLOBAL_LOAD_PTR_TYPES, resolved bythe existing pointer-space resolver). They read a constant-space parameter as
load addrspace(4)and refuse a flat or LDS pointer, which they also used to nameptr addrspace(1). The resolver's message now says "op" rather than "intrinsic".cooperative_global_store,global_load_ldsandglobal_load_async_to_ldsrefuse a constant-space parameter with theglobal_ptr_*text.global_prefetch,flat_prefetch,global_store_async_from_lds,global_load_tr16_b128and both cluster loads) calls
_require_header_ptr/rocke_ll_require_header_ptr, whoseglobal-pointer form is
_require_global_header_ptr/rocke_ll_require_global_header_ptr.The C++
global_store_async_from_ldsandglobal_load_tr16_b128lowerings used to check onlythe IR type; they now check the header type, as the Python engine already did.
TypeErrorin Python andROCKE_ERR_TYPEin C++. The text names the op's builder (store_f16,global_store,global_load_f16,global_load) and the builder's name for the operand (src_ptrfor thecopies into LDS), and says "(its parameter's addr_space)" only when the parameter's override
moved its header type. The
buffer_rsrcbyte-count refusals also name the builder.The portable IR route lowers through the C++ engine, so it refuses the LLVM forms too.
No emission changes for a kernel whose IR LLVM accepted before: byte identity is unchanged, no
golden is re-blessed, and the HIP source of every parity kernel is unchanged.
dsl_docs/reference/op_vocabulary.mdstates the rules next to the buffer ops.Test Plan
tests/core/test_buffer_rsrc_operands.py:i64
num_bytesat llvm20, with the exact text;num_bytesat every flavor and an i64 one at llvm22 and later lower toidentical IR in both engines;
num_byteswith the exact text, and lower an i32num_bytesover a global or a constant-space pointer to the same source.
tests/core/test_constant_space_global_ops.py: each LLVM lowering reads through aconstant-space parameter with each global load at every flavor, the result compiles with the
host clang, and a flat or LDS pointer is refused; every other op listed above refuses a
constant-space parameter with the exact text and type, an LDS parameter is refused without the
addr_space clause, and
flat_prefetchrefuses a parameter moved to constant space.rocke/tests/engines.pygains per-engine helpers thatalso check the C++ status), so the Python cases run in lanes that do not build the
rocke_enginebinding; a C++ case there skips before either engine runs. Develop'savailable_engines()returns the sameENGINESlist, or the Python engine alone when thebinding is not built.
tests/core/future_intrinsic_lowering.cpp(ctestrocke_future_intrinsic_lowering): the C++LLVM and HIP lowerings refuse the
buffer_rsrcforms, with their status codes, and still lowerthe accepted ones; a
constant_space_global_opscase checks a sample of the constant-spaceloads and refusals, so the C++ side also runs in those lanes.
after the change.
against a freshly built shared engine, the touched tests with both engines in strict mode, and
the platform suite compared by failure name against develop.
Test Result
buffer_rsrcLLVM forms lowered without error and LLVM 20llcrejected the result with the errors above; the HIP lowering of an i64num_bytescompiled,and hipcc truncated the byte count to 32 bits. A global load through a constant-space parameter
produced a module the host clang rejects.
parity families are identical to develop's; the later commits change the HIP lowering only in the
refusal's text.
lists the Python-only
barrier_fencefamily as absent from the both-engine run, and configs notyet in the golden file. No golden file changed.
rocke_arch_domain_reproducibility, which skips; this includesrocke_future_intrinsic_lowering.Python cases pass and the 52 C++ cases skip.
rocke/tests/engines.py, with both engines in strict mode: 5266passed, 134 skipped.
testsandpython/rocke/tests) with both engines in strict mode and no GPUvisible: 11255 passed, 14 failed. All 14 also fail on develop:
test_the_cpp_fallback_does_not_warn_twicestubs the engine and fails only underROCKE_CPP_STRICT=1;test_installed_ctest_entries_get_scoped_environment_contractscases fail the same wayon develop;
Submission Checklist
https://github.com/ROCm/TheRock/blob/main/GOVERNANCE.md#pull-requests.
ISSUE ID : AICK-2900
🤖 Generated with Claude Code