diff options
author | Joseph Tremoulet <jotrem@microsoft.com> | 2016-10-26 17:01:57 -0400 |
---|---|---|
committer | Joseph Tremoulet <jotrem@microsoft.com> | 2016-11-04 14:57:20 -0400 |
commit | 86d4d5999267b687be6c404a3a998a9499f7a57f (patch) | |
tree | e02f1e1ec215ee25e6ee2e88cf6029bcc8541085 /src | |
parent | 7f6a791f35c2b03fe71853dc4c4b4633e82a8492 (diff) | |
download | coreclr-86d4d5999267b687be6c404a3a998a9499f7a57f.tar.gz coreclr-86d4d5999267b687be6c404a3a998a9499f7a57f.tar.bz2 coreclr-86d4d5999267b687be6c404a3a998a9499f7a57f.zip |
Clear *_ASG_LHS flags in ResetOptAnnotations
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/compiler.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 104c90de74..74ba9f0e31 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -4650,6 +4650,21 @@ void Compiler::ResetOptAnnotations() 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; + } } } } |