This works around an apparent bug in SSA construction (GitHub issue #7846),
specifically `fgPerNodeLocalVarLiveness`, where heap uses are not
considered upwards-exposed if they follow a heap def in their block (which
is incorrect because the store and load are not necessarily must-alias).
In the non-repeat configuration, these flags are always cleared coming
into SSA construction, because `TreeRenameVariables` is the only thing
that sets them.
tree->ClearVN();
tree->ClearAssertion();
tree->gtCSEnum = NO_CSE;
+
+ // Clear any *_ASG_LHS flags -- these are set during SSA construction,
+ // and the heap live-in calculation depends on them being unset coming
+ // into SSA construction (without clearing them, a block that has a
+ // heap def via one of these before any heap use is treated as not having
+ // an upwards-exposed heap use, even though subsequent heap uses may not
+ // be killed by the store; this seems to be a bug, worked around here).
+ if (tree->OperIsIndir())
+ {
+ tree->gtFlags &= ~GTF_IND_ASG_LHS;
+ }
+ else if (tree->OperGet() == GT_CLS_VAR)
+ {
+ tree->gtFlags &= ~GTF_CLS_VAR_ASG_LHS;
+ }
}
}
}