gallivm: avoid crashing in mod by 0 with llvmpipe

This adds code that is basically the same as the code in umod, udiv and idiv.
However, unlike idiv we return -1.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
Jeff Muizelaar 2016-01-16 03:35:26 +01:00 committed by Roland Scheidegger
parent d54a70aa18
commit e5fefe49f2

View file

@ -1536,8 +1536,22 @@ mod_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->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 doesn't have a guaranteed return value chose -1 for now. */
emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
div_mask,
result, "");
}
/* TGSI_OPCODE_NOT */