http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54673
Bug #: 54673 Summary: [SH] Unnecessary sign extension of logical operation results Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: olege...@gcc.gnu.org Target: sh*-*-* Logical operations already sign extended values as inputs cause additional sign extensions of intermediate values. For example: int test00 (char* a, short* b, int c) { return a[0] ^ a[1] ^ c; } becomes: mov.b @(1,r4),r0 mov.b @r4,r1 xor r1,r0 exts.b r0,r0 rts xor r6,r0 int test01 (char* a, short* b, int c) { return a[0] | a[1] | c; } becomes: mov.b @(1,r4),r0 mov.b @r4,r1 or r1,r0 exts.b r0,r0 rts or r6,r0 int test02 (char* a, short* b, int c) { return a[0] & a[1] & c; } becomes: mov.b @(1,r4),r0 mov.b @r4,r1 and r1,r0 exts.b r0,r0 rts and r6,r0 This seems to be caused by the fact that patterns for xorsi3, iorsi3 and andsi3 allow matching 'subreg' in their operands. In the combine pass it can be observed that it tries combinations such as: Failed to match this instruction: (set (reg:SI 173 [ D.1867 ]) (sign_extend:SI (subreg:QI (xor:SI (subreg:SI (mem:QI (plus:SI (reg/v/f:SI 166 [ a ]) (const_int 1 [0x1])) [0 MEM[(char *)a_2(D) + 1B]+0 S1 A8]) 0) (subreg:SI (reg:QI 171 [ *a_2(D) ]) 0)) 3))) which doesn't go anywhere. I have quickly tried out prohibiting subreg in the operands of the *xorsi3_compact insn and the sign extension (as well as the subreg orgy in combine) disappeared. However, I guess that not matching 'subreg' in the logical patterns will cause problems with DImode logical ops, since they are split into SImode ops working on subregs.