From 3f35b1329e701a04349d40d4b05e9b1e6cf9f71d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 27 Jun 2025 08:58:26 +0200 Subject: [PATCH] aco: allow subdword vector-definitions on some VALU instructions Part-of: --- src/amd/compiler/aco_register_allocation.cpp | 3 ++- src/amd/compiler/aco_validate.cpp | 3 +-- .../instruction_selection/aco_select_nir_alu.cpp | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 29340a28ab3..090e681259d 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -692,7 +692,8 @@ DefInfo::get_subdword_definition_info(Program* program, const aco_ptrisVALU()) { - assert(rc.bytes() <= 2); + if (rc.bytes() == 3) + rc = v1; if (can_use_SDWA(gfx_level, instr, false)) return; diff --git a/src/amd/compiler/aco_validate.cpp b/src/amd/compiler/aco_validate.cpp index 12465a4d425..6e39c423332 100644 --- a/src/amd/compiler/aco_validate.cpp +++ b/src/amd/compiler/aco_validate.cpp @@ -1317,9 +1317,8 @@ get_subdword_bytes_written(Program* program, const aco_ptr& instr, if (instr->isPseudo()) return gfx_level >= GFX8 ? def.bytes() : def.size() * 4u; - if (instr->isVALU() || instr->isVINTRP()) { - assert(def.bytes() <= 2); + if (instr->isVALU() || instr->isVINTRP()) { if (instr->isSDWA()) return instr->sdwa().dst_sel.size(); diff --git a/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp b/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp index 321f43100c5..59f3451ba95 100644 --- a/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp +++ b/src/amd/compiler/instruction_selection/aco_select_nir_alu.cpp @@ -424,8 +424,8 @@ emit_bitwise_logic(isel_context* ctx, nir_alu_instr* instr, Temp dst, Builder::WaveSpecificOpcode op, aco_opcode v32_op) { Builder bld(ctx->program, ctx->block); - Temp src0 = get_alu_src(ctx, instr->src[0]); - Temp src1 = get_alu_src(ctx, instr->src[1]); + Temp src0 = get_alu_src(ctx, instr->src[0], instr->def.num_components); + Temp src1 = get_alu_src(ctx, instr->src[1], instr->def.num_components); if (instr->def.bit_size == 1) { bld.sop2(op, Definition(dst), bld.def(s1, scc), src0, src1); @@ -460,8 +460,8 @@ emit_bcsel(isel_context* ctx, nir_alu_instr* instr, Temp dst) { Builder bld(ctx->program, ctx->block); Temp cond = get_alu_src(ctx, instr->src[0]); - Temp then = get_alu_src(ctx, instr->src[1]); - Temp els = get_alu_src(ctx, instr->src[2]); + Temp then = get_alu_src(ctx, instr->src[1], instr->def.num_components); + Temp els = get_alu_src(ctx, instr->src[2], instr->def.num_components); assert(cond.regClass() == bld.lm); @@ -877,9 +877,9 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr) break; } case nir_op_inot: { - Temp src = get_alu_src(ctx, instr->src[0]); - if (dst.regClass() == v1 || dst.regClass() == v2b || dst.regClass() == v1b) { - emit_vop1_instruction(ctx, instr, aco_opcode::v_not_b32, dst); + Temp src = get_alu_src(ctx, instr->src[0], instr->def.num_components); + if (dst.regClass().type() == RegType::vgpr && dst.size() == 1) { + bld.vop1(aco_opcode::v_not_b32, Definition(dst), src); } else if (dst.regClass() == v2) { Temp lo = bld.tmp(v1), hi = bld.tmp(v1); bld.pseudo(aco_opcode::p_split_vector, Definition(lo), Definition(hi), src);