https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78660
--- Comment #8 from Matthew Fortune <matthew.fortune at imgtec dot com> --- Created attachment 40518 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40518&action=edit testcase I have narrowed this bug down to a mis-compilation of gcc/c/c-decl.c where there are a few code differences after applying yunqiang's partial revert. A reduced and pre-processed c-decl.c file is attached. mips64el-linux-gnu-g++ -fno-PIE -c -DIN_GCC_FRONTEND -O2 -DIN_GCC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common -o c-decl.me.o c-decl.me.c The key (I think) is that the following sequence of 3 instructions ends up being combined into 1 but the resulting instruction leaves the upper 32-bits of reg 316 entirely undefined. Eventually this leads to reg 316 being spilled to the stack where it is allocated a 64-bit slot but this spill only writes 32-bits whereas consumers read 64-bit and even if the value will only ever be operated on as 32-bit or less then logical and branch operations on the reloaded value will go wrong and normal 32-bit operations will be (strictly) undefined. (insn 56 55 57 3 (set (reg:SI 470) (ne:SI (reg/f:DI 469 [ current_scope.1_1->bindings ]) (const_int 0 [0]))) "/althome/mips/v6/src/gcc/gcc/c/c-decl.me.c":915 501 {*sne_zero_disi} (expr_list:REG_DEAD (reg/f:DI 469 [ current_scope.1_1->bindings ]) (nil))) (insn 57 56 58 3 (set (reg:QI 468) (subreg:QI (reg:SI 470) 0)) "/althome/mips/v6/src/gcc/gcc/c/c-decl.me.c":915 360 {*movqi_internal} (expr_list:REG_DEAD (reg:SI 470) (nil))) (insn 58 57 59 3 (set (reg:DI 316 [ iftmp.3_114 ]) (zero_extend:DI (reg:QI 468))) "/althome/mips/v6/src/gcc/gcc/c/c-decl.me.c":915 214 {*zero_extendqidi2} (expr_list:REG_DEAD (reg:QI 468) (nil))) combines to... (insn 58 57 59 3 (set (subreg:SI (reg:DI 316 [ iftmp.3_114 ]) 0) (ne:SI (reg/f:DI 469 [ current_scope.1_1->bindings ]) (const_int 0 [0]))) "/althome/mips/v6/src/gcc/gcc/c/c-decl.me.c":915 501 {*sne_zero_disi} (expr_list:REG_DEAD (reg/f:DI 469 [ current_scope.1_1->bindings ]) (nil))) The relevant fragment of combine is: Trying 57 -> 58: Successfully matched this instruction: (set (reg:DI 316 [ iftmp.3_114 ]) (subreg:DI (reg:SI 470) 0)) allowing combination of insns 57 and 58 original costs 4 + 4 = 8 replacement cost 4 deferring deletion of insn with uid = 57. modifying insn i3 58: r316:DI=r470:SI#0 REG_DEAD r470:SI deferring rescan insn with uid = 58. Trying 56 -> 58: Successfully matched this instruction: (set (subreg:SI (reg:DI 316 [ iftmp.3_114 ]) 0) (ne:SI (reg/f:DI 469 [ current_scope.1_1->bindings ]) (const_int 0 [0]))) allowing combination of insns 56 and 58 original costs 4 + 4 = 8 replacement cost 4 deferring deletion of insn with uid = 56. modifying insn i3 58: r316:DI#0=r469:DI!=0 REG_DEAD r469:DI deferring rescan insn with uid = 58. I've not started investigating why exactly this decision is made.