[Mesa-dev] [PATCH] avoid crashing in mod by 0 with llvmpipe
Roland Scheidegger
sroland at vmware.com
Fri Jan 15 18:57:40 PST 2016
Ok, pushed.
Roland
Am 15.01.2016 um 21:01 schrieb Jeff Muizelaar:
> Do you mind fixing up the language to match what you're looking for
> and committing it?
>
> Thanks,
>
> -Jeff
>
> On Fri, Jan 15, 2016 at 3:00 PM, Roland Scheidegger <sroland at vmware.com> wrote:
>> Am 15.01.2016 um 20:13 schrieb Jeff Muizelaar:
>>> This adds code that is basically the same as the code in smod, div and idiv.
>> That would be umod, not smod, above (and udiv).
>>
>>> However, unlike idiv we return -1.
>>>
>>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
>>> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
>>> index 0ad78b0..d17ef31 100644
>>> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
>>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
>>> @@ -1524,18 +1524,32 @@ min_emit_cpu(
>>>
>>> /* TGSI_OPCODE_MOD (CPU Only) */
>>> static void
>>> mod_emit_cpu(
>>> const struct lp_build_tgsi_action * action,
>>> 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->int_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);
>>> + /* We want to make sure that we never divide/mod by zero to not
>>> + * generate sigfpe. We don't want to crash just because the
>>> + * shader is doing something weird. */
>>> + LLVMValueRef divisor = LLVMBuildOr(builder,
>>> + div_mask,
>>> + emit_data->args[1], "");
>>> + LLVMValueRef result = lp_build_mod(&bld_base->int_bld,
>>> + emit_data->args[0], divisor);
>>> + /* umod by zero is guaranteed to return 0xffffffff */
>> I think this should use language along the lines of what idiv does, i.e.
>> no guaranteed value, pick -1. Because we don't say anything about that
>> in the gallium tgsi docs section about that (unlike udiv/umod).
>> (AFAIK we only really care for udiv/umod due to d3d10, which doesn't
>> have the signed versions - glsl doesn't care either way.)
>>
>>> + emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
>>> + div_mask,
>>> + result, "");
>>> }
>>>
>>> /* TGSI_OPCODE_NOT */
>>> static void
>>> not_emit_cpu(
>>> const struct lp_build_tgsi_action * action,
>>> struct lp_build_tgsi_context * bld_base,
>>> struct lp_build_emit_data * emit_data)
>>
>> Subject should probably say: gallivm: ...
>>
>> With that fixed: Reviewed-by: Roland Scheidegger <sroland at vmware.com>
>>
More information about the mesa-dev
mailing list