[GHC] #9251: ghc does not expose branchless max/min operations as primops

GHC ghc-devs at haskell.org
Sun Jul 6 13:08:44 UTC 2014


#9251: ghc does not expose branchless max/min operations as primops
-------------------------------------+------------------------------------
        Reporter:  carter            |            Owner:  carter
            Type:  task              |           Status:  new
        Priority:  normal            |        Milestone:  7.10.1
       Component:  Compiler          |          Version:  7.8.2
      Resolution:                    |         Keywords:
Operating System:  Unknown/Multiple  |     Architecture:  Unknown/Multiple
 Type of failure:  None/Unknown      |       Difficulty:  Unknown
       Test Case:                    |       Blocked By:
        Blocking:                    |  Related Tickets:  #9246
-------------------------------------+------------------------------------

Comment (by arotenberg):

 Question: What "should" the behaviors of min and max be for the special
 cases of negative zero and NaN? Currently GHC does this:
 {{{
 Prelude> min 0.0 (-0.0) :: Double
 0.0
 Prelude> min (-0.0) 0.0 :: Double
 -0.0
 Prelude> min 0.0 (0.0/0.0) :: Double
 NaN
 Prelude> min (0.0/0.0) 0.0 :: Double
 0.0
 }}}

 The SSE instructions, at least,
 [http://x86.renejeschke.de/html/file_module_x86_id_173.html work similarly
 if you get the order right]:

  If the values being compared are both 0.0s (of either sign), the value in
 the second operand (source operand) is returned. If a value in the second
 operand is an SNaN, that SNaN is returned unchanged to the destination
 (that is, a QNaN version of the SNaN is not returned).

  If only one value is a NaN (SNaN or QNaN) for this instruction, the
 second operand (source operand), either a NaN or a valid floating-point
 value, is written to the result. If instead of this behavior, it is
 required that the NaN source operand (from either the first or second
 operand) be returned, the action of MINSD can be emulated using a sequence
 of instructions, such as, a comparison followed by AND, ANDN and OR.

 However, [http://en.wikipedia.org/wiki/IEEE_754_revision#min_and_max
 according to Wikipedia], IEEE 754-2008 specifies

  The min and max operations are defined but leave some leeway for the case
 where the inputs are equal in value but differ in representation. In
 particular:

   min(+0,−0) or min(−0,+0) must produce something with a value of zero but
 may always return the first argument.

  In order to support operations such as windowing in which a NaN input
 should be quietly replaced with one of the end points, min and max are
 defined to select a number, x, in preference to a quiet NaN:

   min(x,NaN) = min(NaN,x) = x
   max(x,NaN) = max(NaN,x) = x

  In the current draft, these functions are called minNum and maxNum to
 indicate their preference for a number over a quiet NaN.

 Some further comparisons: Java's `Math.min`
 [http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#min-double-
 double- specifies]

  Returns the smaller of two double values. That is, the result is the
 value closer to negative infinity. If the arguments have the same value,
 the result is that same value. If either value is NaN, then the result is
 NaN. Unlike the numerical comparison operators, this method considers
 negative zero to be strictly smaller than positive zero. If one argument
 is positive zero and the other is negative zero, the result is negative
 zero.

 The .NET Framework's `Math.Min` [http://msdn.microsoft.com/en-
 us/library/xcd487wd%28v=vs.110%29.aspx specifies]

  Parameter val1 or val2, whichever is smaller. If val1, val2, or both val1
 and val2 are equal to NaN, NaN is returned.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9251#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list