diff --git a/.pick_status.json b/.pick_status.json index a20ab10dff0..91360932f83 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp index 0d3eac93636..74804aac3ef 100644 --- a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp @@ -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;