summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-05-15 15:35:04 -0400
committerIlia Mirkin <[email protected]>2016-05-17 01:27:29 -0400
commitb1d74e9486d7233412e4aa7bc07a1efbb72e768e (patch)
tree4a0eeb9ad142cdba98fbbd2944e9846c0f44f11b /src/gallium
parent4fb4fd0b6b1fe8387dc4c9154359f890d379e9cd (diff)
nvc0/ir: make sure out-of-bounds buffer loads/atomics get a 0 result
Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp27
1 files changed, 26 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 869b06c2b4c..5e5eacb9824 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -1328,6 +1328,25 @@ NVC0LoweringPass::handleATOM(Instruction *atom)
assert(base->reg.size == 8);
atom->setIndirect(0, 0, base);
atom->getSrc(0)->reg.file = FILE_MEMORY_GLOBAL;
+
+ // Harden against out-of-bounds accesses
+ Value *offset = bld.loadImm(NULL, atom->getSrc(0)->reg.data.offset + typeSizeof(atom->sType));
+ Value *length = loadBufLength32(ind, atom->getSrc(0)->reg.fileIndex * 16);
+ Value *pred = new_LValue(func, FILE_PREDICATE);
+ if (ptr)
+ bld.mkOp2(OP_ADD, TYPE_U32, offset, offset, ptr);
+ bld.mkCmp(OP_SET, CC_GT, TYPE_U32, pred, TYPE_U32, offset, length);
+ atom->setPredicate(CC_NOT_P, pred);
+ if (atom->defExists(0)) {
+ Value *zero, *dst = atom->getDef(0);
+ atom->setDef(0, bld.getSSA());
+
+ bld.setPosition(atom, true);
+ bld.mkMov((zero = bld.getSSA()), bld.mkImm(0))
+ ->setPredicate(CC_P, pred);
+ bld.mkOp2(OP_UNION, TYPE_U32, dst, atom->getDef(0), zero);
+ }
+
return true;
}
base =
@@ -2107,7 +2126,13 @@ NVC0LoweringPass::handleLDST(Instruction *i)
bld.mkCmp(OP_SET, CC_GT, TYPE_U32, pred, TYPE_U32, offset, length);
i->setPredicate(CC_NOT_P, pred);
if (i->defExists(0)) {
- bld.mkMov(i->getDef(0), bld.mkImm(0));
+ Value *zero, *dst = i->getDef(0);
+ i->setDef(0, bld.getSSA());
+
+ bld.setPosition(i, true);
+ bld.mkMov((zero = bld.getSSA()), bld.mkImm(0))
+ ->setPredicate(CC_P, pred);
+ bld.mkOp2(OP_UNION, TYPE_U32, dst, i->getDef(0), zero);
}
}
}