compiler: load LHS subexpressions of op= assignment only once

Fixes golang/go#52811

Change-Id: I369415d1188a483cba81257fdfbb0e5c1a7df1c4
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/405617
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/go/statements.cc b/go/statements.cc
index 95fa3c4..b3db843 100644
--- a/go/statements.cc
+++ b/go/statements.cc
@@ -1260,6 +1260,16 @@
   Move_ordered_evals moe(b);
   this->lhs_->traverse_subexpressions(&moe);
 
+  // We can still be left with subexpressions that have to be loaded
+  // even if they don't have side effects themselves, in case the RHS
+  // changes variables named on the LHS.
+  int i;
+  if (this->lhs_->must_eval_subexpressions_in_order(&i))
+    {
+      Move_subexpressions ms(i, b);
+      this->lhs_->traverse_subexpressions(&ms);
+    }
+
   Expression* lval = this->lhs_->copy();
 
   Operator op;