diff options
author | Eugene Rozenfeld <erozen@microsoft.com> | 2018-08-01 15:48:41 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-01 15:48:41 -0700 |
commit | fd4bd60a0b405126f0d7954861bbbc2504192bd4 (patch) | |
tree | a93e8ab6d6215e0aa66dd0506b048614ca5b9d97 /src/jit | |
parent | c4c16723a83c995838508ed7bca7fb99687f6d40 (diff) | |
download | coreclr-fd4bd60a0b405126f0d7954861bbbc2504192bd4.tar.gz coreclr-fd4bd60a0b405126f0d7954861bbbc2504192bd4.tar.bz2 coreclr-fd4bd60a0b405126f0d7954861bbbc2504192bd4.zip |
Fix value number update in fgMorphCast. (#19226)
removing GT_CAST nodes. It caused a problem for cases
where GT_CAST operand is a constant (e.g., GT_CNS_INT). In these
cases the value number shouldn't change since there is an
assumption that constant nodes have known constant value numbers.
The bug was found by ILGEN, I created a corresponding C# repro.
Without the fix this assert fires: https://github.com/dotnet/coreclr/blob/1f28125ad1f9975fbe68dd6839908aa6e63fc43b#gitext://gotocommit/1f28125ad1f9975fbe68dd6839908aa6e63fc43b/src/jit/assertionprop.cpp#L2687
The fix is to update value numbers only when we changed the operand of GT_CAST and
value number wasn't updated otherwise (e.g., in optNarrowTree).
I verified no x64 diffs in
jit-diff diff --pmi --tests --frameworks
(with pri0 and pri1 tests).
Diffstat (limited to 'src/jit')
-rw-r--r-- | src/jit/morph.cpp | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 9b642c2ddf..438123add9 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -600,6 +600,10 @@ OPTIMIZECAST: case GT_LCL_FLD: case GT_ARR_ELEM: oper->gtType = dstType; + // We're changing the type here so we need to update the VN; + // in other cases we discard the cast without modifying oper + // so the VN doesn't change. + oper->SetVNsFromNode(tree); goto REMOVE_CAST; default: break; @@ -753,8 +757,6 @@ OPTIMIZECAST: return tree; REMOVE_CAST: - oper->SetVNsFromNode(tree); - /* Here we've eliminated the cast, so just return it's operand */ assert(!gtIsActiveCSE_Candidate(tree)); // tree cannot be a CSE candidate |