[Mesa-dev] [PATCH 1/4] gallivm: fix unsigned divide and remainder opcodes

Roland Scheidegger sroland at vmware.com
Tue Apr 9 17:57:24 PDT 2013


Am 10.04.2013 02:22, schrieb Zack Rusin:
> We want to both make sure we never divide by zero to not generate
> sigfpe and that divide by zero is guaranteed to return 0xffffffff.
> Based on José idea.
> 
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c |   29 +++++++++++++++++---
>  1 file changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
> index f3ae7b6..f72fafd 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
> @@ -1543,8 +1543,19 @@ udiv_emit_cpu(
>     struct lp_build_tgsi_context * bld_base,
>     struct lp_build_emit_data * emit_data)
>  {
> -   emit_data->output[emit_data->chan] = lp_build_div(&bld_base->uint_bld,
> -                                   emit_data->args[0], emit_data->args[1]);
> +   
> +   LLVMBuilderRef builder = bld_base->base.gallivm->builder;
> +   LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint_bld,
> +                                        PIPE_FUNC_EQUAL, emit_data->args[1],
> +                                        bld_base->uint_bld.zero);
> +   LLVMValueRef divisor = LLVMBuildOr(builder,
> +                                      div_mask,
> +                                      emit_data->args[1], "");
> +   LLVMValueRef result = lp_build_div(&bld_base->uint_bld,
> +                                      emit_data->args[0], divisor);
> +   emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
> +                                                    div_mask,
> +                                                    result, "");
>  }
>  
>  /* TGSI_OPCODE_UMAX (CPU Only) */
> @@ -1576,8 +1587,18 @@ umod_emit_cpu(
>     struct lp_build_tgsi_context * bld_base,
>     struct lp_build_emit_data * emit_data)
>  {
> -   emit_data->output[emit_data->chan] = lp_build_mod(&bld_base->uint_bld,
> -                                   emit_data->args[0], emit_data->args[1]);
> +   LLVMBuilderRef builder = bld_base->base.gallivm->builder;
> +   LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint_bld,
> +                                        PIPE_FUNC_EQUAL, emit_data->args[1],
> +                                        bld_base->uint_bld.zero);
> +   LLVMValueRef divisor = LLVMBuildOr(builder,
> +                                      div_mask,
> +                                      emit_data->args[1], "");
> +   LLVMValueRef result = lp_build_mod(&bld_base->uint_bld,
> +                                      emit_data->args[0], divisor);
> +   emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
> +                                                    div_mask,
> +                                                    result, "");
>  }
>  
>  /* TGSI_OPCODE_USET Helper (CPU Only) */
> 

I think it would be nice if there'd be a comment in the code itself
saying why this is done (e.g. something similar to the commit message).
But either way,
Reviewed-by: Roland Scheidegger <sroland at vmware.com>


More information about the mesa-dev mailing list