================
@@ -44,8 +44,21 @@ _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_exp(__CLC_GENTYPE
x) {
const __CLC_GENTYPE ulim = 0x1.62e430p+6f;
// ln(smallest_normal) = -87.33654475055310898657
const __CLC_GENTYPE llim = -0x1.5d589ep+6f;
+ // ln(smallest_subnormal) = ln(2^-149) = -103.27892990343184
+ const __CLC_GENTYPE subnorm_llim = -0x1.9d1dap+6f;
- r = x < llim ? 0.0f : r;
+ // The integer scaling above (as_int(y) + (p << 23)) cannot represent
+ // subnormal results, so inputs in [subnorm_llim, llim) whose result is a
+ // subnormal are flushed to zero by the plain "x < llim ? 0" path below.
+ // When subnormals are supported, recompute those via __clc_ldexp so the
+ // subnormal result is preserved. Inputs below subnorm_llim (including -inf)
+ // genuinely underflow to zero and must not go through ldexp, whose exponent
+ // argument would be ill-formed for such extreme inputs.
+ r = x < llim ? (__CLC_GENTYPE)0.0f : r;
----------------
Lurie97 wrote:
Reworked to scale with __clc_ldexp directly, dropping the subnorm_llim /
__clc_fp32_subnormals_supported() fixup path (matches the ocml expF_base.h
flow). The exponent is clamped so extreme inputs don't feed ldexp an ill-formed
value; those still saturate to inf/zero via the existing ulim/llim selects.
Verified on i.MX95 Mali-G310 (FTZ device): OpenCL-CTS math_brute_force exp/exp2
pass 6/6.
https://github.com/llvm/llvm-project/pull/212696
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits