https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85925
Bug ID: 85925 Summary: [ARM][7/8/9 Regression] Mis-compilation at -02, masking with 257 goes wrong in combine Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sudi at gcc dot gnu.org Target Milestone: --- The following test case: #include <stdio.h> int a, c, d; volatile int b; int *e = &d; union U1 { unsigned f0; unsigned f1 : 15; }; int main() { for (c = 0; c <= 1; c++) { union U1 f = {0x10101}; if (c == 1) b; *e = f.f1; } printf("checksum = %X\n", d); } which should print "checksum = 101", but when compiled at -O2 for an aarch32 target it prints "checksum = 10101" arm-none-eabi-gcc -march=armv7-a -c test.c -o test.o -O2 Compiles correctly for -march=armv8-a. Kyrill helped to show the difference between armv7-a and armv8-a starts at combine where the good dump shows: Trying 22 -> 23: 22: r123:HI#0=zero_extract(r117:SI,0xf,0) REG_DEAD r117:SI 23: r124:SI=zero_extend(r123:HI) REG_DEAD r123:HI Successfully matched this instruction: (set (reg:SI 124) (and:SI (reg/v:SI 117 [ f ]) (const_int 257 [0x101]))) allowing combination of insns 22 and 23 original costs 8 + 8 = 16 replacement cost 12 deferring deletion of insn with uid = 22. modifying insn i3 23: r124:SI=r117:SI&0x101 REG_DEAD r117:SI deferring rescan insn with uid = 23. Trying 23 -> 24: 23: r124:SI=r117:SI&0x101 REG_DEAD r117:SI 24: [r116:SI]=r124:SI REG_DEAD r124:SI Failed to match this instruction: (set (mem:SI (reg/f:SI 116 [ pretmp_20 ]) [1 *pretmp_20+0 S4 A32]) (and:SI (reg/v:SI 117 [ f ]) (const_int 257 [0x101]))) but the bad shows: Trying 22 -> 23: 22: r123:HI#0=zero_extract(r117:SI,0xf,0) REG_DEAD r117:SI 23: r124:SI=zero_extend(r123:HI) REG_DEAD r123:HI Successfully matched this instruction: (set (reg:SI 124) (and:SI (reg/v:SI 117 [ f ]) (const_int 257 [0x101]))) rejecting combination of insns 22 and 23 original costs 4 + 4 = 8 replacement cost 12 Trying 23 -> 24: 23: r124:SI=zero_extend(r123:HI) REG_DEAD r123:HI 24: [r116:SI]=r124:SI REG_DEAD r124:SI Successfully matched this instruction: (set (mem:SI (reg/f:SI 116 [ pretmp_20 ]) [1 *pretmp_20+0 S4 A32]) (subreg:SI (reg:HI 123) 0)) allowing combination of insns 23 and 24 original costs 4 + 4 = 8 replacement cost 4 deferring deletion of insn with uid = 23. modifying insn i3 24: [r116:SI]=r123:HI#0 REG_DEAD r123:HI deferring rescan insn with uid = 24. Trying 22 -> 24: 22: r123:HI#0=zero_extract(r117:SI,0xf,0) REG_DEAD r117:SI 24: [r116:SI]=r123:HI#0 REG_DEAD r123:HI Successfully matched this instruction: (set (mem:SI (reg/f:SI 116 [ pretmp_20 ]) [1 *pretmp_20+0 S4 A32]) (reg/v:SI 117 [ f ])) allowing combination of insns 22 and 24 original costs 4 + 4 = 8 replacement cost 4 deferring deletion of insn with uid = 22. modifying insn i3 24: [r116:SI]=r117:SI REG_DEAD r117:SI deferring rescan insn with uid = 24. and thus eats out the masking (and the zero_extend).