https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85805

Georg-Johann Lay <gjl at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |NEW
          Component|target                      |rtl-optimization
            Version|4.8.1                       |8.1.0

--- Comment #6 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
Lokks like a bug in insn combiner, hence rtl optimization issue, not a target
issue.

Test case:

typedef __UINT64_TYPE__ uint64_t;

char tmp;

void test_64 (uint64_t d64)
{
    if ((d64 & 0xFF800000UL) == 0xFF800000UL)
        tmp++;
}

Compiling with v8.0.1

$ avr-gcc foo.c -Os -c -mmcu=avr5 -save-temps -dap

.combine dump reads:

Trying 30 -> 31:
   30: {cc0=cmp(r18:DI,0xff800000);clobber scratch;}
      REG_DEAD r18:DI
   31: pc={(cc0!=0)?L38:pc}
      REG_BR_PROB 708669604
Successfully matched this instruction:
(set (pc)
    (label_ref:HI 38))
allowing combination of insns 30 and 31

i.e. combiner combines the 64-bit comparison of reg:DI 18 against the constant
with the conditional jump on CC0 to an UNCONDITIONAL jump.  Hence anything that
is used to set CC0 becomes unused and is thrown away in the remainder...

with -fdisable-rtl-combine the final asm looks correct and reads:

test_64:
        andi r20,lo8(-128)       ;  16  [c=4 l=1]  andqi3/1
        ldi r18,0                ;  22  [c=4 l=1]  movqi_insn/0
        ldi r19,0                ;  23  [c=4 l=1]  movqi_insn/0
        ldi r22,0                ;  26  [c=4 l=1]  movqi_insn/0
        ldi r23,0                ;  27  [c=4 l=1]  movqi_insn/0
        ldi r24,0                ;  28  [c=4 l=1]  movqi_insn/0
        ldi r25,0                ;  29  [c=4 l=1]  movqi_insn/0
        cp r18,__zero_reg__      ;  30  [c=4 l=8]  compare_const_di2
        cpc r19,__zero_reg__
        sbci r20,-128
        sbci r21,-1
        cpc r22,__zero_reg__
        cpc r23,__zero_reg__
        cpc r24,__zero_reg__
        cpc r25,__zero_reg__
        brne .L1                 ;  31  [c=16 l=1]  branch
        lds r24,tmp      ;  33  [c=4 l=2]  movqi_insn/3
        subi r24,lo8(-(1))       ;  34  [c=4 l=1]  addqi3/1
        sts tmp,r24      ;  35  [c=4 l=2]  movqi_insn/2
.L1:
        ret              ;  53  [c=0 l=1]  return

Insns 16..29 perform the AND of the 64-bit value held in r18...r25, insn 30
performs the comparisons against the constant and sets CC0.

Reply via email to