diff --git a/src/intel/compiler/brw_eu_validate.c b/src/intel/compiler/brw_eu_validate.c index b30c9ba4197..cad582b1db1 100644 --- a/src/intel/compiler/brw_eu_validate.c +++ b/src/intel/compiler/brw_eu_validate.c @@ -2279,6 +2279,47 @@ instruction_restrictions(const struct brw_isa_info *isa, } + if (brw_inst_opcode(isa, inst) == BRW_OPCODE_ADD3) { + const enum brw_reg_type dst_type = inst_dst_type(isa, inst); + + ERROR_IF(dst_type != BRW_REGISTER_TYPE_D && + dst_type != BRW_REGISTER_TYPE_UD && + dst_type != BRW_REGISTER_TYPE_W && + dst_type != BRW_REGISTER_TYPE_UW, + "Destination must be integer D, UD, W, or UW type."); + + for (unsigned i = 0; i < 3; i++) { + enum brw_reg_type src_type; + + switch (i) { + case 0: src_type = brw_inst_3src_a1_src0_type(devinfo, inst); break; + case 1: src_type = brw_inst_3src_a1_src1_type(devinfo, inst); break; + case 2: src_type = brw_inst_3src_a1_src2_type(devinfo, inst); break; + default: unreachable("invalid src"); + } + + ERROR_IF(src_type != BRW_REGISTER_TYPE_D && + src_type != BRW_REGISTER_TYPE_UD && + src_type != BRW_REGISTER_TYPE_W && + src_type != BRW_REGISTER_TYPE_UW, + "Source must be integer D, UD, W, or UW type."); + + if (i == 0) { + if (brw_inst_3src_a1_src0_is_imm(devinfo, inst)) { + ERROR_IF(src_type != BRW_REGISTER_TYPE_W && + src_type != BRW_REGISTER_TYPE_UW, + "Immediate source must be integer W or UW type."); + } + } else if (i == 2) { + if (brw_inst_3src_a1_src2_is_imm(devinfo, inst)) { + ERROR_IF(src_type != BRW_REGISTER_TYPE_W && + src_type != BRW_REGISTER_TYPE_UW, + "Immediate source must be integer W or UW type."); + } + } + } + } + if (brw_inst_opcode(isa, inst) == BRW_OPCODE_OR || brw_inst_opcode(isa, inst) == BRW_OPCODE_AND || brw_inst_opcode(isa, inst) == BRW_OPCODE_XOR || diff --git a/src/intel/compiler/test_eu_validate.cpp b/src/intel/compiler/test_eu_validate.cpp index bb26208cacf..1a78a29fb1a 100644 --- a/src/intel/compiler/test_eu_validate.cpp +++ b/src/intel/compiler/test_eu_validate.cpp @@ -3001,3 +3001,110 @@ TEST_P(validation_test, gfx11_no_byte_src_1_2) clear_instructions(p); } } + +TEST_P(validation_test, add3_source_types) +{ + static const struct { + enum brw_reg_type dst_type; + enum brw_reg_type src0_type; + enum brw_reg_type src1_type; + enum brw_reg_type src2_type; + bool expected_result; + } inst[] = { +#define INST(dst_type, src0_type, src1_type, src2_type, expected_result) \ + { \ + BRW_REGISTER_TYPE_##dst_type, \ + BRW_REGISTER_TYPE_##src0_type, \ + BRW_REGISTER_TYPE_##src1_type, \ + BRW_REGISTER_TYPE_##src2_type, \ + expected_result, \ + } + + INST( F, F, F, F, false), + INST(HF, HF, HF, HF, false), + INST( B, B, B, B, false), + INST(UB, UB, UB, UB, false), + + INST( W, W, W, W, true), + INST(UW, UW, UW, UW, true), + INST( D, D, D, D, true), + INST(UD, UD, UD, UD, true), + + INST( W, D, W, W, true), + INST(UW, UW, UD, UW, true), + INST( D, D, W, D, true), + INST(UD, UD, UD, UW, true), +#undef INST + }; + + + if (devinfo.verx10 < 125) + return; + + for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { + brw_ADD3(p, + retype(g0, inst[i].dst_type), + retype(g0, inst[i].src0_type), + retype(g0, inst[i].src1_type), + retype(g0, inst[i].src2_type)); + + EXPECT_EQ(inst[i].expected_result, validate(p)); + + clear_instructions(p); + } +} + +TEST_P(validation_test, add3_immediate_types) +{ + static const struct { + enum brw_reg_type reg_type; + enum brw_reg_type imm_type; + unsigned imm_src; + bool expected_result; + } inst[] = { +#define INST(reg_type, imm_type, imm_src, expected_result) \ + { \ + BRW_REGISTER_TYPE_##reg_type, \ + BRW_REGISTER_TYPE_##imm_type, \ + imm_src, \ + expected_result, \ + } + + INST( W, W, 0, true), + INST( W, W, 2, true), + INST(UW, UW, 0, true), + INST(UW, UW, 2, true), + INST( D, W, 0, true), + INST(UD, W, 2, true), + INST( D, UW, 0, true), + INST(UW, UW, 2, true), + + INST( W, D, 0, false), + INST( W, D, 2, false), + INST(UW, UD, 0, false), + INST(UW, UD, 2, false), + INST( D, D, 0, false), + INST(UD, D, 2, false), + INST( D, UD, 0, false), + INST(UW, UD, 2, false), +#undef INST + }; + + + if (devinfo.verx10 < 125) + return; + + for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { + brw_ADD3(p, + retype(g0, inst[i].reg_type), + inst[i].imm_src == 0 ? retype(brw_imm_d(0x1234), inst[i].imm_type) + : retype(g0, inst[i].reg_type), + retype(g0, inst[i].reg_type), + inst[i].imm_src == 2 ? retype(brw_imm_d(0x2143), inst[i].imm_type) + : retype(g0, inst[i].reg_type)); + + EXPECT_EQ(inst[i].expected_result, validate(p)); + + clear_instructions(p); + } +}