mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
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:
parent
7d65614422
commit
c717ac1247
1 changed files with 21 additions and 4 deletions
|
|
@ -385,6 +385,25 @@ merge_64bit(struct lp_build_nir_context *bld_base,
|
||||||
return LLVMBuildShuffleVector(builder, input, input2, LLVMConstVector(shuffles, len), "");
|
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,
|
static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base,
|
||||||
nir_op op, unsigned src_bit_size[4], LLVMValueRef src[4])
|
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]);
|
src[0], src[1]);
|
||||||
break;
|
break;
|
||||||
case nir_op_idiv:
|
case nir_op_idiv:
|
||||||
result = lp_build_div(&bld_base->int_bld,
|
result = do_int_divide(bld_base, false, src_bit_size[0], src[0], src[1]);
|
||||||
src[0], src[1]);
|
|
||||||
break;
|
break;
|
||||||
case nir_op_ieq32:
|
case nir_op_ieq32:
|
||||||
result = icmp32(bld_base, PIPE_FUNC_EQUAL, false, src_bit_size[0], src);
|
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, "");
|
result = LLVMBuildZExt(builder, src[0], bld_base->uint64_bld.vec_type, "");
|
||||||
break;
|
break;
|
||||||
case nir_op_udiv:
|
case nir_op_udiv:
|
||||||
result = lp_build_div(&bld_base->uint_bld,
|
result = do_int_divide(bld_base, true, src_bit_size[0], src[0], src[1]);
|
||||||
src[0], src[1]);
|
|
||||||
break;
|
break;
|
||||||
case nir_op_ufind_msb: {
|
case nir_op_ufind_msb: {
|
||||||
struct lp_build_context *uint_bld = get_int_bld(bld_base, true, src_bit_size[0]);
|
struct lp_build_context *uint_bld = get_int_bld(bld_base, true, src_bit_size[0]);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue