haskell/core-libraries-committee

Make cast between words and floats real primops

Closed this issue · 6 comments

base:GHC.Float exposes the following functions:

castWord32ToFloat :: Word32 -> Float
castFloatToWord32 :: Float -> Word32
castWord64ToDouble :: Word64 -> Double
castDoubleToWord64 :: Double -> Word64

stgDoubleToWord64 :: Double# -> Word64#
stgWord64ToDouble :: Word64# -> Double#
stgFloatToWord32 :: Float# -> Word32#
stgWord32ToFloat :: Word32# -> Float#

These functions perform bitcast between word and float types.

Issue

While working on bytestring (in bytestring#631) I've noticed that GHC didn't constant-fold application of these functions to constant values. E.g. stgDoubleToWord64 1.0## gives the following Core:

  = case {__ffi_static_ccall_safe base:stg_doubleToWord64zh "stg_doubleToWord64zh" :: Double#
                                                                             -> Word64#}_ii3E
           1.0##
    of ds1_ii3H
    { __DEFAULT ->
    GHC.Word.W64# ds1_ii3H
    }  

Proposal

Replace the current FFI implementation with real primops. This will allow:

  • constant folding support
  • implementing them using inline assembly (e.g. MOVD instruction on x86-64)

What it means for base:

  1. a few more exports from modules that export all primops (GHC.Base, GHC.Exts...)
  2. we could use the opportunity to rename:
stgDoubleToWord64 :: Double# -> Word64#
stgWord64ToDouble :: Word64# -> Double#
stgFloatToWord32 :: Float# -> Word32#
stgWord32ToFloat :: Word32# -> Float#

into (note the trailing #):

castDoubleToWord64# :: Double# -> Word64#
castWord64ToDouble# :: Word64# -> Double#
castFloatToWord32# :: Float# -> Word32#
castWord32ToFloat# :: Word32# -> Float#

The old names would be deprecated for a few releases.

Implementation

Dear CLC members. Given that the change only cursory touches base and that the linked MR does not contain any breaking changes, I think we can vote as is promptly.

@tomjaguarpaw @mixphix @hasufell @velveteer @angerman @parsonsmatt


+1 from me. I followed Sylvain's work in haskell/bytestring#631 (comment), this patch is a nice optimization indeed.

+1


Thanks for proposing better new names and keeping around the old ones for compatibility. I think that's the right thing to do.

+1, although I will say that the fact that we need to hold the compilers hand and expose these primops explicitly makes me a bit sad.

+1

Thanks all, that's enough votes to approve.