diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index ece97735712..4e00f6ed952 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -857,8 +857,18 @@ static bool visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr) src[0] = ac_to_float(&ctx->ac, src[0]); src[1] = ac_to_float(&ctx->ac, src[1]); src[2] = ac_to_float(&ctx->ac, src[2]); - result = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.fma.legacy", ctx->ac.f32, - src, 3, 0); +#if LLVM_VERSION_MAJOR <= 21 + /* Workaround for LLVM bug that crashes when using legacy fma on GFX12. */ + if (ctx->ac.gfx_level == GFX12) { + LLVMValueRef mulz = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.fmul.legacy", + ctx->ac.f32, src, 2, 0); + result = LLVMBuildFAdd(ctx->ac.builder, mulz, src[2], ""); + } else +#endif + { + result = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.fma.legacy", ctx->ac.f32, + src, 3, 0); + } break; case nir_op_ldexp: src[0] = ac_to_float(&ctx->ac, src[0]);