ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | LICENSE

Commit: a621f332d809b2d77f327c4ae7bfb6e28c2e74b2
Parent: df3f879fbdd93cb79673b3031d13ceda1552aba1
Author: Randy Palamar
Date:   Mon, 17 Feb 2025 05:19:47 -0700

intrinsics: avoid UB when using CLZ/CTZ

Despite using the compiler builtins and the underlying assembly
instruction not caring if the value is 0 it is still undefined
behaviour in C to call these functions with an argument of 0.

Add a little check to workaround this which will be optimized out
and any optimization level other that 0. See: https://godbolt.org/z/aoGx7PP5K

Diffstat:
Mintrinsics.c | 18++++++++++++++++--
Mutil.h | 4++--
2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/intrinsics.c b/intrinsics.c @@ -1,11 +1,25 @@ #define FORCE_INLINE inline __attribute__((always_inline)) /* TODO(rnp): msvc probably won't build this but there are other things preventing that as well */ -#define clz_u32(a) __builtin_clz(a) -#define ctz_u32(a) __builtin_ctz(a) #define sqrt_f32(a) __builtin_sqrtf(a) #define atan2_f32(y, x) __builtin_atan2f(y, x) +static FORCE_INLINE u32 +clz_u32(u32 a) +{ + u32 result = 32; + if (a) result = __builtin_clz(a); + return result; +} + +static FORCE_INLINE u32 +ctz_u32(u32 a) +{ + u32 result = 32; + if (a) result = __builtin_ctz(a); + return result; +} + #ifdef __ARM_ARCH_ISA_A64 /* TODO? debuggers just loop here forever and need a manual PC increment (step over) */ #define debugbreak() asm volatile ("brk 0xf000") diff --git a/util.h b/util.h @@ -21,8 +21,6 @@ #endif #endif -#include "intrinsics.c" - #ifdef _DEBUG #ifdef _WIN32 #define DEBUG_EXPORT __declspec(dllexport) @@ -70,6 +68,8 @@ typedef ptrdiff_t size; typedef ptrdiff_t iptr; typedef size_t uptr; +#include "intrinsics.c" + typedef struct { u8 *beg, *end; } Arena; typedef struct { Arena *arena; u8 *old_beg; } TempArena;