stg_floatToWord32zh: zero-extend the Word32 (#16617)
authorKevin Buhr <buhr@asaurus.net>
Wed, 1 May 2019 22:13:33 +0000 (17:13 -0500)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Wed, 8 May 2019 19:35:13 +0000 (15:35 -0400)
The primop stgFloatToWord32 was sign-extending the 32-bit word, resulting
in weird negative Word32s.  Zero-extend them instead.

Closes #16617.

includes/Cmm.h
libraries/base/cbits/CastFloatWord.cmm
testsuite/tests/codeGen/should_run/T16617.hs [new file with mode: 0644]
testsuite/tests/codeGen/should_run/T16617.stdout [new file with mode: 0644]
testsuite/tests/codeGen/should_run/all.T

index ba84328..99f5233 100644 (file)
 #define BYTES_TO_WDS(n) ((n) / SIZEOF_W)
 #define ROUNDUP_BYTES_TO_WDS(n) (((n) + SIZEOF_W - 1) / SIZEOF_W)
 
-/* TO_W_(n) converts n to W_ type from a smaller type */
+/*
+ * TO_W_(n) and TO_ZXW_(n) convert n to W_ type from a smaller type,
+ * with and without sign extension respectively
+ */
 #if SIZEOF_W == 4
 #define TO_I64(x) %sx64(x)
 #define TO_W_(x) %sx32(x)
+#define TO_ZXW_(x) %zx32(x)
 #define HALF_W_(x) %lobits16(x)
 #elif SIZEOF_W == 8
 #define TO_I64(x) (x)
 #define TO_W_(x) %sx64(x)
+#define TO_ZXW_(x) %zx64(x)
 #define HALF_W_(x) %lobits32(x)
 #endif
 
index 18d275f..2edb006 100644 (file)
@@ -61,7 +61,8 @@ stg_floatToWord32zh(F_ f)
 
     reserve 1 = ptr {
         F_[ptr] = f;
-        w = TO_W_(I32[ptr]);
+        // Fix #16617: use zero-extending (TO_ZXW_) here
+        w = TO_ZXW_(I32[ptr]);
     }
 
     return (w);
diff --git a/testsuite/tests/codeGen/should_run/T16617.hs b/testsuite/tests/codeGen/should_run/T16617.hs
new file mode 100644 (file)
index 0000000..49e5e74
--- /dev/null
@@ -0,0 +1,10 @@
+import GHC.Float
+
+main :: IO ()
+main = do
+  -- As per #16617, Word32s should be non-negative
+  print $ castFloatToWord32 (-1)
+  print $ toInteger (castFloatToWord32 (-1)) > 0
+  -- For completeness, so should Word64s
+  print $ castDoubleToWord64 (-1)
+  print $ toInteger (castDoubleToWord64 (-1)) > 0
diff --git a/testsuite/tests/codeGen/should_run/T16617.stdout b/testsuite/tests/codeGen/should_run/T16617.stdout
new file mode 100644 (file)
index 0000000..3a0c8ec
--- /dev/null
@@ -0,0 +1,4 @@
+3212836864
+True
+13830554455654793216
+True
index 189fb72..6b4d772 100644 (file)
@@ -194,3 +194,4 @@ test('T15892',
         # happen, so -G1 -A32k:
         extra_run_opts('+RTS -G1 -A32k -RTS') ],
      compile_and_run, ['-O'])
+test('T16617', normal, compile_and_run, [''])