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).

Reply via email to