[Mesa-dev] [PATCH] gallivm: fix SCALED -> NORM conversions
Jose Fonseca
jfonseca at vmware.com
Tue Jun 17 08:37:47 PDT 2014
On 17/06/14 13:58, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> Such conversions (which are most likely rather pointless in practice) were
> resulting in shifts with negative shift counts and shifts with counts the same
> as the bit width. This was always undefined in llvm, the code generated was
> rather horrendous but happened to work.
> So make sure such shifts are filtered out and replaced with something that
> works (the generated code is still just as horrendous as before).
>
> This fixes lp_test_format, https://bugs.freedesktop.org/show_bug.cgi?id=73846.
> ---
> src/gallium/auxiliary/gallivm/lp_bld_conv.c | 24 +++++++++++++++++++-----
> 1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
> index d3bf621..fe8f08b 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
> @@ -794,7 +794,8 @@ lp_build_conv(struct gallivm_state *gallivm,
> unsigned dst_offset = lp_const_offset(dst_type);
>
> /* Compensate for different offsets */
> - if (dst_offset > src_offset && src_type.width > dst_type.width) {
> + /* sscaled -> unorm and similar would cause negative shift count, skip */
> + if (dst_offset > src_offset && src_type.width > dst_type.width && src_shift > 0) {
> for (i = 0; i < num_tmps; ++i) {
> LLVMValueRef shifted;
> LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type, src_shift - 1);
> @@ -903,11 +904,24 @@ lp_build_conv(struct gallivm_state *gallivm,
>
> if (src_shift < dst_shift) {
> LLVMValueRef pre_shift[LP_MAX_VECTOR_LENGTH];
> - LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type, dst_shift - src_shift);
>
> - for (i = 0; i < num_tmps; ++i) {
> - pre_shift[i] = tmp[i];
> - tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
> + if (dst_shift - src_shift < dst_type.width) {
> + LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type,
> + dst_shift - src_shift);
> + for (i = 0; i < num_tmps; ++i) {
> + pre_shift[i] = tmp[i];
> + tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
> + }
> + }
> + else {
> + /*
> + * This happens for things like sscaled -> unorm conversions.
> + * Negative shift counts cause undefined results, so hack around it.
> + */
> + for (i = 0; i < num_tmps; ++i) {
> + pre_shift[i] = tmp[i];
> + tmp[i] = lp_build_zero(gallivm, dst_type);
> + }
> }
>
> /* Compensate for different offsets */
Looks okay. Though I wonder if we could simplify the code while we are
at it, but leveraging the lp_build_shl_imm/lp_build_shr_imm helpers.
Jose
More information about the mesa-dev
mailing list