https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96050

            Bug ID: 96050
           Summary: PDP-11: 32-bit MOV from offset(Rn) overrides Rn
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: imachug at gmail dot com
  Target Milestone: ---

Consider the following code:


struct {
        unsigned long a, b;
} structure;

void calc() {
        unsigned long x = structure.a;
        unsigned long y = structure.b;
        asm volatile(""::"r"(x), "r"(y));
}


("asm volatile" is just to stop GCC from removing x and y completely)

When this source is compiled with "-Os -S", GCC erroneously generates the
following assembly to load structure members to registers:


mov     $_structure,r0
mov     (r0),r2
mov     02(r0),r3
mov     04(r0),r0
mov     06(r0),r1


"mov 04(r0), r0" overrides r0, which the next instruction assumes to contain
the old non-overwritten value.

I think this has to do with disabled early clobbering on movsi insn, but adding
"&" to lines 529, 536 in pdp11.md (i.e. changing "=r,r,g,g" to "=&r,r,g,g" in
"[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,g,g")") didn't fix the
bug for me.


$ ./tools/bin/pdp11-aout-gcc -v
Using built-in specs.
COLLECT_GCC=./tools/bin/pdp11-aout-gcc-10.1.0
COLLECT_LTO_WRAPPER=/[redacted]/tools/libexec/gcc/pdp11-aout/10.1.0/lto-wrapper
Target: pdp11-aout
Configured with: ../configure --prefix /[redacted]/tools --target pdp11-aout
--enable-languages=c --with-gnu-as --with-gnu-ld --without-headers
--disable-libssp
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.1.0 (GCC) 

$ uname -a
Linux [redacted] 5.3.0-59-generic #53-Ubuntu SMP Wed Jun 3 15:52:15 UTC 2020
x86_64 x86_64 x86_64 GNU/Linux

Reply via email to