r600/sfn: make sure kill and update_exec don't happen in one group

v2: - Correctly test in multi-slot split whether the group has kill if
      we want to add a multi-slot op.
    - update group_has_predicate if an according vector op was added

Fixes: 359bfc3138 ("r600/sfn: make sure that kill and update pred are not in the same group")

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
(cherry picked from commit 317345cc98)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38268>
This commit is contained in:
Gert Wollny 2025-10-28 16:26:00 +01:00 committed by Dylan Baker
parent e082f6b6c0
commit 2c67b0fac6
2 changed files with 25 additions and 2 deletions

View file

@ -654,7 +654,7 @@
"description": "r600/sfn: make sure kill and update_exec don't happen in one group",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "359bfc3138eea36a32a41d93e37687ed7d413ca3",
"notes": null

View file

@ -870,7 +870,7 @@ BlockScheduler::schedule_alu_to_group_vec(AluGroup *group)
auto i = alu_vec_ready.begin();
auto e = alu_vec_ready.end();
bool group_has_kill = group->has_kill_op();
bool group_has_update_pred = false;
bool group_has_update_pred = group->has_update_exec();
while (i != e) {
sfn_log << SfnLog::schedule << "Try schedule to vec " << **i;
@ -945,6 +945,7 @@ BlockScheduler::schedule_alu_to_group_vec(AluGroup *group)
success = true;
group_has_kill |= is_kill;
group_has_update_pred |= does_update_pred;
sfn_log << SfnLog::schedule << " success\n";
} else {
@ -965,8 +966,20 @@ BlockScheduler::schedule_alu_multislot_to_group_vec(AluGroup *group, ValueFactor
auto i = alu_multi_slot_ready.begin();
auto e = alu_multi_slot_ready.end();
bool group_has_kill = group->has_kill_op();
while (i != e && util_bitcount(group->free_slot_mask()) > 1) {
/* A kill instruction and a predicate update in the same
* group don't mix well, so skip adding a predicate changing
* multi-slot op if we already have a kill. (There are no
* multi-slot kill ops).
*/
if (group_has_kill && (*i)->has_alu_flag(alu_update_exec)) {
++i;
continue;
}
auto dest = (*i)->dest();
bool can_merge = false;
@ -1038,6 +1051,10 @@ BlockScheduler::schedule_alu_to_group_trans(AluGroup *group,
bool success = false;
auto i = readylist.begin();
auto e = readylist.end();
bool group_has_kill = group->has_kill_op();
bool group_has_update_pred = group->has_update_exec();
while (i != e) {
if (check_array_reads(**i)) {
@ -1052,6 +1069,12 @@ BlockScheduler::schedule_alu_to_group_trans(AluGroup *group,
continue;
}
if ((group_has_kill && (*i)->has_alu_flag(alu_update_exec)) ||
(group_has_update_pred && (*i)->is_kill())) {
++i;
continue;
}
if (group->add_trans_instructions(*i)) {
(*i)->pin_dest_to_chan();
auto old_i = i;