if (!deref->array->type->is_vector())
return ir_rvalue_enter_visitor::visit_enter(ir);
+ /* SSBOs and shared variables are backed by memory and may be accessed by
+ * multiple threads simultaneously. It's not safe to lower a single
+ * component store to a load-vec-store because it may race with writes to
+ * other components.
+ */
+ ir_variable *var = deref->variable_referenced();
+ if (var->data.mode == ir_var_shader_storage ||
+ var->data.mode == ir_var_shader_shared)
+ return ir_rvalue_enter_visitor::visit_enter(ir);
+
ir_rvalue *const new_lhs = deref->array;
void *mem_ctx = ralloc_parent(ir);
if (!deref->array->type->is_vector())
return;
+ /* Back-ends need to be able to handle derefs on vectors for SSBOs, UBOs,
+ * and shared variables. They have to handle it for writes anyway so we
+ * may as well require it for reads.
+ */
+ ir_variable *var = deref->variable_referenced();
+ if (var && (var->data.mode == ir_var_shader_storage ||
+ var->data.mode == ir_var_shader_shared ||
+ (var->data.mode == ir_var_uniform &&
+ var->get_interface_type())))
+ return;
+
void *mem_ctx = ralloc_parent(deref);
*rv = new(mem_ctx) ir_expression(ir_binop_vector_extract,
deref->array,