<div dir="ltr"><div><div><div><div>Note that int2Float# converts an Int# to the Float# with the same numeric value (e.g. 72 -> 72.0), not the one with the same bit representation (which doesn't really make sense anyways since Int# and Float# may be different sizes). So I think it's not what you want.<br><br></div>At least on x86_64, it's rather expensive to move a bit representation between a general-purpose register and a floating-point (xmm) register. As far as I know, the only way is to go through memory. This may have design implications for your work. For example, if you have an unboxed sum of two Double#s, it would certainly be better to store the data part in a floating-point register than a general-purpose register. If you have a sum that contains both integral and floating-point variants, it may be better depending on the situation to store its data in integer registers, floating-point registers, or a combination (using extra space). I doubt you want to give the programmer that much control though... One option would be, at least for a first version, treat Int# and Double# and Float# as three incompatible kinds of memory/registers that cannot alias each other.<br><br></div>As for your assembly code, can you provide the Cmm code that compiles to it? But in any case "movq 16(%xmm1),%rax" is certainly wrong, it should be offseting 16 bytes from a register like Sp or R1.<br><br></div>Regards,<br></div>Reid Barton<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 7, 2015 at 11:21 AM, Ömer Sinan Ağacan <span dir="ltr"><<a href="mailto:omeragacan@gmail.com" target="_blank">omeragacan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks Simon, primops worked fine, but not I'm getting assembler errors(even<br>
though -dcore-lint, -dstg-lint and -dcmm-lint are all passing).<br>
<br>
The error is caused by this STG expression:<br>
<br>
    case (#,#) [ds_gX8 ds_gX9] of _ {<br>
      (#,#) tag_gWR ubx_gWS -><br>
          case tag_gWR of tag_gWR {<br>
            __DEFAULT -> GHC.Err.undefined;<br>
            1# -><br>
                let {<br>
                  sat_sWD :: [GHC.Types.Char] =<br>
                      \u srt:SRT:[roK :-> GHC.Show.$fShowInt] []<br>
                          let { sat_sWC :: <a href="http://GHC.Types.Int" rel="noreferrer" target="_blank">GHC.Types.Int</a> = NO_CCS<br>
GHC.Types.I#! [ubx_gWS];<br>
                          } in  GHC.Show.show GHC.Show.$fShowInt sat_sWC; } in<br>
                let {<br>
                  sat_sWB :: [GHC.Types.Char] =<br>
                      \u srt:SRT:[0k :-> GHC.CString.unpackCString#] []<br>
                          GHC.CString.unpackCString# "Left "#;<br>
                } in  GHC.Base.++ sat_sWB sat_sWD;<br>
            2# -><br>
                let {<br>
                  co_gWT :: GHC.Prim.Float# =<br>
                      sat-only \s [] int2Float# [ubx_gWS]; } in<br>
                let {<br>
                  sat_sWH :: [GHC.Types.Char] =<br>
                      \u srt:SRT:[rd2 :-> GHC.Float.$fShowFloat] []<br>
                          let { sat_sWG :: GHC.Types.Float = NO_CCS<br>
GHC.Types.F#! [co_gWT];<br>
                          } in  GHC.Show.show GHC.Float.$fShowFloat<br>
sat_sWG; } in<br>
                let {<br>
                  sat_sWF :: [GHC.Types.Char] =<br>
                      \u srt:SRT:[0k :-> GHC.CString.unpackCString#] []<br>
                          GHC.CString.unpackCString# "Right "#;<br>
                } in  GHC.Base.++ sat_sWF sat_sWH;<br>
          };<br>
    };<br>
<br>
In the first case(when the tag is 1#) I'm not doing any coercions, second<br>
argument of the tuple is directly used. In the second case(when the tag is 2#),<br>
I'm generating this let-binding:<br>
<br>
    let {<br>
      co_gWT :: GHC.Prim.Float# =<br>
          sat-only \s [] int2Float# [ubx_gWS]; }<br>
<br>
And then in the RHS of case alternative I'm using co_gWT instead of ubx_gWS,<br>
but for some reason GHC is generating invalid assembly for this expression:<br>
<br>
    /tmp/ghc2889_0/ghc_2.s: Assembler messages:<br>
<br>
    /tmp/ghc2889_0/ghc_2.s:125:0: error:<br>
         Error: `16(%xmm1)' is not a valid base/index expression<br>
    `gcc' failed in phase `Assembler'. (Exit code: 1)<br>
<br>
The assembly seems to be:<br>
<br>
    ==================== Asm code ====================<br>
    .section .text<br>
    .align 8<br>
    .quad 4294967296<br>
    .quad 18<br>
    co_gWT_info:<br>
    _cY7:<br>
    _cY9:<br>
    movq 16(%xmm1),%rax<br>
    cvtsi2ssq %rax,%xmm0<br>
    movss %xmm0,%xmm1<br>
    jmp *(%rbp)<br>
    .size co_gWT_info, .-co_gWT_info<br>
<br>
Do you have any ideas why this may be happening?<br>
<div class="HOEnZb"><div class="h5"><br>
2015-12-07 7:23 GMT-05:00 Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com">simonpj@microsoft.com</a>>:<br>
> If memory serves, there are primops for converting between unboxed values of different widths.<br>
><br>
> Certainly converting between a float and a non-float will require an instruction on some architectures, since they use different register sets.<br>
><br>
> Re (2) I have no idea.  You'll need to get more information... pprTrace or something.<br>
><br>
> Simon<br>
><br>
> |  -----Original Message-----<br>
> |  From: ghc-devs [mailto:<a href="mailto:ghc-devs-bounces@haskell.org">ghc-devs-bounces@haskell.org</a>] On Behalf Of Ömer<br>
> |  Sinan Agacan<br>
> |  Sent: 06 December 2015 18:25<br>
> |  To: ghc-devs <<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a>><br>
> |  Subject: question about coercions between primitive types in STG level<br>
> |<br>
> |  Hi all,<br>
> |<br>
> |  In my compiler pass(D1559, see ElimUbxSums.hs) I'm doing some unsafe<br>
> |  coercions at the STG level. It works fine for lifted types, but for<br>
> |  unlifted ones I'm having some problems. What I'm trying to do is given<br>
> |  a number of primitive types I'm finding the one with biggest size, and<br>
> |  then generating a constructor that takes this biggest primitive type<br>
> |  as argument.<br>
> |<br>
> |  The problem is that this is not working very well - GHC is generating<br>
> |  illegal instructions that try to load a F32 value to a register<br>
> |  allocated for I64, using movss instruction.<br>
> |<br>
> |  CoreLint is catching this error and printing this:<br>
> |<br>
> |      Cmm lint error:<br>
> |        in basic block c1hF<br>
> |          in assignment:<br>
> |            _g16W::I64 = 4.5 :: W32;   // CmmAssign<br>
> |            Reg ty: I64<br>
> |            Rhs ty: F32<br>
> |<br>
> |  So I have two questions about this:<br>
> |<br>
> |  1. Is there a way to safely do this? What are my options here? What<br>
> |  I'm trying<br>
> |     to do is to use a single data constructor field for different<br>
> |  primitive<br>
> |     types.  The field is guaranteed to be as big as necessary.<br>
> |<br>
> |  2. In the Cmm code shown above, the type annotation is showing `W32`<br>
> |  but in the<br>
> |     error message it says `F32`. I'm confused about this, is this error<br>
> |  message<br>
> |     given because the sizes don't match? (64bits vs 32bits) Why the<br>
> |  type<br>
> |     annotation says W32 while the value has type F32?<br>
> |<br>
> |  Thanks..<br>
> |  _______________________________________________<br>
> |  ghc-devs mailing list<br>
> |  <a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
> |  <a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h" rel="noreferrer" target="_blank">https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h</a><br>
> |  <a href="http://askell.org" rel="noreferrer" target="_blank">askell.org</a>%2fcgi-bin%2fmailman%2flistinfo%2fghc-<br>
> |  devs&data=01%7c01%7csimonpj%<a href="http://40064d.mgd.microsoft.com" rel="noreferrer" target="_blank">40064d.mgd.microsoft.com</a>%7ced6a1fbfa6254e5<br>
> |  2a7d808d2fe6a9a63%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=7j3fQs4<br>
> |  ox67SZbA4jv4uPVVdvp5X5yUUuMaqp4sh%2fpg%3d<br>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</div></div></blockquote></div><br></div>