From e5fefe49f2f86b5125da87c44fe855fd6f3424fc Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Sat, 16 Jan 2016 03:35:26 +0100 Subject: [PATCH] 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 --- .../auxiliary/gallivm/lp_bld_tgsi_action.c | 18 ++++++++++++++++-- 1 file 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 */ -- 2.30.2