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.