exp2(0) needs to be exactly 1, if exp2(src) overflows then it has to be equal to infinity and exp2(nan) has to be equal to a nan. The patches fixes all three cases.
Signed-off-by: Zack Rusin <za...@vmware.com> --- src/gallium/auxiliary/gallivm/lp_bld_arit.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index 7beb117..467cbc6 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -3004,7 +3004,7 @@ lp_build_polynomial(struct lp_build_context *bld, */ const double lp_build_exp2_polynomial[] = { #if EXP_POLY_DEGREE == 5 - 0.999999925063526176901, + 1.000000000000000000000, 0.693153073200168932794, 0.240153617044375388211, 0.0558263180532956664775, @@ -3046,6 +3046,8 @@ lp_build_exp2_approx(struct lp_build_context *bld, LLVMValueRef expipart = NULL; LLVMValueRef expfpart = NULL; LLVMValueRef res = NULL; + LLVMValueRef infmask = bld->zero; + LLVMValueRef nanmask = bld->zero; assert(lp_check_value(bld->type, x)); @@ -3059,6 +3061,10 @@ lp_build_exp2_approx(struct lp_build_context *bld, assert(type.floating && type.width == 32); + /* We need ot handle both inf and nan inputs */ + infmask = lp_build_cmp(bld, PIPE_FUNC_GREATER, x, + lp_build_const_vec(bld->gallivm, type, 129.0)); + nanmask = LLVMBuildFCmp(bld->gallivm->builder, LLVMRealOEQ, x, x, ""); x = lp_build_min(bld, x, lp_build_const_vec(bld->gallivm, type, 129.0)); x = lp_build_max(bld, x, lp_build_const_vec(bld->gallivm, type, -126.99999)); @@ -3081,6 +3087,14 @@ lp_build_exp2_approx(struct lp_build_context *bld, Elements(lp_build_exp2_polynomial)); res = LLVMBuildFMul(builder, expipart, expfpart, ""); + /* If the input would overflow make sure return is correctly an inf */ + res = lp_build_select(bld, infmask, + lp_build_const_vec(bld->gallivm, type, INFINITY), + res); + /* If the input was a nan make sure the return is also a nan */ + res = LLVMBuildSelect(bld->gallivm->builder, nanmask, res, + lp_build_const_vec(bld->gallivm, type, NAN), + ""); } if(p_exp2_int_part) -- 1.7.10.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev