[llvm-branch-commits] [clang] [HLSL] Add missing Shader Model 6.0 availability for wave intrinsics (PR #189445)
Deric C. via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Mar 30 11:59:31 PDT 2026
https://github.com/Icohedron updated https://github.com/llvm/llvm-project/pull/189445
>From 540508f0dcd79212f5ec09c6582dc7803abc98de Mon Sep 17 00:00:00 2001
From: Deric Cheung <cheung.deric at gmail.com>
Date: Mon, 30 Mar 2026 10:29:19 -0700
Subject: [PATCH 1/3] Fix 16-bit Shader Model availability for Wave intrinsics
This commit fixes 16-bit Shader Model availability for HLSL wave
intrinsics. Wave intrinsics require Shader Model 6.0, but many Wave
intrinsics were missing the annotation specifying it.
Furthermore, there wasn't an easy way to specify Shader Model 6.0
availability while maintaining the requirement for Shader Model 6.2 when
16-bit types is enabled and the overload uses half types. To fix the
issue, this commit extends _HLSL_16BIT_AVAILABILITY to accept a 3rd
optional argument that specifies the Shader Model availability when
16-bit types is disabled.
Assisted-by: GitHub Copilot
---
clang/include/clang/Basic/HLSLIntrinsics.td | 8 ++++
.../lib/Headers/hlsl/hlsl_alias_intrinsics.h | 5 ++-
clang/utils/TableGen/HLSLEmitter.cpp | 40 +++++--------------
3 files changed, 22 insertions(+), 31 deletions(-)
diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td
index 7d148b18198fc..27348706c25e6 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -1574,6 +1574,7 @@ def hlsl_wave_active_all_equal_16bit :
let ReturnType = VaryingShape<BoolTy>;
let VaryingTypes = [HalfTy, Int16Ty, UInt16Ty];
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1698,6 +1699,7 @@ def hlsl_wave_active_max :
}];
let VaryingTypes = AllNumericTypes;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1710,6 +1712,7 @@ def hlsl_wave_active_min :
}];
let VaryingTypes = AllNumericTypes;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1723,6 +1726,7 @@ def hlsl_wave_active_product :
}];
let VaryingTypes = AllNumericTypes;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1735,6 +1739,7 @@ def hlsl_wave_active_sum :
}];
let VaryingTypes = AllNumericTypes;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1797,6 +1802,7 @@ def hlsl_wave_prefix_product :
}];
let VaryingTypes = AllNumericTypes;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1809,6 +1815,7 @@ def hlsl_wave_prefix_sum :
}];
let VaryingTypes = AllNumericTypes;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
@@ -1824,5 +1831,6 @@ the specified wave.
let Args = [Varying, UIntTy];
let VaryingTypes = AllTypesWithBool;
let IsConvergent = 1;
+ let Availability = SM6_0;
let VaryingMatDims = [];
}
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index b2480b30f4a26..3ee56b597da30 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -25,7 +25,7 @@ namespace hlsl {
availability(platform, introduced = version, environment = stage)))
#ifdef __HLSL_ENABLE_16_BIT
-#define _HLSL_16BIT_AVAILABILITY(platform, version) \
+#define _HLSL_16BIT_AVAILABILITY(platform, version, ...) \
__attribute__((availability(platform, introduced = version)))
#define _HLSL_16BIT_AVAILABILITY_STAGE(platform, version, stage) \
__attribute__(( \
@@ -33,7 +33,8 @@ namespace hlsl {
#define _HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT() \
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
#else
-#define _HLSL_16BIT_AVAILABILITY(environment, version)
+#define _HLSL_16BIT_AVAILABILITY(platform, version, ...) \
+ __VA_OPT__(_HLSL_AVAILABILITY(platform, __VA_ARGS__))
#define _HLSL_16BIT_AVAILABILITY_STAGE(environment, version, stage)
#define _HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
#endif
diff --git a/clang/utils/TableGen/HLSLEmitter.cpp b/clang/utils/TableGen/HLSLEmitter.cpp
index d115c35af5f6d..ce77c84d0ffcc 100644
--- a/clang/utils/TableGen/HLSLEmitter.cpp
+++ b/clang/utils/TableGen/HLSLEmitter.cpp
@@ -145,9 +145,12 @@ struct TypeInfo {
static void emitAvailability(raw_ostream &OS, StringRef Version,
bool Use16Bit = false) {
- if (Use16Bit)
- OS << "_HLSL_16BIT_AVAILABILITY(shadermodel, " << Version << ")\n";
- else
+ if (Use16Bit) {
+ OS << "_HLSL_16BIT_AVAILABILITY(shadermodel, " << SM6_2;
+ if (!Version.empty())
+ OS << ", " << Version;
+ OS << ")\n";
+ } else
OS << "_HLSL_AVAILABILITY(shadermodel, " << Version << ")\n";
}
@@ -397,32 +400,11 @@ static void buildWorklist(const Record *R,
if (AvailabilityIsAtLeastSM6_2) {
Item.Availability = Availability;
} else {
- Item.Availability = SM6_2;
Item.Use16BitAvail = IsCond16Bit;
-
- // Note: If Availability = x where x < 6.2 and a half type is used,
- // neither _HLSL_AVAILABILITY(shadermodel, x) nor
- // _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) are correct:
- //
- // _HLSL_AVAILABILITY(shadermodel, x) will set the availbility for the
- // half overload to x even when 16-bit types are enabled, but x < 6.2
- // and 6.2 is required for 16-bit half.
- //
- // _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) will set the
- // availability for the half overload to 6.2 when 16-bit types are
- // enabled, but there will be no availability set when 16-bit types
- // are not enabled.
- //
- // A possible solution to this is to make _HLSL_16BIT_AVAILABILITY
- // accept 3 args: (shadermodel, X, Y) where X is the availability for
- // the 16-bit half type overload (which will typically be 6.2), and Y is
- // the availability for the non-16-bit half overload. However, this
- // situation does not currently arise, so we just assert below that this
- // case will never occur.
- assert(
- !(IsCond16Bit && !Availability.empty()) &&
- "Can not handle availability for an intrinsic using half types and"
- " which has an explicit shader model requirement older than 6.2");
+ if (IsCond16Bit)
+ Item.Availability = Availability;
+ else
+ Item.Availability = SM6_2;
}
} else {
Item.Availability = Availability;
@@ -486,7 +468,7 @@ static void emitWorklistOverloads(raw_ostream &OS, const OverloadContext &Ctx,
}
auto EmitAvail = [&]() {
- if (!Item.Availability.empty())
+ if (!Item.Availability.empty() || Item.Use16BitAvail)
emitAvailability(OS, Item.Availability, Item.Use16BitAvail);
};
>From 739a39851980e26cea8627a574828201250ca70b Mon Sep 17 00:00:00 2001
From: Deric Cheung <cheung.deric at gmail.com>
Date: Mon, 30 Mar 2026 11:49:09 -0700
Subject: [PATCH 2/3] Add tests to ensure the 6.0 availability is enforced
---
.../SemaHLSL/WaveBuiltinAvailability.hlsl | 34 +++++++++++++++++--
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl b/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl
index 9c136ae497424..88cfd6056ef32 100644
--- a/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl
+++ b/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl
@@ -1,10 +1,38 @@
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel5.0-library -verify %s
-// WaveActiveCountBits is unavailable before ShaderModel 6.0.
+// Wave intrinsics are unavailable before ShaderModel 6.0.
[shader("compute")]
[numthreads(8,8,1)]
void foo() {
- // expected-error@#site {{'WaveActiveCountBits' is only available on Shader Model 6.0 or newer}}
+ // expected-error@#WaveActiveCountBits {{'WaveActiveCountBits' is only available on Shader Model 6.0 or newer}}
// expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveActiveCountBits' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
- unsigned tmp = hlsl::WaveActiveCountBits(1); // #site
+ unsigned tmp = hlsl::WaveActiveCountBits(1); // #WaveActiveCountBits
+
+ // expected-error@#WaveActiveMax {{'WaveActiveMax' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveActiveMax' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float a = hlsl::WaveActiveMax(1.0f); // #WaveActiveMax
+
+ // expected-error@#WaveActiveMin {{'WaveActiveMin' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveActiveMin' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float b = hlsl::WaveActiveMin(1.0f); // #WaveActiveMin
+
+ // expected-error@#WaveActiveProduct {{'WaveActiveProduct' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveActiveProduct' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float c = hlsl::WaveActiveProduct(1.0f); // #WaveActiveProduct
+
+ // expected-error@#WaveActiveSum {{'WaveActiveSum' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveActiveSum' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float d = hlsl::WaveActiveSum(1.0f); // #WaveActiveSum
+
+ // expected-error@#WavePrefixProduct {{'WavePrefixProduct' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WavePrefixProduct' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float e = hlsl::WavePrefixProduct(1.0f); // #WavePrefixProduct
+
+ // expected-error@#WavePrefixSum {{'WavePrefixSum' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WavePrefixSum' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float f = hlsl::WavePrefixSum(1.0f); // #WavePrefixSum
+
+ // expected-error@#WaveReadLaneAt {{'WaveReadLaneAt' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveReadLaneAt' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ float g = hlsl::WaveReadLaneAt(1.0f, 0u); // #WaveReadLaneAt
}
>From 5b0c1d9fd6d0983afcdd5b9e48d1e4738c0cfdb0 Mon Sep 17 00:00:00 2001
From: Deric Cheung <cheung.deric at gmail.com>
Date: Mon, 30 Mar 2026 11:56:37 -0700
Subject: [PATCH 3/3] Exercise half type overloads in the
WaveBuiltinAvailability test
---
clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl b/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl
index 88cfd6056ef32..5741b81832ad0 100644
--- a/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl
+++ b/clang/test/SemaHLSL/WaveBuiltinAvailability.hlsl
@@ -35,4 +35,15 @@ void foo() {
// expected-error@#WaveReadLaneAt {{'WaveReadLaneAt' is only available on Shader Model 6.0 or newer}}
// expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveReadLaneAt' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
float g = hlsl::WaveReadLaneAt(1.0f, 0u); // #WaveReadLaneAt
+
+ // Test that half overloads (which map to float without native half) also
+ // have the correct SM 6.0 availability via the _HLSL_16BIT_AVAILABILITY
+ // fallback path.
+ // expected-error@#WaveActiveMax_half {{'WaveActiveMax' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveActiveMax' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ half h = hlsl::WaveActiveMax((half)1.0); // #WaveActiveMax_half
+
+ // expected-error@#WaveReadLaneAt_half {{'WaveReadLaneAt' is only available on Shader Model 6.0 or newer}}
+ // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{'WaveReadLaneAt' has been marked as being introduced in Shader Model 6.0 here, but the deployment target is Shader Model 5.0}}
+ half i = hlsl::WaveReadLaneAt((half)1.0, 0u); // #WaveReadLaneAt_half
}
More information about the llvm-branch-commits
mailing list