
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
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@haskell.org] On Behalf Of Ömer | Sinan Agacan | Sent: 06 December 2015 18:25 | To: ghc-devs
| 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