question about coercions between primitive types in STG level
Ömer Sinan Ağacan
omeragacan at gmail.com
Mon Dec 7 16:21:59 UTC 2015
Thanks Simon, primops worked fine, but not I'm getting assembler errors(even
though -dcore-lint, -dstg-lint and -dcmm-lint are all passing).
The error is caused by this STG expression:
case (#,#) [ds_gX8 ds_gX9] of _ {
(#,#) tag_gWR ubx_gWS ->
case tag_gWR of tag_gWR {
__DEFAULT -> GHC.Err.undefined;
1# ->
let {
sat_sWD :: [GHC.Types.Char] =
\u srt:SRT:[roK :-> GHC.Show.$fShowInt] []
let { sat_sWC :: GHC.Types.Int = NO_CCS
GHC.Types.I#! [ubx_gWS];
} in GHC.Show.show GHC.Show.$fShowInt sat_sWC; } in
let {
sat_sWB :: [GHC.Types.Char] =
\u srt:SRT:[0k :-> GHC.CString.unpackCString#] []
GHC.CString.unpackCString# "Left "#;
} in GHC.Base.++ sat_sWB sat_sWD;
2# ->
let {
co_gWT :: GHC.Prim.Float# =
sat-only \s [] int2Float# [ubx_gWS]; } in
let {
sat_sWH :: [GHC.Types.Char] =
\u srt:SRT:[rd2 :-> GHC.Float.$fShowFloat] []
let { sat_sWG :: GHC.Types.Float = NO_CCS
GHC.Types.F#! [co_gWT];
} in GHC.Show.show GHC.Float.$fShowFloat
sat_sWG; } in
let {
sat_sWF :: [GHC.Types.Char] =
\u srt:SRT:[0k :-> GHC.CString.unpackCString#] []
GHC.CString.unpackCString# "Right "#;
} in GHC.Base.++ sat_sWF sat_sWH;
};
};
In the first case(when the tag is 1#) I'm not doing any coercions, second
argument of the tuple is directly used. In the second case(when the tag is 2#),
I'm generating this let-binding:
let {
co_gWT :: GHC.Prim.Float# =
sat-only \s [] int2Float# [ubx_gWS]; }
And then in the RHS of case alternative I'm using co_gWT instead of ubx_gWS,
but for some reason GHC is generating invalid assembly for this expression:
/tmp/ghc2889_0/ghc_2.s: Assembler messages:
/tmp/ghc2889_0/ghc_2.s:125:0: error:
Error: `16(%xmm1)' is not a valid base/index expression
`gcc' failed in phase `Assembler'. (Exit code: 1)
The assembly seems to be:
==================== Asm code ====================
.section .text
.align 8
.quad 4294967296
.quad 18
co_gWT_info:
_cY7:
_cY9:
movq 16(%xmm1),%rax
cvtsi2ssq %rax,%xmm0
movss %xmm0,%xmm1
jmp *(%rbp)
.size co_gWT_info, .-co_gWT_info
Do you have any ideas why this may be happening?
2015-12-07 7:23 GMT-05:00 Simon Peyton Jones <simonpj at microsoft.com>:
> 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
More information about the ghc-devs
mailing list