r600/sfn: AR loads are not dependend on the future and other code blocks

If the AR is loaded from a register changing that register in a loop was
resulting in a scheduling failure because the AR load was made dependend
on a later instruction. Fix the dependencies by only using dependencies on
older instruuctions in the same block.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14114
Fixes: d21054b4bc ("r600/sfn: Add pass to split addess and index register loads")

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38056>
This commit is contained in:
Gert Wollny
2025-10-24 16:59:22 +02:00
committed by Marge Bot
parent bee04c63ba
commit 43d9765e35
3 changed files with 70 additions and 3 deletions
@@ -88,8 +88,10 @@ class CollectDeps : public ConstRegisterVisitor {
public:
void visit(const Register& r) override
{
for (auto p : r.parents())
add_dep(p);
for (auto p : r.parents()) {
if (instr->block_id() == p->block_id() && instr->index() < p->index())
add_dep(p);
}
}
void visit(const LocalArray& value) override {(void)value; UNREACHABLE("Array is not a value");}
void visit(const LocalArrayValue& r) override
@@ -22,7 +22,7 @@ r600_test_dep = declare_dependency(
if with_tests
foreach t : ['valuefactory', 'value', 'instr', 'instrfromstring', 'liverange',
'optimizer', 'shaderfromstring', 'split_address_loads' ]
'optimizer', 'regression', 'shaderfromstring', 'split_address_loads' ]
test(
t,
executable('test-@0@-r600-sfn'.format(t),
@@ -0,0 +1,65 @@
#include "sfn_test_shaders.h"
#include "../sfn_optimizer.h"
#include "../sfn_ra.h"
#include "../sfn_scheduler.h"
#include "../sfn_shader.h"
#include "../sfn_split_address_loads.h"
using namespace r600;
using std::ostringstream;
TEST_F(TestShaderFromNir, CombineRegisterToTexSrc)
{
const char *shader_input =
R"(VS
CHIPCLASS EVERGREEN
INPUT LOC:0
INPUT LOC:1
OUTPUT LOC:0 VARYING_SLOT:0 MASK:15
OUTPUT LOC:1 VARYING_SLOT:32 MASK:3
REGISTERS R1.xyzw R2.xyzw R6.y R7.x R8.y R9.x R10.y
ARRAYS A3[2].zw
SHADER
BLOCK_START
ALU MOV R10.y@free : R2.x@fully{sb} {W}
ALU MOV R9.x@free : R2.y@fully{sb} {W}
ALU MOV R8.y@free : R2.z@fully{sb} {W}
ALU MOV R7.x@free : R2.w@fully{sb} {W}
ALU MOV R6.y@free : I[0] {W}
LOOP_BEGIN
BLOCK_END
BLOCK_START
IF (( ALU PRED_SETGE_INT __.x : R6.y@free KC0[0].x {LEP} PUSH_BEFORE ))
BLOCK_END
BLOCK_START
BREAK
BLOCK_END
BLOCK_START
ENDIF
BLOCK_END
BLOCK_START
ALU INT_TO_FLT CLAMP S22.y@free{s} : R6.y@free {W}
ALU TRUNC S24.w@free{s} : S22.y@free{s} {W}
ALU FLT_TO_INT S25.x@free{s} : S24.w@free{s} {W}
ALU MOV A3[S25.x@free].z : R10.y@free {W}
ALU MOV A3[S25.x@free].w : R9.x@free {W}
ALU MUL_IEEE R5.x@free : R9.x@free I[0.5] {W}
ALU MUL_IEEE R9.x@free : R8.y@free I[0.5] {W}
ALU MUL_IEEE R8.y@free : R7.x@free I[0.5] {W}
ALU MUL_IEEE R7.x@free : R10.y@free I[0.5] {W}
ALU ADD_INT R6.y@free : R6.y@free I[1] {W}
ALU MOV R10.y@free : R5.x@free {W}
LOOP_END
BLOCK_END
BLOCK_START
ALU ADD S47.z@group{s} : A3[0].z A3[1].z {W}
ALU ADD S47.x@group{s} : A3[0].w A3[1].w {W}
EXPORT_DONE PARAM 0 S47.zx__
EXPORT_DONE POS 0 R1.xyzw
BLOCK_END)";
auto sh = from_string(shader_input);
split_address_loads(*sh);
schedule(sh);
}