[MLton-commit] r7224

Wesley Terpstra wesley at mlton.org
Mon Sep 14 13:05:32 PDT 2009


The applyPrim function incorrectly optimized rol/ror.
Here is an example of the problem:

fun id 0w0 = 0w0
  | id x = id (x - 0w1) + 0w1

val x = valOf (Word64.fromString "1234567890abcdef")
val y = MLton.Word64.ror (x, id 0w32)
val z = MLton.Word64.ror (x, 0w32)

val () = print (Word64.toString y ^ "\n")
val () = print (Word64.toString z ^ "\n")

Output:
1234567890ABCDEF
90ABCDEF12345678

Expected output:
90ABCDEF12345678
90ABCDEF12345678

The problem stems from confusing the wordsize of the left and right arguments.

The optimization should check if the rol/ror is a multiple of the left 
wordsize, replacing the rol/ror by identity. However, as it incorrectly took
the right wordsize, a shift by 32 was considered identity for a 64 bit value.


----------------------------------------------------------------------

U   mlton/trunk/mlton/atoms/prim.fun

----------------------------------------------------------------------

Modified: mlton/trunk/mlton/atoms/prim.fun
===================================================================
--- mlton/trunk/mlton/atoms/prim.fun	2009-09-05 11:39:52 UTC (rev 7223)
+++ mlton/trunk/mlton/atoms/prim.fun	2009-09-14 20:05:31 UTC (rev 7224)
@@ -1861,23 +1861,19 @@
                                 then Var x
                              else Apply (neg s, [x])
                      else Unknown
-                  fun ro () =
+                  fun ro s =
                      if inOrder
                         then
-                           let
-                              val s = WordX.size w
-                           in
-                              if WordX.isZero
-                                 (WordX.rem
-                                  (w,
-                                   WordX.fromIntInf
-                                   (IntInf.fromInt
-                                    (Bits.toInt (WordSize.bits s)),
-                                    s),
-                                   {signed = false}))
-                                 then Var x
-                              else Unknown
-                           end
+                           if WordX.isZero
+                              (WordX.rem
+                               (w,
+                                WordX.fromIntInf
+                                (IntInf.fromInt
+                                 (Bits.toInt (WordSize.bits s)),
+                                 WordX.size w),
+                                {signed = false}))
+                              then Var x
+                           else Unknown
                      else
                         if WordX.isZero w orelse WordX.isAllOnes w
                            then word w
@@ -1944,8 +1940,8 @@
                                     orelse signed andalso WordX.isNegOne w)
                            then zero s
                         else Unknown
-                   | Word_rol _ => ro ()
-                   | Word_ror _ => ro ()
+                   | Word_rol s => ro s
+                   | Word_ror s => ro s
                    | Word_rshift (s, {signed}) =>
                         if signed
                            then




More information about the MLton-commit mailing list