summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/gallivm
diff options
context:
space:
mode:
authorJeff Muizelaar <[email protected]>2016-01-16 03:35:26 +0100
committerRoland Scheidegger <[email protected]>2016-01-16 03:36:29 +0100
commite5fefe49f2f86b5125da87c44fe855fd6f3424fc (patch)
tree7e967a68e153310aad1f196469970e7ee109fb8f /src/gallium/auxiliary/gallivm
parentd54a70aa18a0139a5eefbc5193fabaf739317533 (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
index 3d5e2cb316b..6f75bec5005 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
@@ -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 */