summaryrefslogtreecommitdiff
path: root/src/vm/jithelpers.cpp
diff options
context:
space:
mode:
authorMike Danes <onemihaid@hotmail.com>2018-01-20 14:08:37 +0200
committerMike Danes <onemihaid@hotmail.com>2018-01-20 14:08:37 +0200
commitca397e5f57a649ad3bcc621cbb02354670f87a08 (patch)
tree4a494f97f3fdf53603483950aa61dd103dc62a8d /src/vm/jithelpers.cpp
parentc7c2869ca0def15c25b8043ac78a378e0145bac8 (diff)
downloadcoreclr-ca397e5f57a649ad3bcc621cbb02354670f87a08.tar.gz
coreclr-ca397e5f57a649ad3bcc621cbb02354670f87a08.tar.bz2
coreclr-ca397e5f57a649ad3bcc621cbb02354670f87a08.zip
Fix 64 bit shift inconsistencies (on 32 bit targets)
Recent shift changes made the JIT_LLsh helper mask the shift count to 6 bits. The other 2 helpers (JIT_LRsh and JIT_LRsz) so now we get inconsistencies such as `(x >> 64) != (x << 64)`. The ECMA spec says that "the return value is unspecified if shiftAmount is greater than or equal to the width of value" so the JIT has no obligation to implement a particular behavior. But it seems preferable to have all shift instructions behave similarly, it avoids complications and reduces risks. This also changes `ValueNumStore::EvalOpIntegral` to mask the shift count for 64 bit shifts so it matches `gtFoldExprConst`. Otherwise the produced value depends on the C/C++ compiler's behavior.
Diffstat (limited to 'src/vm/jithelpers.cpp')
-rw-r--r--src/vm/jithelpers.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 9f887e6616..e3d93d21df 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -464,7 +464,7 @@ HCIMPLEND
HCIMPL2_VV(INT64, JIT_LRsh, INT64 num, int shift)
{
FCALL_CONTRACT;
- return num >> shift;
+ return num >> (shift & 0x3F);
}
HCIMPLEND
@@ -472,7 +472,7 @@ HCIMPLEND
HCIMPL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift)
{
FCALL_CONTRACT;
- return num >> shift;
+ return num >> (shift & 0x3F);
}
HCIMPLEND
#endif // !BIT64 && !_TARGET_X86_