question about coercions between primitive types in STG level
Ömer Sinan Ağacan
omeragacan at gmail.com
Thu Dec 10 02:45:59 UTC 2015
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 <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%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 at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>
>
More information about the ghc-devs
mailing list