[Mesa-dev] [PATCH] avoid crashing in mod by 0 with llvmpipe
Jeff Muizelaar
jmuizelaar at mozilla.com
Fri Jan 15 11:13:34 PST 2016
This adds code that is basically the same as the code in smod, div and idiv.
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 */
+ 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)
More information about the mesa-dev
mailing list