https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72710
Bug ID: 72710 Summary: combine rejects post-inc mem Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org CC: segher at gcc dot gnu.org Target Milestone: --- Target: sh*-*-* This is happening on SH on the AMS branch in CSiBE/OpenTCP/ip.c: unsigned short ip_checksum(unsigned short, char, char); unsigned long ip_checksum_buf (unsigned short cs, char* buf, unsigned short len) { unsigned short dat; unsigned long temp; temp = cs; while(len>1) { len -= 2; dat = *buf++; dat <<= 8; dat |= *buf++; temp += dat; } temp = (temp >> 16) + (temp & 0xFFFF); temp += (temp >>16); if(len) temp = ip_checksum(temp, *buf, 0); return( (unsigned short) temp ); } Without AMS, before combine there are the two insns: (insn 80 78 81 4 (set (reg:QI 257 [ MEM[base: _67, offset: 1B] ]) (mem:QI (plus:SI (reg:SI 240 [ ivtmp.12 ]) (const_int 1 [0x1])) [0 MEM[base: _67, offset: 1B]+0 S1 A8])) sh_tmp.cpp:1549 200 {*movqi_load_mem_disp12} (nil)) (insn 81 80 82 4 (set (reg:HI 256 [ MEM[base: _67, offset: 1B]+-1 ]) (sign_extend:HI (reg:QI 257 [ MEM[base: _67, offset: 1B] ]))) sh_tmp.cpp:1549 177 {*extendqihi2_compact_reg} (expr_list:REG_DEAD (reg:QI 257 [ MEM[base: _67, offset: 1B] ]) (nil))) Then during combine: Trying 80 -> 81: Failed to match this instruction: (set (reg:HI 256 [ MEM[base: _67, offset: 1B]+-1 ]) (sign_extend:HI (mem:QI (plus:SI (reg:SI 240 [ ivtmp.12 ]) (const_int 1 [0x1])) [0 MEM[base: _67, offset: 1B]+0 S1 A8]))) .... Trying 80, 81 -> 83: Failed to match this instruction: (set (reg:SI 259) (ior:SI (subreg:SI (mem:QI (plus:SI (reg:SI 240 [ ivtmp.12 ]) (const_int 1 [0x1])) [0 MEM[base: _67, offset: 1B]+0 S1 A8]) 0) (subreg:SI (reg:HI 258 [ dat ]) 0))) Successfully matched this instruction: (set (reg:SI 256 [ MEM[base: _67, offset: 1B]+-3 ]) (sign_extend:SI (mem:QI (plus:SI (reg:SI 240 [ ivtmp.12 ]) (const_int 1 [0x1])) [0 MEM[base: _67, offset: 1B]+0 S1 A8]))) So combine promotes reg 256 from SImode to HImode and everything's good. The same two initial insns with AMS before combine: (insn 80 146 81 4 (set (reg:QI 257 [ MEM[base: _67, offset: 1B] ]) (mem:QI (post_inc:SI (reg:SI 480)) [0 MEM[base: _67, offset: 1B]+0 S1 A8])) sh_tmp.cpp:1549 202 {*movqi} (expr_list:REG_INC (reg:SI 480) (nil))) (insn 81 80 82 4 (set (reg:HI 256 [ MEM[base: _67, offset: 1B]+-1 ]) (sign_extend:HI (reg:QI 257 [ MEM[base: _67, offset: 1B] ]))) sh_tmp.cpp:1549 177 {*extendqihi2_compact_reg} (expr_list:REG_DEAD (reg:QI 257 [ MEM[base: _67, offset: 1B] ]) (nil))) Then combine does: Trying 80 -> 81: Failed to match this instruction: (set (reg:HI 256 [ MEM[base: _67, offset: 1B]+-1 ]) (sign_extend:HI (mem:QI (post_inc:SI (reg:SI 480)) [0 MEM[base: _67, offset: 1B]+0 S1 A8]))) ... Trying 80, 81 -> 83: Failed to match this instruction: (set (reg:SI 259) (ior:SI (subreg:SI (sign_extend:HI (mem:QI (post_inc:SI (reg:SI 480)) [0 MEM[base: _67, offset: 1B]+0 S1 A8])) 0) (subreg:SI (reg:HI 258 [ dat ]) 0))) Failed to match this instruction: (set (reg:HI 256 [ MEM[base: _67, offset: 1B]+-1 ]) (sign_extend:HI (mem:QI (post_inc:SI (reg:SI 480)) [0 MEM[base: _67, offset: 1B]+0 S1 A8]))) As a consequence, the redundant sign extension after the actually sign-extending mem-load remains. At the moment it seems that only adding more patterns to the MD helps: (define_insn "*extend<mode>hi2_compact_snd" [(set (match_operand:HI 0 "arith_reg_dest" "=r") (sign_extend:HI (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))] "TARGET_SH1 && false" "mov.<bw> %1,%0" [(set_attr "type" "load")])