summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2017-10-20 11:36:42 -0700
committerBrian Sullivan <briansul@microsoft.com>2017-10-20 11:36:42 -0700
commitfb789966c8ef538001f2f6c90bc156637e863d74 (patch)
tree15422fb235bddf117aff3cd9f903932ab2f22ed4
parentae991c3a6042256c25d6c82e2714cd41eb14798a (diff)
downloadcoreclr-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.hpp19
-rw-r--r--src/jit/gentree.cpp30
-rw-r--r--src/jit/gentree.h1
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)