tint: Implement sem::Load

The resolver now wraps sem::Expression objects with a sem::Load object
anywhere that the load rule is invoked. sem::Expression provides an
`UnwrapLoad()` method that returns the inner expression (or
passthrough, if no load is present), which is analaguous to
Type::UnwrapRef().

The logic for alias analysis in `RegisterLoadIfNeeded` has been folded
into the new `Resolver::Load` method.

Fixed up many transforms and tests. The only difference in output is
for a single SPIR-V backend test, where some IDs have changed due to
slight re-ordering of when expressions are generated.

There may be further clean-ups possible (e.g. removing unnecessary
calls to `UnwrapRef`, and simplifying places in the SPIR-V writer or
transforms that deal with memory accesses), but these can be addressed
in future patches.

Fixed: tint:1654
Change-Id: I69adecfe9251faae46546b64d0cdc29eea26cd4e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99706
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
index 6b55e5d..2471b89 100644
--- a/src/tint/transform/spirv_atomic.cc
+++ b/src/tint/transform/spirv_atomic.cc
@@ -164,7 +164,7 @@
     void ProcessAtomicExpressions() {
         for (size_t i = 0; i < atomic_expressions.Length(); i++) {
             Switch(
-                atomic_expressions[i],  //
+                atomic_expressions[i]->UnwrapLoad(),  //
                 [&](const sem::VariableUser* user) {
                     auto* v = user->Variable()->Declaration();
                     if (v->type && atomic_variables.emplace(user->Variable()).second) {
@@ -262,7 +262,7 @@
                         }
 
                         auto sem_rhs = ctx.src->Sem().Get(assign->rhs);
-                        if (is_ref_to_atomic_var(sem_rhs)) {
+                        if (is_ref_to_atomic_var(sem_rhs->UnwrapLoad())) {
                             ctx.Replace(assign->rhs, [=] {
                                 auto* rhs = ctx.CloneWithoutTransform(assign->rhs);
                                 return b.Call(sem::str(sem::BuiltinType::kAtomicLoad),
@@ -274,7 +274,7 @@
                     [&](const ast::VariableDeclStatement* decl) {
                         auto* var = decl->variable;
                         if (auto* sem_init = ctx.src->Sem().Get(var->initializer)) {
-                            if (is_ref_to_atomic_var(sem_init)) {
+                            if (is_ref_to_atomic_var(sem_init->UnwrapLoad())) {
                                 ctx.Replace(var->initializer, [=] {
                                     auto* rhs = ctx.CloneWithoutTransform(var->initializer);
                                     return b.Call(sem::str(sem::BuiltinType::kAtomicLoad),