[Mesa-dev] [PATCH] glsl: ensure that frexp returns a 0 exponent for zero values
Matt Turner
mattst88 at gmail.com
Fri Jul 18 14:27:52 PDT 2014
On Fri, Jul 18, 2014 at 9:19 AM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> The current code appears to work in simple tests, however this will
> guarantee that the returned exponent is 0 for a 0 value.
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>
> I couldn't make a simple test-case that would cause the current logic to
> fail. However when I did the same thing with doubles, I ran into trouble. It
> seems safer to move the csel outside of the add in case the value actually has
> a non-0 exponent despite a 0 significand.
>
> src/glsl/builtin_functions.cpp | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
> index e01742c..5755de9 100644
> --- a/src/glsl/builtin_functions.cpp
> +++ b/src/glsl/builtin_functions.cpp
> @@ -4229,8 +4229,8 @@ builtin_builder::_frexp(const glsl_type *x_type, const glsl_type *exp_type)
> * to unsigned integers to ensure that 1 bits aren't shifted in.
> */
> body.emit(assign(exponent, rshift(bitcast_f2i(abs(x)), exponent_shift)));
> - body.emit(assign(exponent, add(exponent, csel(is_not_zero, exponent_bias,
> - imm(0, vec_elem)))));
> + body.emit(assign(exponent, csel(is_not_zero, add(exponent, exponent_bias),
> + imm(0, vec_elem))));
So you're changing the logic from
exponent = (f2i(abs(x) >> 23) + (x != 0.0f) ? -126 : 0;
to
exponent = (x != 0.0f) ? (f2i(abs(x) >> 23) - 126 : 0;
These seem identical to me, and trivially so for 0.0f/-0.0f. I have a
feeling that this patch is papering over a bug in your code generation
for f2i(abs(x)).
In commit 9c48ae75 I fixed a bug in i965 where instead of generating
f2i(abs(x)) we'd apply the source modifier effectively after the
bitcast (reading the register with a different type), so we'd get
abs(f2i(x)).
For 0.0f, applying the f2i and abs out of order doesn't affect the
result, but for -0.0f (0x80000000, -2147483648) instead of getting 0,
you'd get abs(-2147483648) (which is likely -2147483648 itself!).
I don't have any idea about why this might occur for you with doubles
but not floats, but you should have something to look into now.
More information about the mesa-dev
mailing list