From 0619e4db6382095cb487c586ba9c676547727245 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Tue, 10 Sep 2024 12:21:30 +0100 Subject: [PATCH] nir,aco,ac/llvm: add nir_op_alignbyte_amd Signed-off-by: Rhys Perry Reviewed-by: Georg Lehmann Part-of: --- src/amd/compiler/aco_instruction_selection.cpp | 8 ++++++++ src/amd/compiler/aco_instruction_selection_setup.cpp | 3 ++- src/amd/llvm/ac_nir_to_llvm.c | 5 +++++ src/compiler/nir/nir_opcodes.py | 5 +++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index 28ebda7a11e..e614e0c53d1 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -3634,6 +3634,14 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr) } break; } + case nir_op_alignbyte_amd: { + if (dst.regClass() == v1) { + emit_vop3a_instruction(ctx, instr, aco_opcode::v_alignbyte_b32, dst, false, 3u); + } else { + isel_err(&instr->instr, "Unimplemented NIR instr bit size"); + } + break; + } case nir_op_fquantize2f16: { Temp src = get_alu_src(ctx, instr->src[0]); if (dst.regClass() == v1) { diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp index 6caf3619d59..91cac51ebc4 100644 --- a/src/amd/compiler/aco_instruction_selection_setup.cpp +++ b/src/amd/compiler/aco_instruction_selection_setup.cpp @@ -445,7 +445,8 @@ init_context(isel_context* ctx, nir_shader* shader) case nir_op_udot_2x16_uadd: case nir_op_sdot_2x16_iadd: case nir_op_udot_2x16_uadd_sat: - case nir_op_sdot_2x16_iadd_sat: type = RegType::vgpr; break; + case nir_op_sdot_2x16_iadd_sat: + case nir_op_alignbyte_amd: type = RegType::vgpr; break; case nir_op_fmul: case nir_op_ffma: case nir_op_fadd: diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index 9692a08d4e7..da4a88ff2d0 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -1245,6 +1245,11 @@ static bool visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr) (LLVMValueRef[]){src[0], src[1], src[2]}, 3, 0); break; + case nir_op_alignbyte_amd: + result = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.alignbyte", ctx->ac.i32, + (LLVMValueRef[]){src[0], src[1], src[2]}, 3, 0); + break; + default: fprintf(stderr, "Unknown NIR alu instr: "); nir_print_instr(&instr->instr, stderr); diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index 564ab540e59..7c2cb5b67ba 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -1307,6 +1307,11 @@ unop_horiz("cube_amd", 4, tfloat32, 3, tfloat32, """ unop("fsin_amd", tfloat, "sinf(6.2831853 * src0)") unop("fcos_amd", tfloat, "cosf(6.2831853 * src0)") +opcode("alignbyte_amd", 0, tuint32, [0, 0, 0], [tuint32, tuint32, tuint32], False, "", """ + uint64_t src = src1 | ((uint64_t)src0 << 32); + dst = src >> ((src2 & 0x3) * 8); +""") + # Midgard specific sin and cos # These expect their inputs to be divided by pi. unop("fsin_mdg", tfloat, "sinf(3.141592653589793 * src0)")