From d43694188946faf89c843e4f99b9201105f177f5 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 11 Aug 2025 20:04:15 -0500 Subject: [PATCH 1/3] [SPIRV] Preserve NaN, Inf, and signed zeros w/ -Gis The `-Gis` flag opts into "strict" IEEE math rules, which include preserving NaN, Inf and signed/unsigned zeros. This change adds the SPIRV SignedZeroInfNanPreserve capability and execution mode when `-Gis` is passed to DXC. ../tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl --- tools/clang/lib/SPIRV/SpirvEmitter.cpp | 12 ++++++++++++ .../test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl | 11 +++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 5019fe3926..c69ebdb42f 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -862,6 +862,18 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) { SourceLocation()); } + // For Vulkan 1.2 and later, add SignedZeroInfNanPreserve when -Gis is + // provided to preserve NaN/Inf and signed zeros. + if (spirvOptions.IEEEStrict && + featureManager.getSpirvVersion(featureManager.getTargetEnv()) >= + VersionTuple(1, 2)) { + spvBuilder.addExecutionMode(entryFunction, + spv::ExecutionMode::SignedZeroInfNanPreserve, + {32}, SourceLocation()); + spvBuilder.requireCapability(spv::Capability::SignedZeroInfNanPreserve, + SourceLocation()); + } + llvm::StringRef denormMode = spirvOptions.floatDenormalMode; if (!denormMode.empty()) { if (denormMode.equals_lower("preserve")) { diff --git a/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl b/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl new file mode 100644 index 0000000000..a3bf0c834d --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl @@ -0,0 +1,11 @@ +// RUN: %dxc -T cs_6_0 -spirv -Gis %s| FileCheck %s --check-prefixes=CHECK,OLD +// RUN: %dxc -T cs_6_0 -spirv -Gis -fspv-target-env=vulkan1.2 %s| FileCheck %s --check-prefixes=CHECK,NEW + +// OLD-NOT: OpCapability SignedZeroInfNanPreserve +// NEW: OpCapability SignedZeroInfNanPreserve +// CHECK: OpEntryPoint +// OLD-NOT: OpExecutionMode %main SignedZeroInfNanPreserve 32 +// NEW: OpExecutionMode %main SignedZeroInfNanPreserve 32 + +[numthreads(8,1,1)] +void main() {} From b0d2e8b565b90f4a7d0499c8dd6a0319a7517785 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Wed, 13 Aug 2025 09:15:27 -0500 Subject: [PATCH 2/3] Update based on feedback from @keenuts ../tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl --- tools/clang/lib/SPIRV/SpirvEmitter.cpp | 7 ++++--- .../test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl | 11 +++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index c69ebdb42f..f231625001 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -864,9 +864,10 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) { // For Vulkan 1.2 and later, add SignedZeroInfNanPreserve when -Gis is // provided to preserve NaN/Inf and signed zeros. - if (spirvOptions.IEEEStrict && - featureManager.getSpirvVersion(featureManager.getTargetEnv()) >= - VersionTuple(1, 2)) { + if (spirvOptions.IEEEStrict) { + if (featureManager.getSpirvVersion(featureManager.getTargetEnv()) < + VersionTuple(1, 2)) + spvBuilder.requireExtension("SPV_KHR_float_controls", SourceLocation()); spvBuilder.addExecutionMode(entryFunction, spv::ExecutionMode::SignedZeroInfNanPreserve, {32}, SourceLocation()); diff --git a/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl b/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl index a3bf0c834d..0da7cf3c26 100644 --- a/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl +++ b/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl @@ -1,11 +1,10 @@ -// RUN: %dxc -T cs_6_0 -spirv -Gis %s| FileCheck %s --check-prefixes=CHECK,OLD -// RUN: %dxc -T cs_6_0 -spirv -Gis -fspv-target-env=vulkan1.2 %s| FileCheck %s --check-prefixes=CHECK,NEW +// RUN: %dxc -T cs_6_0 -spirv -Gis %s| FileCheck %s --check-prefixes=CHECK,PRE_1_3 +// RUN: %dxc -T cs_6_0 -spirv -Gis -fspv-target-env=vulkan1.2 %s| FileCheck %s -// OLD-NOT: OpCapability SignedZeroInfNanPreserve -// NEW: OpCapability SignedZeroInfNanPreserve +// CHECK: OpCapability SignedZeroInfNanPreserve +// PRE_1_3: OpExtension "SPV_KHR_float_controls" // CHECK: OpEntryPoint -// OLD-NOT: OpExecutionMode %main SignedZeroInfNanPreserve 32 -// NEW: OpExecutionMode %main SignedZeroInfNanPreserve 32 +// CHECK: OpExecutionMode %main SignedZeroInfNanPreserve 32 [numthreads(8,1,1)] void main() {} From f33ccd3be16938f4f4e5e0daf54f29e97a66c523 Mon Sep 17 00:00:00 2001 From: Chris B Date: Wed, 13 Aug 2025 15:00:20 -0500 Subject: [PATCH 3/3] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nathan Gauër --- tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl b/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl index 0da7cf3c26..41ca4f7d63 100644 --- a/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl +++ b/tools/clang/test/CodeGenSPIRV/SignedZeroInfNanPreserve.hlsl @@ -1,8 +1,8 @@ -// RUN: %dxc -T cs_6_0 -spirv -Gis %s| FileCheck %s --check-prefixes=CHECK,PRE_1_3 +// RUN: %dxc -T cs_6_0 -spirv -Gis %s| FileCheck %s --check-prefixes=CHECK,PRE_1_2 // RUN: %dxc -T cs_6_0 -spirv -Gis -fspv-target-env=vulkan1.2 %s| FileCheck %s // CHECK: OpCapability SignedZeroInfNanPreserve -// PRE_1_3: OpExtension "SPV_KHR_float_controls" +// PRE_1_2: OpExtension "SPV_KHR_float_controls" // CHECK: OpEntryPoint // CHECK: OpExecutionMode %main SignedZeroInfNanPreserve 32