https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195
Bug ID: 89195 Summary: [7/8/9 regression] Corrupted stack offset after combine Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: wilco at gcc dot gnu.org Target Milestone: --- The following testcase generates incorrect stack offsets on AArch64 since GCC7 when compiled with -O1 -mbig-endian: struct S { unsigned i : 24; }; volatile unsigned char x; int f (struct S d) { return d.i & x; } This produces: sub sp, sp, #16 str x0, [sp, 8] adrp x0, x ldrb w0, [x0, #:lo12:x] and w0, w0, 255 mov x1, 2305843009213693952 add x1, sp, x1 ldr w1, [x1, 7] and w0, w1, w0 add sp, sp, 16 ret The combine output is as follows: Trying 10, 11 -> 12: 10: r100:SI=[sfp:DI-0x8] 11: r101:SI#0=zero_extract(r100:SI#0,0x18,0x8) REG_DEAD r100:SI 12: r98:SI=r101:SI&r92:SI REG_DEAD r101:SI REG_DEAD r92:SI Failed to match this instruction: (set (reg:SI 98) (and:SI (mem/c:SI (plus:DI (reg/f:DI 64 sfp) (const_int 2305843009213693943 [0x1ffffffffffffff7])) [1 dD.3407+2305843009213693951 S4 A8]) (reg:SI 92 [ x.0_3+-3 ]))) Successfully matched this instruction: (set (reg:SI 101) (mem/c:SI (plus:DI (reg/f:DI 64 sfp) (const_int 2305843009213693943 [0x1ffffffffffffff7])) [1 dD.3407+2305843009213693951 S4 A8])) Successfully matched this instruction: (set (reg:SI 98) (and:SI (reg:SI 101) (reg:SI 92 [ x.0_3+-3 ]))) allowing combination of insns 10, 11 and 12 original costs 16 + 4 + 4 = 24 replacement costs 16 + 4 = 20 deferring deletion of insn with uid = 10. modifying insn i2 11: r101:SI=[sfp:DI+0x1ffffffffffffff7] deferring rescan insn with uid = 11. modifying insn i3 12: r98:SI=r101:SI&r92:SI REG_DEAD r92:SI REG_DEAD r101:SI deferring rescan insn with uid = 12. So it appears to want to change the offset -8 to -7 to optimize the zero-extend away (this is an out-of-bound access, but maybe OK for locals?). It must be converting a bit offset to a byte offset using an unsigned shift, losing the top 3 bits, which results in a wildly out of range offset...