This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libgo patch committed: Return random number of hash of NaN


It is valid to store a NaN in a Go hash table.  However, the result can
not be looked up, because NaN never equals NaN.  The only way to see the
result is to range over the map.  This means that the hash code used for
a NaN is irrelevant.  In general it's better to not hash all NaN values
to the same bucket, so this patch simply uses a random number.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline and 4.7 branch.

Ian

diff -r 895a5e834a7b libgo/runtime/go-type-complex.c
--- a/libgo/runtime/go-type-complex.c	Fri Sep 21 23:01:55 2012 -0700
+++ b/libgo/runtime/go-type-complex.c	Fri Sep 21 23:03:04 2012 -0700
@@ -32,10 +32,14 @@
       cf = ucf.cf;
       cfr = __builtin_crealf (cf);
       cfi = __builtin_cimagf (cf);
-      if (__builtin_isinff (cfr) || __builtin_isinff (cfi)
-	  || __builtin_isnanf (cfr) || __builtin_isnanf (cfi))
+      if (__builtin_isinff (cfr) || __builtin_isinff (cfi))
 	return 0;
 
+      /* NaN != NaN, so the hash code of a NaN is irrelevant.  Make it
+	 random so that not all NaNs wind up in the same place.  */
+      if (__builtin_isnanf (cfr) || __builtin_isnanf (cfi))
+	return runtime_fastrand1 ();
+
       /* Avoid negative zero.  */
       if (cfr == 0 && cfi == 0)
 	return 0;
@@ -62,10 +66,12 @@
       cd = ucd.cd;
       cdr = __builtin_crealf (cd);
       cdi = __builtin_cimagf (cd);
-      if (__builtin_isinf (cdr) || __builtin_isinf (cdi)
-	  || __builtin_isnan (cdr) || __builtin_isnan (cdi))
+      if (__builtin_isinf (cdr) || __builtin_isinf (cdi))
 	return 0;
 
+      if (__builtin_isnan (cdr) || __builtin_isnan (cdi))
+	return runtime_fastrand1 ();
+
       /* Avoid negative zero.  */
       if (cdr == 0 && cdi == 0)
 	return 0;
diff -r 895a5e834a7b libgo/runtime/go-type-float.c
--- a/libgo/runtime/go-type-float.c	Fri Sep 21 23:01:55 2012 -0700
+++ b/libgo/runtime/go-type-float.c	Fri Sep 21 23:03:04 2012 -0700
@@ -29,8 +29,14 @@
 
       __builtin_memcpy (uf.a, vkey, 4);
       f = uf.f;
-      if (__builtin_isinff (f) || __builtin_isnanf (f) || f == 0)
+      if (__builtin_isinff (f) || f == 0)
 	return 0;
+
+      /* NaN != NaN, so the hash code of a NaN is irrelevant.  Make it
+	 random so that not all NaNs wind up in the same place.  */
+      if (__builtin_isnanf (f))
+	return runtime_fastrand1 ();
+
       return (uintptr_t) uf.si;
     }
   else if (key_size == 8)
@@ -45,8 +51,12 @@
 
       __builtin_memcpy (ud.a, vkey, 8);
       d = ud.d;
-      if (__builtin_isinf (d) || __builtin_isnan (d) || d == 0)
+      if (__builtin_isinf (d) || d == 0)
 	return 0;
+
+      if (__builtin_isnan (d))
+	return runtime_fastrand1 ();
+
       return (uintptr_t) ud.di;
     }
   else

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]