Module: Mesa Branch: staging/22.2 Commit: da97b8a0e13403b134f711d148d8e3d32f135993 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=da97b8a0e13403b134f711d148d8e3d32f135993
Author: Danylo Piliaiev <[email protected]> Date: Mon Sep 5 12:18:55 2022 +0300 ir3: Prevent reordering movmsk with kill `kill` changes which fibers are active, thus reodering instructions which depend on which fibers are active - is wrong. The issue was hidden because only `ballot(true)` is translated to movmsk immidiately, while others are passed as MACRO and don't properly take part in ir3_sched (which does the reordering). Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7162 Fixes CTS test (on gen3+): dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_ballot Fixes: b1b80c06a78e62b2d8477b07f12b0153435b66a8 ("ir3: Implement nir subgroup intrinsics") Signed-off-by: Danylo Piliaiev <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18413> (cherry picked from commit 33e60798e144c6638343486371462e5522f3afd4) --- .pick_status.json | 2 +- src/freedreno/ir3/ir3.h | 2 ++ src/freedreno/ir3/ir3_compiler_nir.c | 14 +++++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 879dd64fbce..53d4ea70ad0 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -193,7 +193,7 @@ "description": "ir3: Prevent reordering movmsk with kill", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "b1b80c06a78e62b2d8477b07f12b0153435b66a8" }, diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 222eb6184cf..667dca8cbb0 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -483,6 +483,8 @@ struct ir3_instruction { IR3_BARRIER_PRIVATE_R = 1 << 9, IR3_BARRIER_PRIVATE_W = 1 << 10, IR3_BARRIER_CONST_W = 1 << 11, + IR3_BARRIER_ACTIVE_FIBERS_R = 1 << 12, + IR3_BARRIER_ACTIVE_FIBERS_W = 1 << 13, } barrier_class, barrier_conflict; diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 45f6c80bf6d..0272da3ba25 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -2471,9 +2471,13 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) kill = ir3_KILL(b, cond, 0); } - /* Side-effects should not be moved on a different side of the kill */ - kill->barrier_class = IR3_BARRIER_IMAGE_W | IR3_BARRIER_BUFFER_W; - kill->barrier_conflict = IR3_BARRIER_IMAGE_W | IR3_BARRIER_BUFFER_W; + /* - Side-effects should not be moved on a different side of the kill + * - Instructions that depend on active fibers should not be reordered + */ + kill->barrier_class = IR3_BARRIER_IMAGE_W | IR3_BARRIER_BUFFER_W | + IR3_BARRIER_ACTIVE_FIBERS_W; + kill->barrier_conflict = IR3_BARRIER_IMAGE_W | IR3_BARRIER_BUFFER_W | + IR3_BARRIER_ACTIVE_FIBERS_R; kill->srcs[0]->num = regid(REG_P0, 0); array_insert(ctx->ir, ctx->ir->predicates, kill); @@ -2566,6 +2570,10 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) array_insert(ctx->ir, ctx->ir->predicates, ballot); ctx->max_stack = MAX2(ctx->max_stack, ctx->stack + 1); } + + ballot->barrier_class = IR3_BARRIER_ACTIVE_FIBERS_R; + ballot->barrier_conflict = IR3_BARRIER_ACTIVE_FIBERS_W; + ir3_split_dest(ctx->block, dst, ballot, 0, components); break; }
