summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-09-01 22:30:53 -0700
committerJason Ekstrand <[email protected]>2017-11-07 10:37:52 -0800
commitb67230de635528bfc6d5e66b90f7406eb97eb1c0 (patch)
tree3b7de1ef38673cf9450e411a5e69fa8227399255
parentaa4ff4b98c93b6870fd3f4ae9dae8aae350b0476 (diff)
intel/fs: Protect opt_algebraic from OOB BROADCAST indices
Reviewed-by: Iago Toral Quiroga <[email protected]>
-rw-r--r--src/intel/compiler/brw_fs.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp
index fdbc6dbd0ea..c2907bf40b0 100644
--- a/src/intel/compiler/brw_fs.cpp
+++ b/src/intel/compiler/brw_fs.cpp
@@ -2423,8 +2423,17 @@ fs_visitor::opt_algebraic()
progress = true;
} else if (inst->src[1].file == IMM) {
inst->opcode = BRW_OPCODE_MOV;
- inst->src[0] = component(inst->src[0],
- inst->src[1].ud);
+ /* It's possible that the selected component will be too large and
+ * overflow the register. This can happen if someone does a
+ * readInvocation() from GLSL or SPIR-V and provides an OOB
+ * invocationIndex. If this happens and we some how manage
+ * to constant fold it in and get here, then component() may cause
+ * us to start reading outside of the VGRF which will lead to an
+ * assert later. Instead, just let it wrap around if it goes over
+ * exec_size.
+ */
+ const unsigned comp = inst->src[1].ud & (inst->exec_size - 1);
+ inst->src[0] = component(inst->src[0], comp);
inst->sources = 1;
inst->force_writemask_all = true;
progress = true;