diff --git a/src/panfrost/bifrost/valhall/test/test-lower-constants.cpp b/src/panfrost/bifrost/valhall/test/test-lower-constants.cpp index 6bd3293c995..8438ebd0537 100644 --- a/src/panfrost/bifrost/valhall/test/test-lower-constants.cpp +++ b/src/panfrost/bifrost/valhall/test/test-lower-constants.cpp @@ -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))); +} diff --git a/src/panfrost/bifrost/valhall/va_lower_constants.c b/src/panfrost/bifrost/valhall/va_lower_constants.c index f8dc9d37a8f..e5a8fd7e224 100644 --- a/src/panfrost/bifrost/valhall/va_lower_constants.c +++ b/src/panfrost/bifrost/valhall/va_lower_constants.c @@ -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); + } } } }