Merge pull request #1878 from adriadam10/fix/shader-fma-mix-fused
fix(shader): translate v_fma_mix_f32 as a fused multiply-add
This commit is contained in:
commit
f145139676
|
|
@ -70,6 +70,26 @@ void Check(const std::string& name, std::uint32_t encoding, std::uint32_t wordCo
|
|||
}
|
||||
}
|
||||
|
||||
void CheckMix(const std::string& name, const std::array<std::uint32_t, 2>& words) {
|
||||
const RdnaInstruction instruction = DecodeRdnaVectorOp(std::span<const std::uint32_t>(words), 0u);
|
||||
Require(instruction.family == RdnaInstructionFamily::VOP3P, name + " is not decoded as VOP3P");
|
||||
Require(instruction.op == RdnaOpcode::VFmaF32, name + " decodes to another opcode");
|
||||
|
||||
IrProgram program;
|
||||
auto& block = program.CreateBlock();
|
||||
program.SetEntryBlock(block);
|
||||
TranslationContext context(program, block, 256);
|
||||
context.SetFloatMode(ShaderFloatMode{0xf0u, false, false, false});
|
||||
context.TranslateInstruction(instruction);
|
||||
|
||||
std::uint32_t fused = 0u;
|
||||
for (const auto* value : block.Instructions()) {
|
||||
Require(value->Opcode() != IrOpcode::FPMad32, name + " rounds the product separately");
|
||||
if (value->Opcode() == IrOpcode::FPFma32) ++fused;
|
||||
}
|
||||
Require(fused == 1u, name + " emits " + std::to_string(fused) + " fused multiply-adds");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
|
@ -83,6 +103,8 @@ int main() {
|
|||
Check("v_fmac_f32", 0x2bu, 1u, RdnaOpcode::VMacF32, IrOpcode::FPFma32, accumulate);
|
||||
Check("v_fmamk_f32", 0x2cu, 2u, RdnaOpcode::VMadmkF32, IrOpcode::FPFma32, multiplyLiteral);
|
||||
Check("v_fmaak_f32", 0x2du, 2u, RdnaOpcode::VMadakF32, IrOpcode::FPFma32, addLiteral);
|
||||
CheckMix("v_fma_mix_f32", {0xcc200005u, 0x04220f06u});
|
||||
CheckMix("v_fma_mix_f32 op_sel_hi:[1,0,1]", {0xcc204005u, 0x0c220f06u});
|
||||
return 0;
|
||||
} catch (const std::exception& error) {
|
||||
std::cerr << error.what() << '\n';
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ bool roundsProductSeparately(const RdnaInstruction& inst) {
|
|||
if (inst.op == RdnaOpcode::VMadF32) {
|
||||
return true;
|
||||
}
|
||||
if (inst.family == RdnaInstructionFamily::VOP3P) {
|
||||
return false;
|
||||
}
|
||||
const std::uint32_t vop2 = inst.family == RdnaInstructionFamily::VOP3 ? inst.opcodeId - 0x100u : inst.opcodeId;
|
||||
return vop2 == 0x1fu || vop2 == 0x20u || vop2 == 0x21u;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue