summaryrefslogtreecommitdiff
path: root/src/amd
diff options
context:
space:
mode:
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>2019-12-10 17:46:26 +0100
committerDylan Baker <dylan@pnwbakers.com>2019-12-12 09:22:54 -0800
commit3a58a73661ffac7d4cff458dd017d74d3cf588d3 (patch)
treec8de178f9e6a7a4be63e371a3863a049dabad5a0 /src/amd
parent1452cf672cc2489763738e943d60680dee876e38 (diff)
downloadmesa-3a58a73661ffac7d4cff458dd017d74d3cf588d3.tar.gz
ac/nir: fix out-of-bound access when loading constants from global
Global load/store instructions can't know if the offset is out-of-bound because they don't use descriptors (no range). Fix this by clamping the offset for arrays that are indexed with a non-constant offset that's greater or equal to the array size. This fixes VM faults and GPU hangs with Dead Rising 4. Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/2148 Fixes: 71a67942003 ("ac/nir: Enable nir_opt_large_constants") Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> (cherry picked from commit a0f1a5fa051786c16de6f0062771051f8565daec)
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/llvm/ac_nir_to_llvm.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c
index 3d758759af7..fe3883a0c2b 100644
--- a/src/amd/llvm/ac_nir_to_llvm.c
+++ b/src/amd/llvm/ac_nir_to_llvm.c
@@ -3713,11 +3713,21 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
break;
}
case nir_intrinsic_load_constant: {
+ unsigned base = nir_intrinsic_base(instr);
+ unsigned range = nir_intrinsic_range(instr);
+
LLVMValueRef offset = get_src(ctx, instr->src[0]);
- LLVMValueRef base = LLVMConstInt(ctx->ac.i32,
- nir_intrinsic_base(instr),
- false);
- offset = LLVMBuildAdd(ctx->ac.builder, offset, base, "");
+ offset = LLVMBuildAdd(ctx->ac.builder, offset,
+ LLVMConstInt(ctx->ac.i32, base, false), "");
+
+ /* Clamp the offset to avoid out-of-bound access because global
+ * instructions can't handle them.
+ */
+ LLVMValueRef size = LLVMConstInt(ctx->ac.i32, base + range, false);
+ LLVMValueRef cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntULT,
+ offset, size, "");
+ offset = LLVMBuildSelect(ctx->ac.builder, cond, offset, size, "");
+
LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->constant_data,
offset);
LLVMTypeRef comp_type =