summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-01-11 16:41:18 -0500
committerIlia Mirkin <[email protected]>2016-01-14 18:20:27 -0500
commit37b67db6ae34fb6586d640a7a1b6232f091dd812 (patch)
tree5c1f64182d04ddaf470ac755f2dd87b7c8d8bd56
parent7a521ddf36b3d1f7b81604341fcda26c60809c9b (diff)
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 <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp6
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target.h2
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp10
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.h2
4 files changed, 19 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index 6530078b938..dc1ab769b98 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -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 !
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
index 673f8811ff3..e6e1912adae 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
@@ -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 *,
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
index 014c652eede..a03afa8dc8d 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
@@ -384,6 +384,16 @@ TargetNVC0::insnCanLoad(const Instruction *i, int s,
}
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
{
if (ty == TYPE_NONE)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.h
index 3c5c7480405..7d11cd96315 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.h
@@ -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;