gallivm/nir: wrap idiv to avoid divide by 0 (v2)
This code is taken from the TGSI paths, and should fix the regression seens with GLES2 v2: use the udiv path which has d3d10 defined return. Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2303>
This commit is contained in:
@@ -385,6 +385,25 @@ merge_64bit(struct lp_build_nir_context *bld_base,
|
||||
return LLVMBuildShuffleVector(builder, input, input2, LLVMConstVector(shuffles, len), "");
|
||||
}
|
||||
|
||||
static LLVMValueRef
|
||||
do_int_divide(struct lp_build_nir_context *bld_base,
|
||||
bool is_unsigned, unsigned src_bit_size,
|
||||
LLVMValueRef src, LLVMValueRef src2)
|
||||
{
|
||||
struct gallivm_state *gallivm = bld_base->base.gallivm;
|
||||
LLVMBuilderRef builder = gallivm->builder;
|
||||
struct lp_build_context *int_bld = get_int_bld(bld_base, is_unsigned, src_bit_size);
|
||||
LLVMValueRef div_mask = lp_build_cmp(int_bld, PIPE_FUNC_EQUAL, src2,
|
||||
int_bld->zero);
|
||||
LLVMValueRef divisor = LLVMBuildOr(builder,
|
||||
div_mask,
|
||||
src2, "");
|
||||
LLVMValueRef result = lp_build_div(int_bld, src, divisor);
|
||||
/* udiv by zero is guaranteed to return 0xffffffff at least with d3d10
|
||||
* may as well do same for idiv */
|
||||
return LLVMBuildOr(builder, div_mask, result, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base,
|
||||
nir_op op, unsigned src_bit_size[4], LLVMValueRef src[4])
|
||||
{
|
||||
@@ -576,8 +595,7 @@ static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base,
|
||||
src[0], src[1]);
|
||||
break;
|
||||
case nir_op_idiv:
|
||||
result = lp_build_div(&bld_base->int_bld,
|
||||
src[0], src[1]);
|
||||
result = do_int_divide(bld_base, false, src_bit_size[0], src[0], src[1]);
|
||||
break;
|
||||
case nir_op_ieq32:
|
||||
result = icmp32(bld_base, PIPE_FUNC_EQUAL, false, src_bit_size[0], src);
|
||||
@@ -660,8 +678,7 @@ static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base,
|
||||
result = LLVMBuildZExt(builder, src[0], bld_base->uint64_bld.vec_type, "");
|
||||
break;
|
||||
case nir_op_udiv:
|
||||
result = lp_build_div(&bld_base->uint_bld,
|
||||
src[0], src[1]);
|
||||
result = do_int_divide(bld_base, true, src_bit_size[0], src[0], src[1]);
|
||||
break;
|
||||
case nir_op_ufind_msb: {
|
||||
struct lp_build_context *uint_bld = get_int_bld(bld_base, true, src_bit_size[0]);
|
||||
|
Reference in New Issue
Block a user