Opened 8 years ago

Closed 8 years ago

#5422 closed bug (fixed)

Panic when using lots of registers in cmm code

Reported by: pumpkin Owned by: igloo
Priority: high Milestone: 7.4.1
Component: Compiler Version: 7.2.1
Keywords: Cc: ekmett@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


If I try to compile (using ghc -c) the following code:

  foreign "C" f(R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11);

I get:

ghc: panic! (the 'impossible' happened)
  (GHC version 7.2.1 for x86_64-apple-darwin):

Change History (10)

comment:1 Changed 8 years ago by pumpkin

Note that the bug does not appear until I use R11. Up to R10, all is well.

comment:2 Changed 8 years ago by ekmett

Cc: ekmett@… added

comment:3 Changed 8 years ago by pumpkin

This bug is caused by the fact that baseRegOffset in CgUtils.hs has a bunch of hard-coded pattern matches up to 10 on VanillaReg, and panics if those aren't enough. I guess 10 registers are good enough for everyone? Using statically computed offsets into the StgRegTable seems unfortunate here, but I don't know how it works well enough to have any better ideas :/

comment:4 Changed 8 years ago by simonmar

In the beginning there were 8 registers, and That Was Enough For Everyone. Then, I needed to sneak some information from compiled code into the RTS and the easiest way to do that was to add a register. This happened a few more times. So compiled code only uses 8 registers at most; certain special sequences that interact with the RTS need to pass information in the higher registers.

Now, primops have a fixed calling convention that puts all arguments in the R registers. This is so that we can write the primop code once and for all without worrying about platform-dependent calling conventions. Fortunately there aren't any primops with more than 8 arguments, so that's ok.

Eventually primops will use the same calling convention as other Haskell functions, but this will have to wait until the new code generator is fully working and we can ditch the old one and rewrite the RTS primop code.

So, I presume you want to write a primop with more than 8 arguments?

comment:5 Changed 8 years ago by ekmett

Yes. For a concrete example, calling MPFR's 'add' function in the style of our use of GMP would take 9.

type CSign#      = Int#
type CPrecision# = Int#
type CExp#       = Int#
type CRounding#  = Int#

foreign import prim "mpfr_cmm_add" mpfrAdd#
  :: CRounding#
  -> CPrecision# -> CSign# -> CExp# -> ByteArray#
  -> CPrecision# -> CSign# -> CExp# -> ByteArray#
  -> (# CPrecision#, CSign#, CExp#, ByteArray# #)

As a stopgap, we are multiplying sign by precision a priori and unpacking in C--.

type CSignPrec# = Int#

foreign import prim "mpfr_cmm_add" mpfrAdd#
  :: CRounding#
  -> CSignPrec# -> CExp# -> ByteArray#
  -> CSignPrec# -> CExp# -> ByteArray#
  -> (# CSignPrec#, CExp#, ByteArray# #)

This gets us down to 7 for most ops, in exchange for a bunch of random bit twiddling, but there are some bindings that will still push us up against the limit.

comment:6 Changed 8 years ago by igloo

Milestone: 7.4.1
Priority: normalhigh

See also #5423. I think we can improve things (e.g. better error, and increasing the number of regs), but not a complete fix (primops using the same calling convention as other Haskell functions), for 7.4.

comment:7 Changed 8 years ago by simonmar

Agreed - let's fix it so that all 10 regs can be used for now.

comment:8 Changed 8 years ago by igloo

Owner: set to igloo

comment:9 Changed 8 years ago by igloo@…

commit ab9e7e37baa71576f9dd8aaff07d10a330e5625d

Author: Ian Lynagh <>
Date:   Sun Nov 6 15:53:39 2011 +0000

    Give a better error for uses of R11, R12, ...; trac #5422
    It's still a panic, as it wouldn't be trivial to give a proper error
    at the point that we generate it, but it's now a bit nicer:
        Registers above R10 are not supported (tried to use R11)

 compiler/codeGen/CgUtils.hs |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

comment:10 Changed 8 years ago by igloo

Resolution: fixed
Status: newclosed

10 regs can now be used, and you get a friendlier panic if you exceed 10.

Note: See TracTickets for help on using tickets.