mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 19:50:11 +01:00
ir3/spill: Fix extracting from a vector at the end of a block
If this happens then "after" is NULL, so we can't use it to get the
block, and the instruction is never moved at the end so we have to
create the split instructions before creating the collect to make sure
they are in the right order.
This happens when reloading a complex vector value that has been
coalesced at the end of a basic block, which apparently hasn't happened
until a gfxbench5 shader on zink hit this case. This fixes it.
Closes: #7054
Fixes: 613eaac7b5 ("ir3: Initial support for spilling non-shared registers")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18082>
This commit is contained in:
parent
f9d7308014
commit
dcfbb60392
1 changed files with 8 additions and 4 deletions
|
|
@ -854,7 +854,7 @@ split(struct ir3_register *def, unsigned offset,
|
||||||
assert(!(def->flags & IR3_REG_ARRAY));
|
assert(!(def->flags & IR3_REG_ARRAY));
|
||||||
assert(def->merge_set);
|
assert(def->merge_set);
|
||||||
struct ir3_instruction *split =
|
struct ir3_instruction *split =
|
||||||
ir3_instr_create(after->block, OPC_META_SPLIT, 1, 1);
|
ir3_instr_create(block, OPC_META_SPLIT, 1, 1);
|
||||||
struct ir3_register *dst = __ssa_dst(split);
|
struct ir3_register *dst = __ssa_dst(split);
|
||||||
dst->flags |= def->flags & IR3_REG_HALF;
|
dst->flags |= def->flags & IR3_REG_HALF;
|
||||||
struct ir3_register *src = ir3_src_create(split, INVALID_REG, def->flags);
|
struct ir3_register *src = ir3_src_create(split, INVALID_REG, def->flags);
|
||||||
|
|
@ -874,16 +874,20 @@ extract(struct ir3_register *parent_def, unsigned offset, unsigned elems,
|
||||||
if (offset == 0 && elems == reg_elems(parent_def))
|
if (offset == 0 && elems == reg_elems(parent_def))
|
||||||
return parent_def;
|
return parent_def;
|
||||||
|
|
||||||
|
struct ir3_register *srcs[elems];
|
||||||
|
for (unsigned i = 0; i < elems; i++) {
|
||||||
|
srcs[i] = split(parent_def, offset + i, after, block);
|
||||||
|
}
|
||||||
|
|
||||||
struct ir3_instruction *collect =
|
struct ir3_instruction *collect =
|
||||||
ir3_instr_create(after->block, OPC_META_COLLECT, 1, elems);
|
ir3_instr_create(block, OPC_META_COLLECT, 1, elems);
|
||||||
struct ir3_register *dst = __ssa_dst(collect);
|
struct ir3_register *dst = __ssa_dst(collect);
|
||||||
dst->flags |= parent_def->flags & IR3_REG_HALF;
|
dst->flags |= parent_def->flags & IR3_REG_HALF;
|
||||||
dst->wrmask = MASK(elems);
|
dst->wrmask = MASK(elems);
|
||||||
add_to_merge_set(parent_def->merge_set, dst, parent_def->merge_set_offset);
|
add_to_merge_set(parent_def->merge_set, dst, parent_def->merge_set_offset);
|
||||||
|
|
||||||
for (unsigned i = 0; i < elems; i++) {
|
for (unsigned i = 0; i < elems; i++) {
|
||||||
ir3_src_create(collect, INVALID_REG, parent_def->flags)->def =
|
ir3_src_create(collect, INVALID_REG, parent_def->flags)->def = srcs[i];
|
||||||
split(parent_def, offset + i, after, block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (after)
|
if (after)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue