Clear *_ASG_LHS flags in ResetOptAnnotations
authorJoseph Tremoulet <jotrem@microsoft.com>
Wed, 26 Oct 2016 21:01:57 +0000 (17:01 -0400)
committerJoseph Tremoulet <jotrem@microsoft.com>
Fri, 4 Nov 2016 18:57:20 +0000 (14:57 -0400)
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.

src/jit/compiler.cpp

index 104c90de74882b436786ad0b95427c491e552ce3..74ba9f0e311b378798e1713a5ddb29cb23d456a0 100644 (file)
@@ -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;
+                }
             }
         }
     }