From e8797496bf7caeb08b5334d13d0d5aa039106210 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 28 Jul 2025 22:35:14 -0700 Subject: Fix CUDA backend missing U32_firstbitlow implementation (#7921) * Initial plan * Add U32_firstbitlow implementation for CUDA and CPP backends Co-authored-by: bmillsNV <163073245+bmillsNV@users.noreply.github.com> * Add I32_firstbitlow and comprehensive testing for signed/unsigned firstbitlow Co-authored-by: bmillsNV <163073245+bmillsNV@users.noreply.github.com> * Convert firstbitlow test to use inline filecheck syntax Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> * Add U32_firstbithigh and I32_firstbithigh implementations for CUDA and CPP backends Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Update prelude/slang-cpp-scalar-intrinsics.h * Update prelude/slang-cpp-scalar-intrinsics.h * Update prelude/slang-cpp-scalar-intrinsics.h * Refactor Metal bit intrinsics to handle zero case correctly Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> * Update slang-cuda-prelude.h remove fake links * Update hlsl.meta.slang * if -1, return -1 due to implicit hlsl rule * -1 or 0 is ~0u as per hlsl implictly * 0 or -1 as per hlsl * fix the math to map to hlsl * fix compile error * forgot `31 - clz` * format code (#7943) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * Update source/slang/hlsl.meta.slang * Update source/slang/hlsl.meta.slang * Update source/slang/hlsl.meta.slang * Update source/slang/hlsl.meta.slang --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bmillsNV <163073245+bmillsNV@users.noreply.github.com> Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> Co-authored-by: ArielG-NV Co-authored-by: slangbot Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --- source/slang/hlsl.meta.slang | 59 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) (limited to 'source') diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 2ac886f61..66d1cb5e6 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -9539,6 +9539,39 @@ vector faceforward(vector n, vector i, vector ng) } } +// Helper functions for Metal target +internal int __metal_clz(int value) +{ + __target_switch + { + case metal: __intrinsic_asm "clz"; + } +} + +internal uint __metal_clz(uint value) +{ + __target_switch + { + case metal: __intrinsic_asm "clz"; + } +} + +internal int __metal_ctz(int value) +{ + __target_switch + { + case metal: __intrinsic_asm "ctz"; + } +} + +internal uint __metal_ctz(uint value) +{ + __target_switch + { + case metal: __intrinsic_asm "ctz"; + } +} + /// Find first set bit starting at high bit and working down. /// @param value The value to find set bits in. /// @return The bit index number of the most significant bit, @@ -9559,7 +9592,14 @@ int firstbithigh(int value) case cuda: __intrinsic_asm "$P_firstbithigh($0)"; case glsl: __intrinsic_asm "findMSB"; case hlsl: __intrinsic_asm "firstbithigh"; - case metal: __intrinsic_asm "clz"; + case metal: + { + if ((int)value < 0) + value = ~value; + if (value == 0) + return ~0u; + return 31 - __metal_clz(value); + } case spirv: return spirv_asm { OpExtInst $$int result glsl450 FindSMsb $value }; @@ -9576,7 +9616,6 @@ vector firstbithigh(vector value) { case glsl: __intrinsic_asm "findMSB"; case hlsl: __intrinsic_asm "firstbithigh"; - case metal: __intrinsic_asm "clz"; case spirv: return spirv_asm { OpExtInst $$vector result glsl450 FindSMsb $value }; @@ -9596,7 +9635,14 @@ uint firstbithigh(uint value) case cuda: __intrinsic_asm "$P_firstbithigh($0)"; case glsl: __intrinsic_asm "findMSB"; case hlsl: __intrinsic_asm "firstbithigh"; - case metal: __intrinsic_asm "clz"; + case metal: + { + if ((int)value < 0) + value = ~value; + if (value == 0) + return ~0u; + return 31 - __metal_clz(value); + } case spirv: return spirv_asm { OpExtInst $$uint result glsl450 FindUMsb $value }; @@ -9613,7 +9659,6 @@ vector firstbithigh(vector value) { case glsl: __intrinsic_asm "findMSB"; case hlsl: __intrinsic_asm "firstbithigh"; - case metal: __intrinsic_asm "clz"; case spirv: return spirv_asm { OpExtInst $$vector result glsl450 FindUMsb $value }; @@ -9639,7 +9684,7 @@ int firstbitlow(int value) case cuda: __intrinsic_asm "$P_firstbitlow($0)"; case glsl: __intrinsic_asm "findLSB"; case hlsl: __intrinsic_asm "firstbitlow"; - case metal: __intrinsic_asm "ctz"; + case metal: return (value==0) ? -1 : __metal_ctz(value); case spirv: return spirv_asm { OpExtInst $$int result glsl450 FindILsb $value }; @@ -9656,7 +9701,6 @@ vector firstbitlow(vector value) { case glsl: __intrinsic_asm "findLSB"; case hlsl: __intrinsic_asm "firstbitlow"; - case metal: __intrinsic_asm "ctz"; case spirv: return spirv_asm { OpExtInst $$vector result glsl450 FindILsb $value }; @@ -9676,7 +9720,7 @@ uint firstbitlow(uint value) case cuda: __intrinsic_asm "$P_firstbitlow($0)"; case glsl: __intrinsic_asm "findLSB"; case hlsl: __intrinsic_asm "firstbitlow"; - case metal: __intrinsic_asm "ctz"; + case metal: return (value==0) ? -1 : __metal_ctz(value); case spirv: return spirv_asm { OpExtInst $$uint result glsl450 FindILsb $value }; @@ -9693,7 +9737,6 @@ vector firstbitlow(vector value) { case glsl: __intrinsic_asm "findLSB"; case hlsl: __intrinsic_asm "firstbitlow"; - case metal: __intrinsic_asm "ctz"; case spirv: return spirv_asm { OpExtInst $$vector result glsl450 FindILsb $value }; -- cgit v1.2.3