Skip to content

Commit f7fe921

Browse files
Make ByteAddressBuffer alignment a constexpr compile-time contract
Mark the `alignment` parameter of `LoadAligned`/`Store` and the underlying `__byteAddressBufferLoad`/`__byteAddressBufferStore` intrinsics `constexpr`, so a non-compile-time-constant alignment is rejected by the language's built-in constexpr enforcement (diagnostic 40012) instead of a bespoke check. Front-end enforcement, so it is target-agnostic. Part of the #11545 ByteAddressBuffer alignment-contract decomposition (slice 1 of 4). Co-authored-by: Harsh Aggarwal <haaggarwal@nvidia.com>
1 parent 12f6779 commit f7fe921

2 files changed

Lines changed: 31 additions & 12 deletions

File tree

source/slang/hlsl.meta.slang

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -463,16 +463,16 @@ struct ByteAddressBuffer
463463

464464
/// Load a value with type `T` from the buffer at the specified location with a known alignment.
465465
///@param T The type of the value to load from the buffer.
466-
///@param location The input address in bytes, which must be a multiple of 4.
467-
///@param alignment The known alignment of `location`, which must be a multiple of 4 and compatible with `T`.
466+
///@param location The input address in bytes, which must be a multiple of `alignment`.
467+
///@param alignment The known alignment of `location` in bytes; a compile-time constant.
468468
///@return The value loaded from the buffer.
469469
///@remarks
470470
/// On HLSL, `alignment` is informational only and does not affect the emitted intrinsic.
471471
/// On other targets, `alignment` is forwarded to the lowered load instruction.
472472
[__readNone]
473473
[ForceInline]
474474
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer)]
475-
T LoadAligned<T>(uint location, uint alignment)
475+
T LoadAligned<T>(uint location, constexpr uint alignment)
476476
{
477477
return __byteAddressBufferLoad<T>(this, location, alignment);
478478
}
@@ -5894,23 +5894,23 @@ uint64_t __asuint64(uint2 i)
58945894

58955895
__intrinsic_op($(kIROp_ByteAddressBufferLoad))
58965896
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer)]
5897-
T __byteAddressBufferLoad<T>(ByteAddressBuffer buffer, uint offset, uint alignment);
5897+
T __byteAddressBufferLoad<T>(ByteAddressBuffer buffer, uint offset, constexpr uint alignment);
58985898

58995899
__intrinsic_op($(kIROp_ByteAddressBufferLoad))
59005900
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer_rw)]
5901-
T __byteAddressBufferLoad<T>(RWByteAddressBuffer buffer, uint offset, uint alignment);
5901+
T __byteAddressBufferLoad<T>(RWByteAddressBuffer buffer, uint offset, constexpr uint alignment);
59025902

59035903
__intrinsic_op($(kIROp_ByteAddressBufferLoad))
59045904
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer_rw)]
5905-
T __byteAddressBufferLoad<T>(RasterizerOrderedByteAddressBuffer buffer, uint offset, uint alignment);
5905+
T __byteAddressBufferLoad<T>(RasterizerOrderedByteAddressBuffer buffer, uint offset, constexpr uint alignment);
59065906

59075907
__intrinsic_op($(kIROp_ByteAddressBufferStore))
59085908
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer_rw)]
5909-
void __byteAddressBufferStore<T>(RWByteAddressBuffer buffer, uint offset, uint alignment, T value);
5909+
void __byteAddressBufferStore<T>(RWByteAddressBuffer buffer, uint offset, constexpr uint alignment, T value);
59105910

59115911
__intrinsic_op($(kIROp_ByteAddressBufferStore))
59125912
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer_rw)]
5913-
void __byteAddressBufferStore<T>(RasterizerOrderedByteAddressBuffer buffer, uint offset, uint alignment, T value);
5913+
void __byteAddressBufferStore<T>(RasterizerOrderedByteAddressBuffer buffer, uint offset, constexpr uint alignment, T value);
59145914

59155915
__intrinsic_op($(kIROp_GetUntypedBufferPtr))
59165916
[require(cpp_cuda, byteaddressbuffer)]
@@ -6442,16 +6442,16 @@ struct $(item.name)
64426442

64436443
/// Load a value with type `T` from the buffer at the specified location with a known alignment.
64446444
///@param T The type of the value to load from the buffer.
6445-
///@param location The input address in bytes, which must be a multiple of 4.
6446-
///@param alignment The known alignment of `location`, which must be a multiple of 4 and compatible with `T`.
6445+
///@param location The input address in bytes, which must be a multiple of `alignment`.
6446+
///@param alignment The known alignment of `location` in bytes; a compile-time constant.
64476447
///@return The value loaded from the buffer.
64486448
///@remarks
64496449
/// On HLSL, `alignment` is informational only and does not affect the emitted intrinsic.
64506450
/// On other targets, `alignment` is forwarded to the lowered load instruction.
64516451
[__NoSideEffect]
64526452
[ForceInline]
64536453
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm, byteaddressbuffer_rw)]
6454-
T LoadAligned<T>(uint location, uint alignment)
6454+
T LoadAligned<T>(uint location, constexpr uint alignment)
64556455
{
64566456
return __byteAddressBufferLoad<T>(this, location, alignment);
64576457
}
@@ -7142,7 +7142,7 @@ $}
71427142

71437143
[__unsafeForceInlineEarly]
71447144
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl_llvm)]
7145-
void Store<T>(uint address, T value, uint alignment)
7145+
void Store<T>(uint address, T value, constexpr uint alignment)
71467146
{
71477147
__byteAddressBufferStore(this, address, alignment, value);
71487148
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//DIAGNOSTIC_TEST:SIMPLE(diag=CHECK):
2+
3+
// Issue #11545: `ByteAddressBuffer`/`RWByteAddressBuffer` `LoadAligned`/`Store`
4+
// take a `constexpr` alignment, so a runtime (non-compile-time-constant)
5+
// alignment is rejected at compile time. This replaces the former custom
6+
// diagnostic with the language's built-in `constexpr` enforcement, and is a
7+
// front-end check, so it fires independent of the chosen target.
8+
9+
RWByteAddressBuffer buf;
10+
11+
[shader("compute")]
12+
[numthreads(1, 1, 1)]
13+
void computeMain(uint3 tid: SV_DispatchThreadID)
14+
{
15+
uint runtimeAlignment = tid.x;
16+
//CHECK: ^ expected a compile-time constant
17+
float v = buf.LoadAligned<float>(0, runtimeAlignment);
18+
buf.Store<float>(16, v, runtimeAlignment);
19+
}

0 commit comments

Comments
 (0)