Skip to content

Floating of unsafeEqualityProof

In #19539 (closed) Ben discovered that an unsafeEqualityProof call was impeding optimisation. This ticket is to track that problem.

Ben saw this:

mapAccumL
  = ...
                          case GHC.Prim.newPinnedByteArray# @GHC.Prim.RealWorld dt2 s of
                          { (# ipv [Occ=Once1], ipv1 #) ->
                          let {
                            ipv2 :: ForeignPtr Word8
                            [LclId]
                            ipv2
                              = case Unsafe.Coerce.unsafeEqualityProof
                                       @(TYPE 'GHC.Types.UnliftedRep)
                                       @(GHC.Prim.MutableByteArray# GHC.Prim.RealWorld)
                                       @GHC.Prim.ByteArray#
                                of
                                { Unsafe.Coerce.UnsafeRefl co ->
                                GHC.ForeignPtr.ForeignPtr
                                  @Word8
                                  (GHC.Prim.byteArrayContents# (ipv1 `cast` ...))
                                  (GHC.ForeignPtr.PlainPtr ipv1)
                                }
                           } in

So any case ipv2 of ForeignPtr x y -> blah in the body of that let aren't going to optimise as they should.

We have to be careful about floating unsafeEqualityProof outwards -- see Note [Implementing unsafeCoerce] in base:Unsafe.Coerce.

Rather, I think we want to float it inwards so we get

ipv2 = ForeignPtr (byteArrayContents# (case unsafeEqualityProof of UnsafeRefl co -> ipv1 `cast` co)) (PlainPtr ipv1)

This is not entirely straightforward; see Note [Floating primops] in GHC.Core.Opt.FloatIn. But it should be entirely do-able, by treating usafeEqualityProof as magical, as we already do in GHC.Core.Unfold.inlineBoringOk.

I'm not sure how urgent this ticket is. Obviously it affects only programs that do unsafeCoerce#. But they tend to be performance-hungry programs...

Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information