Skip to content

Commit daeba0c

Browse files
[SPIRV] Add SM6.6 IsHelperLane (microsoft#5488)
Fix microsoft#5427
1 parent 4b6e799 commit daeba0c

File tree

7 files changed

+72
-1
lines changed

7 files changed

+72
-1
lines changed

tools/clang/include/clang/SPIRV/FeatureManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class FeatureManager {
8989
std::string getKnownExtensions(const char *delimiter, const char *prefix = "",
9090
const char *postfix = "");
9191

92-
/// Rqeusts the given target environment for translating the given feature at
92+
/// Request the given target environment for translating the given feature at
9393
/// the given source location. Emits an error if the requested target
9494
/// environment does not match user's target environemnt.
9595
bool requestTargetEnv(spv_target_env, llvm::StringRef target, SourceLocation);

tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,6 +3312,7 @@ SpirvVariable *DeclResultIdMapper::getBuiltinVar(spv::BuiltIn builtIn,
33123312
spv::StorageClass sc = spv::StorageClass::Max;
33133313
// Valid builtins supported
33143314
switch (builtIn) {
3315+
case spv::BuiltIn::HelperInvocation:
33153316
case spv::BuiltIn::SubgroupSize:
33163317
case spv::BuiltIn::SubgroupLocalInvocationId:
33173318
needsLegalization = true;

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8504,6 +8504,9 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
85048504
retVal = spvBuilder.createLoad(retType, var, srcLoc, srcRange);
85058505
needsLegalization = true;
85068506
} break;
8507+
case hlsl::IntrinsicOp::IOP_IsHelperLane:
8508+
retVal = processIsHelperLane(callExpr, srcLoc, srcRange);
8509+
break;
85078510
case hlsl::IntrinsicOp::IOP_WaveIsFirstLane:
85088511
retVal = processWaveQuery(callExpr, spv::Op::OpGroupNonUniformElect);
85098512
break;
@@ -9161,6 +9164,32 @@ SpirvInstruction *SpirvEmitter::processWaveQuery(const CallExpr *callExpr,
91619164
opcode, retType, spv::Scope::Subgroup, callExpr->getExprLoc());
91629165
}
91639166

9167+
SpirvInstruction *SpirvEmitter::processIsHelperLane(const CallExpr *callExpr,
9168+
SourceLocation loc,
9169+
SourceRange range) {
9170+
assert(callExpr->getNumArgs() == 0);
9171+
9172+
if(!featureManager.isTargetEnvVulkan1p3OrAbove()) {
9173+
// If IsHelperlane is used for Vulkan 1.2 or less, we enable
9174+
// SPV_EXT_demote_to_helper_invocation extension to use
9175+
// OpIsHelperInvocationEXT instruction.
9176+
featureManager.allowExtension("SPV_EXT_demote_to_helper_invocation");
9177+
9178+
const QualType retType = callExpr->getCallReturnType(astContext);
9179+
return spvBuilder.createIsHelperInvocationEXT(retType, callExpr->getExprLoc());
9180+
}
9181+
9182+
// The SpreadVolatileSemanticsPass legalization pass will decorate the
9183+
// load with Volatile.
9184+
const QualType retType = callExpr->getCallReturnType(astContext);
9185+
auto *var =
9186+
declIdMapper.getBuiltinVar(spv::BuiltIn::HelperInvocation, retType, loc);
9187+
auto retVal = spvBuilder.createLoad(retType, var, loc, range);
9188+
needsLegalization = true;
9189+
9190+
return retVal;
9191+
}
9192+
91649193
SpirvInstruction *SpirvEmitter::processWaveVote(const CallExpr *callExpr,
91659194
spv::Op opcode) {
91669195
// Signatures:

tools/clang/lib/SPIRV/SpirvEmitter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,10 @@ class SpirvEmitter : public ASTConsumer {
590590
/// Processes SM6.0 wave query intrinsic calls.
591591
SpirvInstruction *processWaveQuery(const CallExpr *, spv::Op opcode);
592592

593+
/// Processes SM6.6 IsHelperLane intrisic calls.
594+
SpirvInstruction *processIsHelperLane(const CallExpr *, SourceLocation loc,
595+
SourceRange range);
596+
593597
/// Processes SM6.0 wave vote intrinsic calls.
594598
SpirvInstruction *processWaveVote(const CallExpr *, spv::Op opcode);
595599

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %dxc -T ps_6_0 -E main
2+
3+
// CHECK-NOT: OpDecorate {{%\w+}} BuiltIn HelperInvocation
4+
5+
float4 main() : SV_Target {
6+
float ret = 1.0;
7+
8+
if (IsHelperLane()) ret = 2.0;
9+
10+
return ret;
11+
}
12+
// CHECK: [[HelperInvocation:%\d+]] = OpIsHelperInvocationEXT %bool
13+
// CHECK: OpBranchConditional [[HelperInvocation]]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fspv-target-env=vulkan1.3
2+
3+
// CHECK: OpEntryPoint Fragment
4+
// CHECK-SAME: %gl_HelperInvocation
5+
6+
// CHECK: OpDecorate %gl_HelperInvocation BuiltIn HelperInvocation
7+
8+
// CHECK: %gl_HelperInvocation = OpVariable %_ptr_Input_bool Input
9+
10+
float4 main() : SV_Target {
11+
// CHECK: [[val:%\d+]] = OpLoad %bool %gl_HelperInvocation
12+
// CHECK: OpBranchConditional [[val]]
13+
float ret = 1.0;
14+
15+
if (IsHelperLane()) ret = 2.0;
16+
17+
return ret;
18+
}

tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,12 @@ TEST_F(FileTest, IntrinsicsSM66PackClampU8S8) {
14931493
TEST_F(FileTest, IntrinsicsSM66Unpack) {
14941494
runFileTest("intrinsics.sm6_6.unpack.hlsl");
14951495
}
1496+
TEST_F(FileTest, IntrinsicsSM66IsHelperLane) {
1497+
runFileTest("intrinsics.sm6_6.ishelperlane.hlsl");
1498+
}
1499+
TEST_F(FileTest, IntrinsicsSM66IsHelperLaneVk1p3) {
1500+
runFileTest("intrinsics.sm6_6.ishelperlane.vk1p3.hlsl");
1501+
}
14961502

14971503
// For attributes
14981504
TEST_F(FileTest, AttributeEarlyDepthStencil) {

0 commit comments

Comments
 (0)