shader: drop BFM mask bits shifted past bit 31 instead of an out-of-range bit-field insert

This commit is contained in:
nmzik
2026-10-21 22:59:56 +02:00
parent 2862ad5b25
commit fa32940d14
2 changed files with 28 additions and 3 deletions
@@ -380,9 +380,8 @@ void Translator::S_QUADMASK_B64(const Decoder::Instruction& inst) {
void Translator::BFM_B32(const Decoder::Instruction& inst) {
const auto count = ir.BitwiseAnd(ReadU32(inst.src0), IR::U32(IR::Value(31u)));
const auto offset = ir.BitwiseAnd(ReadU32(inst.src1), IR::U32(IR::Value(31u)));
const auto result = ir.Emit(IR::ValueOpcode::BitFieldInsert,
{IR::Value(0u), IR::Value(0xffffffffu), offset, count});
WriteOperand(DestinationOperand(inst), result);
// Mask bits shifted past bit 31 are dropped.
WriteOperand(DestinationOperand(inst), ir.ShiftLeftLogical(RightMask32(count), offset));
}
IR::U32 Translator::RightMask32(IR::U32 count) {
+26
View File
@@ -25622,6 +25622,31 @@ TestCase VectorBfeI32SignExtendsField() {
return test;
}
TestCase VectorBfmDropsMaskBitsPastBit31() {
using O = ShaderOpcode;
std::vector<u32> code;
for (u32 vgpr = 0; vgpr < 4; vgpr++) {
AppendVMovU32(&code, 30, vgpr * sizeof(u32));
AppendBufferLoadDword(&code, vgpr, 30);
}
AppendVop3(&code, 0x363, 10, Vgpr(0), Vgpr(1));
AppendVop3(&code, 0x363, 11, Vgpr(2), Vgpr(3));
AppendStoreVgpr(&code, 10, 0);
AppendStoreVgpr(&code, 11, 1);
AppendEnd(&code);
TestCase test;
test.name = "VectorBfmDropsMaskBitsPastBit31";
test.code = std::move(code);
// Size and offset use bits [4:0]; mask bits shifted past bit 31 are dropped.
test.initial = {24, 16, 0x3fu, 0x21u};
test.expected = {0xffff0000u, 0xfffffffeu};
test.opcodes = {O::V_MOV_B32, O::BUFFER_LOAD_DWORD, O::V_BFM_B32,
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
return test;
}
TestCase VectorAlignByteUsesTwoBitByteOffset() {
using O = ShaderOpcode;
@@ -42981,6 +43006,7 @@ std::vector<TestCase> MakeCases() {
AddCase(VectorVop3LshlrevB64Captured);
AddCase(VectorVop3IntegerOps);
AddCase(VectorBfeI32SignExtendsField);
AddCase(VectorBfmDropsMaskBitsPastBit31);
AddCase(VectorAlignByteUsesTwoBitByteOffset);
AddCase(VectorCarryAndBitCountOps);
AddCase(ScalarVector64BitFloatInlineConstants);