nvc0/ir: be careful about propagating very large offsets into const load

Indirect constbuf indexing works by using very large offsets. However if
an indirect constbuf index load is const-propagated, it becomes a very
large const offset. Take that into account when legalizing the SSA by
moving the high parts of that offset into the file index. Also disallow
very large (or small) indices on most other instructions.

This fixes regressions in ubo_array_indexing/*-two-arrays piglit tests.

Fixes: abd326e81b (nv50/ir: propagate indirect loads into instructions)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin 2016-01-11 16:41:18 -05:00
parent 7a521ddf36
commit 37b67db6ae
4 changed files with 19 additions and 1 deletions

View file

@ -540,6 +540,12 @@ NVC0LegalizePostRA::visit(BasicBlock *bb)
// It seems like barriers are never required for tessellation since
// the warp size is 32, and there are always at most 32 tcs threads.
bb->remove(i);
} else
if (i->op == OP_LOAD && i->subOp == NV50_IR_SUBOP_LDC_IS) {
int offset = i->src(0).get()->reg.data.offset;
if (abs(offset) > 0x10000)
i->src(0).get()->reg.fileIndex += offset >> 16;
i->src(0).get()->reg.data.offset = (int)(short)offset;
} else {
// TODO: Move this to before register allocation for operations that
// need the $c register !

View file

@ -192,7 +192,7 @@ public:
virtual bool insnCanLoad(const Instruction *insn, int s,
const Instruction *ld) const = 0;
virtual bool insnCanLoadOffset(const Instruction *insn, int s,
int offset) const { return true; }
int offset) const = 0;
virtual bool isOpSupported(operation, DataType) const = 0;
virtual bool isAccessSupported(DataFile, DataType) const = 0;
virtual bool isModSupported(const Instruction *,

View file

@ -383,6 +383,16 @@ TargetNVC0::insnCanLoad(const Instruction *i, int s,
return true;
}
bool
TargetNVC0::insnCanLoadOffset(const Instruction *insn, int s, int offset) const
{
const ValueRef& ref = insn->src(s);
if (ref.getFile() == FILE_MEMORY_CONST &&
(insn->op != OP_LOAD || insn->subOp != NV50_IR_SUBOP_LDC_IS))
return offset >= -0x8000 && offset < 0x8000;
return true;
}
bool
TargetNVC0::isAccessSupported(DataFile file, DataType ty) const
{

View file

@ -48,6 +48,8 @@ public:
virtual bool insnCanLoad(const Instruction *insn, int s,
const Instruction *ld) const;
virtual bool insnCanLoadOffset(const Instruction *insn, int s,
int offset) const;
virtual bool isOpSupported(operation, DataType) const;
virtual bool isAccessSupported(DataFile, DataType) const;
virtual bool isModSupported(const Instruction *, int s, Modifier) const;