diff options
author | Brian Sullivan <briansul@microsoft.com> | 2017-10-20 11:36:42 -0700 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2017-10-20 11:36:42 -0700 |
commit | fb789966c8ef538001f2f6c90bc156637e863d74 (patch) | |
tree | 15422fb235bddf117aff3cd9f903932ab2f22ed4 | |
parent | ae991c3a6042256c25d6c82e2714cd41eb14798a (diff) | |
download | coreclr-fb789966c8ef538001f2f6c90bc156637e863d74.tar.gz coreclr-fb789966c8ef538001f2f6c90bc156637e863d74.tar.bz2 coreclr-fb789966c8ef538001f2f6c90bc156637e863d74.zip |
Fix the gtHashValue to properly hash all the bits when we have a 64-bit item
-rw-r--r-- | src/jit/compiler.hpp | 19 | ||||
-rw-r--r-- | src/jit/gentree.cpp | 30 | ||||
-rw-r--r-- | src/jit/gentree.h | 1 |
3 files changed, 40 insertions, 10 deletions
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp index 9743173f5a..acc7bb688e 100644 --- a/src/jit/compiler.hpp +++ b/src/jit/compiler.hpp @@ -175,12 +175,25 @@ inline BOOL genMaxOneBit(unsigned value) * Given a value that has exactly one bit set, return the position of that * bit, in other words return the logarithm in base 2 of the given value. */ - inline unsigned genLog2(unsigned value) { return BitPosition(value); } +// Given an unsigned 64-bit value, returns the lower 32-bits in unsigned format +// +inline unsigned ulo32(unsigned __int64 value) +{ + return static_cast<unsigned>(value); +} + +// Given an unsigned 64-bit value, returns the upper 32-bits in unsigned format +// +inline unsigned uhi32(unsigned __int64 value) +{ + return static_cast<unsigned>(value >> 32); +} + /***************************************************************************** * * Given a value that has exactly one bit set, return the position of that @@ -189,8 +202,8 @@ inline unsigned genLog2(unsigned value) inline unsigned genLog2(unsigned __int64 value) { - unsigned lo32 = (unsigned)value; - unsigned hi32 = (unsigned)(value >> 32); + unsigned lo32 = ulo32(value); + unsigned hi32 = uhi32(value); if (lo32 != 0) { diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index c199a29772..78837c9f59 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -1885,6 +1885,7 @@ AGAIN: switch (oper) { + UINT64 bits; case GT_LCL_VAR: add = tree->gtLclVar.gtLclNum; break; @@ -1894,16 +1895,26 @@ AGAIN: break; case GT_CNS_INT: - add = (int)tree->gtIntCon.gtIconVal; + add = tree->gtIntCon.gtIconVal; break; case GT_CNS_LNG: - add = (int)tree->gtLngCon.gtLconVal; + bits = (UINT64)tree->gtLngCon.gtLconVal; +#ifdef _TARGET_64BIT_ + add = bits; +#else // 32-bit target + add = genTreeHashAdd(uhi32(bits), ulo32(bits)); +#endif break; case GT_CNS_DBL: - add = (int)tree->gtDblCon.gtDconVal; + bits = *(UINT64*)(&tree->gtDblCon.gtDconVal); +#ifdef _TARGET_64BIT_ + add = bits; +#else // 32-bit target + add = genTreeHashAdd(uhi32(bits), ulo32(bits)); +#endif break; case GT_CNS_STR: - add = (int)tree->gtStrCon.gtSconCPX; + add = tree->gtStrCon.gtSconCPX; break; case GT_JMP: @@ -1915,8 +1926,15 @@ AGAIN: break; } - // narrowing cast, but for hashing. - hash = genTreeHashAdd(hash, (unsigned)add); + // narrow 'add' into a 32-bit 'val' + unsigned val; +#ifdef _TARGET_64BIT_ + val = genTreeHashAdd(uhi32(add), ulo32(add)); +#else // 32-bit target + val = add; +#endif + + hash = genTreeHashAdd(hash, val); goto DONE; } diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 6c915ce429..4c194a45a9 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -2734,7 +2734,6 @@ struct GenTreeLngCon : public GenTreeIntConCommon INT32 HiVal() { return (INT32)(gtLconVal >> 32); - ; } GenTreeLngCon(INT64 val) : GenTreeIntConCommon(GT_CNS_NATIVELONG, TYP_LONG) |