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 -> GHC.Types.IO () = \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 GHC.Prim.Int# of (sat_s1Ia :: GHC.Prim.Int#) { __DEFAULT -> let { sat_s1Ib :: GHC.Types.Int = NO_CCS GHC.Types.I#! [(sat_s1Ia :: GHC.Prim.Int#)]; } in System.IO.print :: forall a_aUq. GHC.Show.Show a_aUq => a_aUq -> GHC.Types.IO () (GHC.Show.$fShowInt :: GHC.Show.Show GHC.Types.Int) (sat_s1Ib :: GHC.Types.Int); }; }; (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 GHC.Prim.Int# of (co_g21m :: GHC.Prim.Int#) { __DEFAULT -> (#,#) [2## (co_g21m :: GHC.Prim.Int#)]; } :: UbxTup 2 of (sat_s21b :: (# GHC.Prim.Int#, GHC.Prim.Int# #)) { (#,#) (sat_g21R :: GHC.Prim.Int#) (sat_g21S :: GHC.Prim.Int#) -> Main.showEither2 :: (# GHC.Prim.Int#, GHC.Prim.Int# #) -> [GHC.Types.Char] (sat_g21R :: GHC.Prim.Int#) (sat_g21S :: GHC.Prim.Int#); }; 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 <marlo...@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-boun...@haskell.org] On Behalf Of Ömer >> | Sinan Agacan >> | Sent: 06 December 2015 18:25 >> | To: ghc-devs <ghc-devs@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@haskell.org >> | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h >> | askell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc- >> | devs&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7ced6a1fbfa6254e5 >> | 2a7d808d2fe6a9a63%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=7j3fQs4 >> | ox67SZbA4jv4uPVVdvp5X5yUUuMaqp4sh%2fpg%3d >> _______________________________________________ >> ghc-devs mailing list >> ghc-devs@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs >> > _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs