pan/va: Handle 8-bit lane when lowering constants

We need to be careful to ensure the output of constant lowering still selects a
single lane, otherwise we lower something like:

   44 = MKVEC.v2i8 43.b1, #0x0.b0, #0x0

to

   44 = MKVEC.v2i8 24.b1, u256, u256

which loses the .b0 swizzle, and thus renders the MKVEC.v2i8 unable to pack.
Similarly, we need to allow zero-extension with fields marked "lane". Currently
only MKVEC.v2i8 hits this path, as the other instructions using "lane"
modifiers are unary and therefore will have been constant folded.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17220>
This commit is contained in:
Alyssa Rosenzweig
2022-06-22 15:15:00 -04:00
committed by Marge Bot
parent 6b87a65e38
commit 7d07fb9a67
2 changed files with 25 additions and 2 deletions

View File

@@ -188,3 +188,16 @@ TEST_F(LowerConstants, HandleTrickyNegativesFP16)
CASE(bi_fadd_v2f16_to(b, bi_register(0), bi_register(0), bi_imm_f16(57216.0)),
bi_fadd_v2f16_to(b, bi_register(0), bi_register(0), bi_neg(bi_half(va_lut(3), 1))));
}
TEST_F(LowerConstants, MaintainMkvecRestrictedSwizzles)
{
CASE(bi_mkvec_v2i8_to(b, bi_register(0), bi_register(0),
bi_imm_u8(0), bi_imm_u32(0)),
bi_mkvec_v2i8_to(b, bi_register(0), bi_register(0),
bi_byte(va_lut(0), 0), va_lut(0)));
CASE(bi_mkvec_v2i8_to(b, bi_register(0), bi_register(0),
bi_imm_u8(14), bi_imm_u32(0)),
bi_mkvec_v2i8_to(b, bi_register(0), bi_register(0),
bi_byte(va_lut(11), 2), va_lut(0)));
}

View File

@@ -143,7 +143,7 @@ va_resolve_constant(bi_builder *b, uint32_t value, struct va_src_info info, bool
}
/* Try extending a byte */
if (!staging && (info.widen || info.lanes) &&
if (!staging && (info.widen || info.lanes || info.lane) &&
is_extension_of_8(value, is_signed)) {
bi_index lut = va_lut_index_8(value & 0xFF);
@@ -207,7 +207,7 @@ va_lower_constants(bi_context *ctx, bi_instr *I)
} else if (info.size == VA_SIZE_16) {
assert(swz >= BI_SWIZZLE_H00 && swz <= BI_SWIZZLE_H11);
value = bi_apply_swizzle(value, swz);
} else if (info.size == VA_SIZE_8 && info.lanes) {
} else if (info.size == VA_SIZE_8 && (info.lane || info.lanes)) {
/* 8-bit extract */
unsigned chan = (swz - BI_SWIZZLE_B0000);
assert(chan < 4);
@@ -221,6 +221,16 @@ va_lower_constants(bi_context *ctx, bi_instr *I)
bi_index cons = va_resolve_constant(&b, value, info, is_signed, staging);
cons.neg ^= I->src[s].neg;
I->src[s] = cons;
/* If we're selecting a single 8-bit lane, we should return a single
* 8-bit lane to ensure the result is encodeable. By convention,
* applying the lane select puts the desired constant (at least) in the
* bottom byte, so we can always select the bottom byte.
*/
if (info.lane && I->src[s].swizzle == BI_SWIZZLE_H01) {
assert(info.size == VA_SIZE_8);
I->src[s] = bi_byte(I->src[s], 0);
}
}
}
}