POssible bug in the Arm code generator

Hi all,

I do a little work on the Glasgow Haskell Compiler (GHC) which uses
LLVM for the backend when compiling for Arm and some other targets.

The reason I am posting to this list is that a GHC compiled program
(using the LLVM backend) is getting an illegal instruction exception
on the this instruction:

     ldr r0, [r0]

According to the Arm archtecture manual:

    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489i/CIHGJHED.html

this is pre-indexed load instruction of the form:

    LDR{type}{cond} Rt, [Rn, #offset]

but is illegal because the pre-indexed form of this instruction does
not allow 'Rt' and 'Rn' to be the same register.

The above all makes sense, but I find it a little hard to believe that
I am the first person to find this.

I'm using llvm-3.6.2 from a Debian package.

Clues? Comments?

Cheers,
Erik

Pay closer attention to the instruction descriptions on the page you linked above:

LDR{*type*}{*cond*} *Rt*, [*Rn* {, #*offset*}]        ; immediate offset

`

LDR{*type*}{*cond*} *Rt*, [*Rn*, #*offset*]!          ; pre-indexed

`

The pre-indexed form is always specified with an offset, and follows the brackets with an exclamation mark. You have an immediate offset load, for which Rt==Rn is permitted.

A possible reason for an illegal instruction exception is that you have generated some ARM code and tried to execute it as Thumb or vise-versa.

Owen Shepherd wrote:

Pay closer attention to the instruction descriptions on the page you linked
above:

LDR{*type*}{*cond*} *Rt*, [*Rn* {, #*offset*}] ; immediate offset

LDR{*type*}{*cond*} *Rt*, [*Rn*, #*offset*]! ; pre-indexed

The pre-indexed form is always specified with an offset, and* follows the
brackets with an exclamation mark*. You have an immediate offset load, for
which Rt==Rn is permitted.

Ah, missed that.

A possible reason for an illegal instruction exception is that you have
generated some ARM code and tried to execute it as Thumb or vise-versa.

Well, I'm getting SIGILL, but GHC does not generate or use thumb instructions
and the SIGILL happens after susccessfuly running a bunch of other arm
instructions. From GDB:

  Program received signal SIGILL, Illegal instruction.
  0x03ff9dbc in stg_ap_v_fast ()
  (gdb) bt
  #0 0x03ff9dbc in stg_ap_v_fast ()
  #1 0x03fc6ce6 in StgRun (f=0x3ff9db4 <stg_ap_v_fast>, basereg=0x49d2090 <MainCapability+16>) at
      rts/StgCRun.c:81
  #2 0x03fca52a in schedule (initialCapability=0x49d2080 <MainCapability>, task=0x49e62c0) at
      rts/Schedule.c:524
  #3 0x03fcc5e6 in scheduleWaitThread (tso=0xb6c07000, ret=0x0, pcap=0xbeffeb74) at
      rts/Schedule.c:2429
  #4 0x03fbc7e4 in rts_evalLazyIO (cap=0xbeffeb74, p=0x402d470 <ZCMain_main_closure>, ret=0x0) at
      rts/RtsAPI.c:500
  #5 0x03fce2be in hs_main (argc=3, argv=0xbeffed64, main_closure=0x402d470 <ZCMain_main_closure>,
      rts_config=...) at rts/RtsMain.c:64
  #6 0x00141508 in main ()
  (gdb) disassemble
  Dump of assembler code for function stg_ap_v_fast:
     0x03ff9db4 <+0>: push {r7, lr}
     0x03ff9db6 <+2>: sub sp, #32
     0x03ff9db8 <+4>: add r7, sp, #0
     0x03ff9dba <+6>: ldr r3, [pc, #508] ; (0x3ff9fb8 <stg_ap_v_fast+516>)
  => 0x03ff9dbc <+8>: ldr r3, [r3, #0]
     0x03ff9dbe <+10>: and.w r3, r3, #3

Erik