[arm] Don't generate invalid LDRD insns
authorAlex Coplan <alex.coplan@arm.com>
Mon, 18 May 2020 15:29:04 +0000 (16:29 +0100)
committerAlex Coplan <alex.coplan@arm.com>
Mon, 18 May 2020 15:31:43 +0000 (16:31 +0100)
commit8b8f3117263ca79b3febadadb07732588d99d5f6
treed6cebeaf9f743b78ad81dc883005418a59d2172e
parent94f687bd9ae37ece9391a3c42783c5768d26e81d
[arm] Don't generate invalid LDRD insns

This fixes a bug in the arm backend where GCC generates invalid LDRD
instructions. The LDRD instruction requires the first transfer register to be
even, but GCC attempts to use odd registers here. For example, with the
following C code:

    struct c {
      double a;
    } __attribute((aligned)) __attribute((packed));
    struct c d;
    struct c f(struct c);
    void e() { f(d); }

The struct d is passed in registers r1 and r2 to the function f, and GCC
attempted to do this with a LDRD instruction when compiling with -march=armv7-a
on a soft float toolchain.

The fix is analogous to the corresponding one for STRD in the same function:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=52057dc4ac5295caebf83147f688d769c93cbc8d

2020-05-18  Alex Coplan  <alex.coplan@arm.com>

gcc/:
* config/arm/arm.c (output_move_double): Fix codegen when loading into
a register pair with an odd base register.

gcc/testsuite/:
* gcc.c-torture/compile/packed-aligned-1.c: New test.
* gcc.c-torture/execute/packed-aligned.c: New test.
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/packed-aligned-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/packed-aligned.c [new file with mode: 0644]