diff options
author | SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> | 2021-07-13 11:35:10 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-13 11:35:10 +0300 |
commit | b744e1f0bdd6aedf9908ff53acf0ff163be6d20f (patch) | |
tree | 240e2bfc029ed6a7eb99244563c54adfe09ccf1e /src/coreclr | |
parent | fe44d588f241c5b72b3b56768a0dbbb1bea027a7 (diff) |
Fix bad folding (#54722)
* Always sign-extend from int32 in gtFoldExprConst
GT_CNS_INT of TYP_INT on 64 hosts has an implicit contract:
the value returned by IconValue() must "fit" into 32 bit
signed integer, i. e. "static_cast<int>(IconValue()) == IconValue()".
gtFoldExprConst was failing to uphold this contract when the target
was 32 bit and the host was 64 bit.
Fix this by always truncating before calling SetIconValue().
* Add a simple test that reproduces bad codegen
Diffstat (limited to 'src/coreclr')
-rw-r--r-- | src/coreclr/jit/gentree.cpp | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 277cd53e1c1..7f16e6cd400 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -14856,19 +14856,15 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree) JITDUMP("\nFolding operator with constant nodes into a constant:\n"); DISPTREE(tree); -#ifdef TARGET_64BIT - // Some operations are performed as 64 bit instead of 32 bit so the upper 32 bits - // need to be discarded. Since constant values are stored as ssize_t and the node - // has TYP_INT the result needs to be sign extended rather than zero extended. - i1 = INT32(i1); -#endif // TARGET_64BIT - // Also all conditional folding jumps here since the node hanging from // GT_JTRUE has to be a GT_CNS_INT - value 0 or 1. tree->ChangeOperConst(GT_CNS_INT); tree->ChangeType(TYP_INT); - tree->AsIntCon()->SetIconValue(i1); + // Some operations are performed as 64 bit instead of 32 bit so the upper 32 bits + // need to be discarded. Since constant values are stored as ssize_t and the node + // has TYP_INT the result needs to be sign extended rather than zero extended. + tree->AsIntCon()->SetIconValue(static_cast<int>(i1)); tree->AsIntCon()->gtFieldSeq = fieldSeq; if (vnStore != nullptr) { |