diff --git a/src/amd/compiler/aco_optimizer.cpp b/src/amd/compiler/aco_optimizer.cpp index a3db0a97684..5402a9b9227 100644 --- a/src/amd/compiler/aco_optimizer.cpp +++ b/src/amd/compiler/aco_optimizer.cpp @@ -3346,8 +3346,11 @@ combine_vop3p(opt_ctx& ctx, aco_ptr& instr) !vop3p->opsel_lo[1] && !vop3p->opsel_hi[1]) { Instruction* op_instr = ctx.info[instr->operands[0].tempId()].parent_instr; - if (op_instr->isVOP3P() && - instr_info.alu_opcode_infos[(int)op_instr->opcode].output_modifiers) { + const aco_alu_opcode_info& opcode_info = instr_info.alu_opcode_infos[(int)op_instr->opcode]; + aco_type op_type = opcode_info.def_types[0]; + if (op_instr->isVOP3P() && op_type.num_components == 2 && + op_type.base_type == aco_base_type_float && op_type.bit_size == 16 && + opcode_info.output_modifiers) { op_instr->valu().clamp = true; propagate_swizzles(&op_instr->valu(), vop3p->opsel_lo[0], vop3p->opsel_hi[0]); instr->definitions[0].swapTemp(op_instr->definitions[0]); diff --git a/src/amd/compiler/tests/test_optimizer.cpp b/src/amd/compiler/tests/test_optimizer.cpp index 42dc3c3f7c3..8edaee7695b 100644 --- a/src/amd/compiler/tests/test_optimizer.cpp +++ b/src/amd/compiler/tests/test_optimizer.cpp @@ -2048,3 +2048,33 @@ BEGIN_TEST(optimizer.trans_no_omod) finish_opt_test(); END_TEST + +BEGIN_TEST(optimizer.pk_clamp_fma_mix) + //>> v1: %a:v[0], v1: %b:v[1], v2b: %c:v[2][0:16] = p_startpgm + if (!setup_cs("v1 v1 v2b", GFX12)) + return; + + //! v2b: %cvt0 = v_fma_mixlo_f16 1.0, %a, %b + //! v1: %clamp0 = v_pk_mul_f16 %cvt0.xx, 1.0.xx clamp + //! p_unit_test 0, %clamp0 + Temp add0 = bld.vop2(aco_opcode::v_add_f32, bld.def(v1), inputs[0], inputs[1]); + Temp cvt0 = bld.vop1(aco_opcode::v_cvt_f16_f32, bld.def(v2b), add0); + Builder::Result clamp0 = + bld.vop3p(aco_opcode::v_pk_mul_f16, bld.def(v1), cvt0, Operand::c16(0x3c00), 0, 0); + clamp0->valu().clamp = true; + + writeout(0, clamp0); + + //! v1: %add1 = v_fma_mix_f32 1.0, lo(%c), %a + //! v1: %clamp1 = v_pk_mul_f16 %add1, 1.0.xx clamp + //! p_unit_test 1, %clamp1 + Temp cvt1 = bld.vop1(aco_opcode::v_cvt_f32_f16, bld.def(v1), inputs[2]); + Temp add1 = bld.vop2(aco_opcode::v_add_f32, bld.def(v1), inputs[0], cvt1); + Builder::Result clamp1 = + bld.vop3p(aco_opcode::v_pk_mul_f16, bld.def(v1), add1, Operand::c16(0x3c00), 0, 0x1); + clamp1->valu().clamp = true; + + writeout(1, clamp1); + + finish_opt_test(); +END_TEST