+/**
+ * Return true if the memory accessed by a LOAD or STORE instruction is
+ * read-only or write-only, respectively.
+ *
+ * \param shader_buffers_reverse_access_mask
+ * For LOAD, set this to (store | atomic) slot usage in the shader.
+ * For STORE, set this to (load | atomic) slot usage in the shader.
+ * \param images_reverse_access_mask Same as above, but for images.
+ */
+static bool is_oneway_access_only(const struct tgsi_full_instruction *inst,
+ const struct tgsi_shader_info *info,
+ unsigned shader_buffers_reverse_access_mask,
+ unsigned images_reverse_access_mask)
+{
+ /* RESTRICT means NOALIAS.
+ * If there are no writes, we can assume the accessed memory is read-only.
+ * If there are no reads, we can assume the accessed memory is write-only.
+ */
+ if (inst->Memory.Qualifier & TGSI_MEMORY_RESTRICT) {
+ unsigned reverse_access_mask;
+
+ if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
+ reverse_access_mask = shader_buffers_reverse_access_mask;
+ } else if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
+ reverse_access_mask = info->images_buffers &
+ images_reverse_access_mask;
+ } else {
+ reverse_access_mask = ~info->images_buffers &
+ images_reverse_access_mask;
+ }
+
+ if (inst->Src[0].Register.Indirect) {
+ if (!reverse_access_mask)
+ return true;
+ } else {
+ if (!(reverse_access_mask &
+ (1u << inst->Src[0].Register.Index)))
+ return true;
+ }
+ }
+
+ /* If there are no buffer writes (for both shader buffers & image
+ * buffers), it implies that buffer memory is read-only.
+ * If there are no buffer reads (for both shader buffers & image
+ * buffers), it implies that buffer memory is write-only.
+ *
+ * Same for the case when there are no writes/reads for non-buffer
+ * images.
+ */
+ if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
+ (inst->Src[0].Register.File == TGSI_FILE_IMAGE &&
+ inst->Memory.Texture == TGSI_TEXTURE_BUFFER)) {
+ if (!shader_buffers_reverse_access_mask &&
+ !(info->images_buffers & images_reverse_access_mask))
+ return true;
+ } else {
+ if (!(~info->images_buffers & images_reverse_access_mask))
+ return true;
+ }
+ return false;
+}
+