Skip to content

Commit

Permalink
Implement proper ER-mode comparison for floating point types
Browse files Browse the repository at this point in the history
  • Loading branch information
latkin committed Apr 21, 2015
1 parent 52e6e03 commit a693443
Show file tree
Hide file tree
Showing 2 changed files with 417 additions and 63 deletions.
39 changes: 33 additions & 6 deletions src/fsharp/FSharp.Core/prim-types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1214,8 +1214,14 @@ namespace Microsoft.FSharp.Core
when 'T : uint64 = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : unativeint = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
// Note, these bail out to GenericComparisonWithComparerIntrinsic if called with NaN values, because clt and cgt and ceq all return "false" for that case.
when 'T : float = if (# "clt" x y : bool #) then (-1) else if (# "cgt" x y : bool #) then 1 else if (# "ceq" x y : bool #) then 0 else GenericComparisonWithComparerIntrinsic comp x y
when 'T : float32 = if (# "clt" x y : bool #) then (-1) else if (# "cgt" x y : bool #) then 1 else if (# "ceq" x y : bool #) then 0 else GenericComparisonWithComparerIntrinsic comp x y
when 'T : float = if (# "clt" x y : bool #) then (-1)
elif (# "cgt" x y : bool #) then (1)
elif (# "ceq" x y : bool #) then (0)
else GenericComparisonWithComparerIntrinsic comp x y
when 'T : float32 = if (# "clt" x y : bool #) then (-1)
elif (# "cgt" x y : bool #) then (1)
elif (# "ceq" x y : bool #) then (0)
else GenericComparisonWithComparerIntrinsic comp x y
when 'T : char = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : string =
// NOTE: we don't have to null check here because System.String.CompareOrdinal
Expand Down Expand Up @@ -1284,8 +1290,18 @@ namespace Microsoft.FSharp.Core
when 'T : uint32 = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : uint64 = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : unativeint = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : float = if (# "clt" x y : bool #) then (-1) else (# "cgt" x y : int #)
when 'T : float32 = if (# "clt" x y : bool #) then (-1) else (# "cgt" x y : int #)
when 'T : float = if (# "clt" x y : bool #) then (-1)
elif (# "cgt" x y : bool #) then (1)
elif (# "ceq" x y : bool #) then (0)
elif (# "ceq" x x : bool #) then (1)
elif (# "ceq" y y : bool #) then (-1)
else (0)
when 'T : float32 = if (# "clt" x y : bool #) then (-1)
elif (# "cgt" x y : bool #) then (1)
elif (# "ceq" x y : bool #) then (0)
elif (# "ceq" x x : bool #) then (1)
elif (# "ceq" y y : bool #) then (-1)
else (0)
when 'T : char = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : string =
// NOTE: we don't have to null check here because System.String.CompareOrdinal
Expand Down Expand Up @@ -4611,6 +4627,7 @@ namespace Microsoft.FSharp.Core
when ^T : decimal = System.Decimal.op_Inequality((# "" x:decimal #), (# "" y:decimal #))


// static comparison (ER mode) with static optimizations for some well-known cases
[<CompiledName("Compare")>]
let inline compare (x:^T) (y:^T) : int =
(if x < y then -1 elif x > y then 1 else 0)
Expand All @@ -4625,8 +4642,18 @@ namespace Microsoft.FSharp.Core
when ^T : uint32 = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when ^T : uint64 = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when ^T : unativeint = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when ^T : float = if (# "clt" x y : bool #) then (-1) else (# "cgt" x y : int #)
when ^T : float32 = if (# "clt" x y : bool #) then (-1) else (# "cgt" x y : int #)
when ^T : float = if (# "clt" x y : bool #) then (-1)
elif (# "cgt" x y : bool #) then (1)
elif (# "ceq" x y : bool #) then (0)
elif (# "ceq" x x : bool #) then (1)
elif (# "ceq" y y : bool #) then (-1)
else (0)
when ^T : float32 = if (# "clt" x y : bool #) then (-1)
elif (# "cgt" x y : bool #) then (1)
elif (# "ceq" x y : bool #) then (1)
elif (# "ceq" x x : bool #) then (1)
elif (# "ceq" y y : bool #) then (-1)
else (0)
when ^T : char = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when ^T : string =
// NOTE: we don't have to null check here because System.String.CompareOrdinal
Expand Down
Loading

0 comments on commit a693443

Please sign in to comment.