[GHC] #13442: Add a coercion/cast operator to CMM
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- While trying to implement casts between floating-point and integral types #4092) @rwbarton suggested the following CMM: {{{ stg_wordToFloatzh(W_ w) { D_ d; STK_CHK_P_LL(WDS(1), stg_wordToFloatzh, w); Sp(-1) = w; d = Sp(-1); return (d); } }}} This code works outside of GHC, but when I try to add it as `rts/CastFloatWord.cmm` the CMM linter complains with: {{{ Cmm lint error: in basic block c5 in assignment: _c2::F64 = I64[Sp + -1 * 8]; Reg ty: F64 Rhs ty: I64 Program was: {offset c6: // global _c1::I64 = R1; //tick src<rts/CastFloatWord.cmm:(7,1)-(13,1)> if (Sp - 1 * 8 < SpLim) goto c3; else goto c5; c3: // global //tick src<rts/CastFloatWord.cmm:9:35-100> R1 = _c1::I64; R2 = stg_wordToFloatzh; call stg_gc_prim_p_ll(R1, R2) args: 8, res: 0, upd: 8; c5: // global I64[Sp + -1 * 8] = _c1::I64; _c2::F64 = I64[Sp + -1 * 8]; D1 = _c2::F64; call (P64[(old + 8)])(D1) args: 8, res: 0, upd: 8; } }}} For hand written CMM code like this, it would be nice to have a cast/coercion to allow this code to pass the linter. Looking for suggestions as to the syntax. I suspect that it would be best if the destination type was made explicit in the cast operation. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by erikd): For the time being, I'm going with the following syntax: {{{ _c2::F64 = <F64> I64[Sp + -1 * 8]; }}} where the `<F64>` is the cast destination type. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): Can we have a keyword in there as well? Anything to avoid Cmm turning into more of a symbol-soup that it already is. Perhaps `cast <F64> I64[Sp + -1 * 8];`¿ -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by erikd): Sure, that should be easy. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): Replying to [comment:1 erikd]:
For the time being, I'm going with the following syntax: {{{ _c2::F64 = <F64> I64[Sp + -1 * 8]; }}} where the `<F64>` is the cast destination type.
I'm a little confused, is this supposed to be valid input Cmm? I thought I got a syntax error when I tried writing things like {{{ a = I64[Sp - WDS(1)]; }}} but if you can write that, then the version for a double should certainly be {{{ a = F64[Sp - WDS(1)]; }}} and not involve any sort of "cast". -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): In particular, an actual cast is problematic as your original purpose here was precisely to implement a word to double cast operation. It seems like the goal of adding this cast is to slip past Cmm's type checking, but as there actually is a well-typed way to do what you want in Cmm, it would be better to do that; and add input Cmm syntax for it if necessary. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by erikd):
I'm a little confused, is this supposed to be valid input Cmm?
The `cast <F64>` is my proposed extension to CMM.
It seems like the goal of adding this cast is to slip past Cmm's type checking,
The CMM type checker seems fine with this, its CMM's linter than complains.
but as there actually is a well-typed way to do what you want in Cmm,
There is? Please elaborate! -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): Take any old function that calculates with `Double` like {{{#!hs f :: Double -> Double f x = x + 1 }}} and compile it with `-O -ddump-cmm`, and it will do things like {{{ cOz: _sOd::F64 = %MO_F_Add_W64(F64[R1 + 7], 1.0 :: W64); I64[Hp - 8] = GHC.Types.D#_con_info; F64[Hp] = _sOd::F64; R1 = Hp - 7; Sp = Sp + 8; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; }}} `F64[A]` is the way to denote the 64-bit floating point quantity at address `A`. So internally Cmm has a representation of exactly the construct you need already. I'm just not sure whether it is possible to write that construct in a `.cmm` file. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by erikd): * status: new => closed * resolution: => invalid Comment: Ok, this works: {{{ stg_wordToFloatzh(W_ w) { D_ d; STK_CHK_P_LL(WDS(1), stg_wordToFloatzh, w); Sp(-1) = w; d = D_ [Sp(-1)]; return (d); } }}} Closing this ticket. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:8> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by erikd): * status: closed => new * resolution: invalid => Comment: Nope, that doesn't work, it segfaults. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:9> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by erikd): Thinking about it some more, I can't see how CMM could represent a casting operation without the `CmmCast` expression I added. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:10> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): It should be {{{ d = D_[Sp - WDS(1)]; }}} `Sp(-1)` is already a memory access ("the value at `Sp - WDS(1)`"). -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:11> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13442: Add a coercion/cast operator to CMM -------------------------------------+------------------------------------- Reporter: erikd | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by rwbarton): * status: new => closed * resolution: => invalid Comment: Replying to [comment:10 erikd]:
Thinking about it some more, I can't see how CMM could represent a casting operation without the `CmmCast` expression I added.
Let's please not add a generic casting operation to Cmm. We already have a variety of specific conversions; and the whole point here is that it is not easy to implement the specific conversion that you need (as in ticket:4092#comment:9). -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13442#comment:12> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC