summaryrefslogtreecommitdiffstats
path: root/src/amd/common/ac_llvm_build.c
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2018-03-28 23:54:40 +0200
committerBas Nieuwenhuizen <[email protected]>2018-03-29 00:03:03 +0200
commit4503ff760c794c3bb15b978a47c530037d56498e (patch)
treedfff19da4d0e66103c33a95da776a9b41b945d62 /src/amd/common/ac_llvm_build.c
parent4f96747530be799e3ccd84ccf48df6d7fdbd0a03 (diff)
ac/nir: Add workaround for GFX9 buffer views.
On GFX9 whether the buffer size is interpreted as elements or bytes depends on whether IDXEN is enabled in the instruction. If the index is a constant zero, LLVM optimizes IDXEN to 0. Now the size in elements is interpreted in bytes which of course results in out of bounds accesses. The correct fix is most likely to disable the LLVM optimization, but we need something to work with LLVM <= 6.0. radeonsi does the max between stride and element count on the CPU but that results in the size intrinsics returning the wrong size for the buffer. This would cause CTS errors for radv. v2: Also include the store changes. Fixes: e38685cc62e 'Revert "radv: disable support for VEGA for now."' Reviewed-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src/amd/common/ac_llvm_build.c')
-rw-r--r--src/amd/common/ac_llvm_build.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 1ae2b9dd170..6f577cdac7f 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -1082,6 +1082,30 @@ LLVMValueRef ac_build_buffer_load_format(struct ac_llvm_context *ctx,
can_speculate, true);
}
+LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx,
+ LLVMValueRef rsrc,
+ LLVMValueRef vindex,
+ LLVMValueRef voffset,
+ unsigned num_channels,
+ bool glc,
+ bool can_speculate)
+{
+ LLVMValueRef elem_count = LLVMBuildExtractElement(ctx->builder, rsrc, LLVMConstInt(ctx->i32, 2, 0), "");
+ LLVMValueRef stride = LLVMBuildExtractElement(ctx->builder, rsrc, LLVMConstInt(ctx->i32, 1, 0), "");
+ stride = LLVMBuildLShr(ctx->builder, stride, LLVMConstInt(ctx->i32, 16, 0), "");
+
+ LLVMValueRef new_elem_count = LLVMBuildSelect(ctx->builder,
+ LLVMBuildICmp(ctx->builder, LLVMIntUGT, elem_count, stride, ""),
+ elem_count, stride, "");
+
+ LLVMValueRef new_rsrc = LLVMBuildInsertElement(ctx->builder, rsrc, new_elem_count,
+ LLVMConstInt(ctx->i32, 2, 0), "");
+
+ return ac_build_buffer_load_common(ctx, new_rsrc, vindex, voffset,
+ num_channels, glc, false,
+ can_speculate, true);
+}
+
/**
* Set range metadata on an instruction. This can only be used on load and
* call instructions. If you know an instruction can only produce the values