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