gollvm: fold deref(addr(X)) => X
The existing implementation folds addr(deref(X)) => X only. This
change makes it also work the opposite way.
Updates golang/go#51648
Change-Id: Idc1996d431827fb2c410e4d9fdd99625c1d2dfa6
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/393295
Trust: Eli Benderskyā€ˇ <eliben@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/bridge/go-llvm-materialize.cpp b/bridge/go-llvm-materialize.cpp
index 49aaad3..8e89288 100644
--- a/bridge/go-llvm-materialize.cpp
+++ b/bridge/go-llvm-materialize.cpp
@@ -1942,7 +1942,7 @@
if (expr && expr->value())
return std::make_pair(ContinueWalk, node);
- // Fold addr(deref(X)) => X
+ // Fold addr(deref(X)) and deref(addr(X)) => X
if (node->flavor() == N_Address) {
std::vector<Bexpression *> akids = expr->getChildExprs();
if (akids[0]->flavor() == N_Deref) {
@@ -1959,6 +1959,22 @@
// Return result
expr = dkids[0];
}
+ } else if (node->flavor() == N_Deref) {
+ std::vector<Bexpression *> dkids = expr->getChildExprs();
+ if (dkids[0]->flavor() == N_Address) {
+ Bexpression *address = dkids[0];
+
+ // Extract children and delete first the deref node, then the
+ // addr node. Order is important; if we delete the addr first
+ // then the integrity visitor will wind up trying to access the
+ // deleted addr.
+ be_->nodeBuilder().extractChildenAndDestroy(expr);
+ std::vector<Bexpression *> akids =
+ be_->nodeBuilder().extractChildenAndDestroy(address);
+
+ // Return result
+ expr = akids[0];
+ }
}
return std::make_pair(ContinueWalk, expr);
}