Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C++ (Circle)
CIRCT
Clean
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
GLSL
Go
Haskell
HLSL
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Nim
Objective-C
Objective-C++
OCaml
OpenCL C
Pascal
Pony
Python
Racket
Ruby
Rust
Snowball
Scala
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
TypeScript Native
V
Vala
Visual Basic
WASM
Zig
Javascript
GIMPLE
Ygen
hlsl source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
Clang (trunk)
DXC (trunk)
DXC 1.6.2112
DXC 1.7.2207
DXC 1.7.2212
DXC 1.7.2308
DXC 1.8.2306-preview
DXC 1.8.2403
DXC 1.8.2403.1
DXC 1.8.2403.2
DXC 1.8.2405
DXC 1.8.2407
RGA 2.6.1 (DXC 1.6.2112)
RGA 2.6.1 (DXC 1.7.2207)
RGA 2.6.2 (DXC 1.6.2112)
RGA 2.6.2 (DXC 1.7.2207)
RGA 2.6.2 (DXC trunk)
RGA 2.9.0 (DXC trunk)
Options
Source code
groupshared uint lds_min; groupshared uint lds_max; [numthreads(64, 1, 1)] void main(uint group_index : SV_GroupIndex) { if (group_index == 0) { lds_min = 0xffffffffu; lds_max = 0; } // Suppose we want to compute the min and max values of fvalue across // all invocations in the group. float fvalue; // Perform a bitwise cast of the float value to an unsigned value. uint uvalue = asuint(fvalue); if ((uvalue >> 31) == 0) { // The sign bit wasn't set, so set it temporarily. uvalue = uvalue | (1 << 31); } else { // In the case where we started with a negative value, take // the ones complement. uvalue = ~uvalue; } // This barrier ensures that invocation with group index 0 has // run and initialized our LDS values. GroupMemoryBarrierWithGroupSync(); uint original_min; InterlockedMin(lds_min, uvalue, original_min); uint original_max; InterlockedMax(lds_max, uvalue, original_max); // Ensure interlocked operations have finished across all invocations // in the group. // Reminder that interlocked operations do not imply a memory or // execution barrier! GroupMemoryBarrierWithGroupSync(); if (group_index == 0) { float group_min; float group_max; if ((lds_min >> 31) == 0) { // The MSB is unset, so take the complement, then bitcast, // turning this back into a negative floating point value. group_min = asfloat(~lds_min); } else { // The MSB is set, so we started with a positive float. // Unset the MSB and bitcast. group_min = asfloat(lds_min & ~(1u << 31)); } // Do the same conversion operation for the max value. if ((lds_max >> 31) == 0) { group_max = asfloat(~lds_max); } else { group_max = asfloat(lds_max & ~(1u << 31)); } // Now, group_min and group_max refer to the min and max // floating point values of `fvalue` across the group. } }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
About the author
Statistics
Changelog
Version tree