question about coercions between primitive types in STG level

Simon Peyton Jones simonpj at microsoft.com
Thu Dec 17 12:52:48 UTC 2015


Omer

Honestly I'm out of my depth here, and so time-poor that I don't think I can realistically help much.  I hope others can be more useful!

Simon

|  -----Original Message-----
|  From: Ömer Sinan Ağacan [mailto:omeragacan at gmail.com]
|  Sent: 10 December 2015 02:46
|  To: Simon Marlow <marlowsd at gmail.com>; Simon Peyton Jones
|  <simonpj at microsoft.com>; ghc-devs <ghc-devs at haskell.org>; rwbarton at gmail.com
|  Subject: Re: question about coercions between primitive types in STG level
|  
|  Thanks for all the answers,
|  
|  Simon, do you remember anything about the ticket about converting between
|  floating point types and integers? I spend quite a bit of time in Trac
|  searching for this but couldn't find it.
|  
|  
|  Before implementing a new primop, MachOp, and code generation functions for
|  that I tried this: Since type signature of this new primop will be same as
|  float2Int# I thought maybe I should first make current implementation
|  working, and then I can just change the primop to coerceFloat2Int# and it
|  would work.
|  
|  However I'm still this same problem(illegal assembly). What I changed is I
|  looked at the GHC-generated, working STG code that uses float2Int#, and
|  tried to generate a very similar code myself. The change I had to make for
|  this was to use a case expression instead of let expression to bind result
|  of this primop.
|  
|  Here's an example. This STG is working fine:
|  
|      sat_s1Ic :: GHC.Types.Float ->
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Types.IO&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=BnXCV6rCnP5ibif0LwHYctTd6BVA85horA1D
|  1Uketrk%3d () =
|          \r srt:SRT:[0B :-> System.IO.print,
|                      rUB :-> GHC.Show.$fShowInt] [ds_s1I7]
|              case
|                  ds_s1I7 :: GHC.Types.Float :: Alg GHC.Types.Float
|              of
|              (wild_s1I8 :: GHC.Types.Float)
|              { GHC.Types.F# (f_s1I9 :: GHC.Prim.Float#) ->
|                    case
|                        float2Int# [(f_s1I9 :: GHC.Prim.Float#)] :: Prim
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#
|                    of
|                    (sat_s1Ia ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#)
|                    { __DEFAULT ->
|                          let {
|                            sat_s1Ib ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Types.Int&data=01%7c0
|  1%7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72
|  f988bf86f141af91ab2d7cd011db47%7c1&sdata=SP%2fVPreBotFEHkZyK2Y1YSX30dEjkei6h
|  PARLyK11Yw%3d =
|                                NO_CCS GHC.Types.I#! [(sat_s1Ia ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#)];
|                          } in
|                            System.IO.print
|                              :: forall a_aUq. GHC.Show.Show a_aUq => a_aUq ->
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Types.IO&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=BnXCV6rCnP5ibif0LwHYctTd6BVA85horA1D
|  1Uketrk%3d ()
|                                (GHC.Show.$fShowInt :: GHC.Show.Show
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Types.Int&data=01%7c0
|  1%7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72
|  f988bf86f141af91ab2d7cd011db47%7c1&sdata=SP%2fVPreBotFEHkZyK2Y1YSX30dEjkei6h
|  PARLyK11Yw%3d)
|                                (sat_s1Ib ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Types.Int&data=01%7c0
|  1%7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72
|  f988bf86f141af91ab2d7cd011db47%7c1&sdata=SP%2fVPreBotFEHkZyK2Y1YSX30dEjkei6h
|  PARLyK11Yw%3d);
|                    };
|              };
|  
|  (Sorry for extra noisy output, I changed Outputable instances to print some
|  extra info)
|  
|  This code is generated by GHC for a program that uses the primop directly
|  and it's working. This is the code generated by my pass:
|  
|      Main.main2 :: [GHC.Types.Char] =
|          \u srt:SRT:[r4 :-> Main.showEither2] []
|              case
|                  case
|                      float2Int# [1.2#] :: Prim
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#
|                  of
|                  (co_g21m ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#)
|                  { __DEFAULT -> (#,#) [2## (co_g21m ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#)];
|                  } :: UbxTup 2
|              of
|              (sat_s21b :: (#
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#,
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d# #))
|              { (#,#) (sat_g21R ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#) (sat_g21S ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#) ->
|                    Main.showEither2
|                      :: (#
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#,
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d# #) -> [GHC.Types.Char]
|                        (sat_g21R ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#) (sat_g21S ::
|  https://na01.safelinks.protection.outlook.com/?url=GHC.Prim.Int&data=01%7c01
|  %7csimonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7c72f
|  988bf86f141af91ab2d7cd011db47%7c1&sdata=GMVWFJOAJ4IZj2t9WZ2hX3h7xm7U7Dbn0OfU
|  gjON958%3d#);
|              };
|  
|  Types look correct, and I'm using a case expression to bind the result of
|  the primop. But generated assembly for this is still invalid! I'm wondering
|  if there are some invariants that I'm invalidating here, even although -
|  dstg-lint is passing. Does anyone know what I might be doing wrong here?
|  
|  One thing that I'm not being very careful is the information about live
|  variables, but I don't see how it might be related with this illegal
|  instruction error.
|  
|  Thanks again..
|  
|  2015-12-07 13:57 GMT-05:00 Simon Marlow <marlowsd at gmail.com>:
|  > Simon's right, you need an explicit conversion, and unfortunately
|  > those conversions don't currently exist.  You would have to add them
|  > to the MachOp type, and implement them in each of the native code
|  generators.
|  >
|  > The good news is that if you did this, we could implement cheap
|  > conversions between the IEEE floating point types and their
|  > representations as unboxed integers, which is currently done by poking
|  > the values to memory and then peeking them back at the desired type.
|  > There's a ticket for this around somewhere....
|  >
|  > Cheers
|  > Simon
|  >
|  >
|  > On 07/12/2015 12:23, Simon Peyton Jones wrote:
|  >>
|  >> If memory serves, there are primops for converting between unboxed
|  >> values of different widths.
|  >>
|  >> Certainly converting between a float and a non-float will require an
|  >> instruction on some architectures, since they use different register
|  sets.
|  >>
|  >> Re (2) I have no idea.  You'll need to get more information...
|  >> pprTrace or something.
|  >>
|  >> Simon
|  >>
|  >> |  -----Original Message-----
|  >> |  From: ghc-devs [mailto:ghc-devs-bounces at haskell.org] On Behalf Of
|  >> | Ömer  Sinan Agacan
|  >> |  Sent: 06 December 2015 18:25
|  >> |  To: ghc-devs <ghc-devs at haskell.org>
|  >> |  Subject: question about coercions between primitive types in STG
|  >> | level
|  >> |
|  >> |  Hi all,
|  >> |
|  >> |  In my compiler pass(D1559, see ElimUbxSums.hs) I'm doing some
|  >> | unsafe  coercions at the STG level. It works fine for lifted types,
|  >> | but for  unlifted ones I'm having some problems. What I'm trying to
|  >> | do is given  a number of primitive types I'm finding the one with
|  >> | biggest size, and  then generating a constructor that takes this
|  >> | biggest primitive type  as argument.
|  >> |
|  >> |  The problem is that this is not working very well - GHC is
|  >> | generating  illegal instructions that try to load a F32 value to a
|  >> | register  allocated for I64, using movss instruction.
|  >> |
|  >> |  CoreLint is catching this error and printing this:
|  >> |
|  >> |      Cmm lint error:
|  >> |        in basic block c1hF
|  >> |          in assignment:
|  >> |            _g16W::I64 = 4.5 :: W32;   // CmmAssign
|  >> |            Reg ty: I64
|  >> |            Rhs ty: F32
|  >> |
|  >> |  So I have two questions about this:
|  >> |
|  >> |  1. Is there a way to safely do this? What are my options here?
|  >> | What  I'm trying
|  >> |     to do is to use a single data constructor field for different
|  >> | primitive
|  >> |     types.  The field is guaranteed to be as big as necessary.
|  >> |
|  >> |  2. In the Cmm code shown above, the type annotation is showing
|  >> | `W32`  but in the
|  >> |     error message it says `F32`. I'm confused about this, is this
|  >> | error  message
|  >> |     given because the sizes don't match? (64bits vs 32bits) Why the
|  >> | type
|  >> |     annotation says W32 while the value has type F32?
|  >> |
|  >> |  Thanks..
|  >> |  _______________________________________________
|  >> |  ghc-devs mailing list
|  >> |  ghc-devs at haskell.org
|  >> |
|  >> | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmai
|  >> | l.h
|  >> |  askell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc-
|  >> |
|  >> | devs&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7ced6a1fbfa625
|  >> | 4e5
|  >> |
|  >> | 2a7d808d2fe6a9a63%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=7j3f
|  >> | Qs4  ox67SZbA4jv4uPVVdvp5X5yUUuMaqp4sh%2fpg%3d
|  >> _______________________________________________
|  >> ghc-devs mailing list
|  >> ghc-devs at haskell.org
|  >> https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.
|  >> haskell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc-devs&data=01%7c01%7c
|  >> simonpj%40064d.mgd.microsoft.com%7c900655295d074c8b867b08d3010c2165%7
|  >> c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=DYbGX1f9UBqSTEN9qDWBiqM9H
|  >> ucMEitgBCnh4ZZjneg%3d
|  >>
|  >


More information about the ghc-devs mailing list