diff options
author | Mike Danes <onemihaid@hotmail.com> | 2018-01-20 14:08:37 +0200 |
---|---|---|
committer | Mike Danes <onemihaid@hotmail.com> | 2018-01-20 14:08:37 +0200 |
commit | ca397e5f57a649ad3bcc621cbb02354670f87a08 (patch) | |
tree | 4a494f97f3fdf53603483950aa61dd103dc62a8d /src/vm/jithelpers.cpp | |
parent | c7c2869ca0def15c25b8043ac78a378e0145bac8 (diff) | |
download | coreclr-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.cpp | 4 |
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_ |