[Bug target/54236] [SH] Improve addc and subc insn utilization
olegendo at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sat Sep 27 17:42:00 GMT 2014
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54236
--- Comment #9 from Oleg Endo <olegendo at gcc dot gnu.org> ---
The following function compiled with -O2
unsigned int check (unsigned int x)
{
return x == 0 ? 1 : x;
}
results in:
tst r4,r4
bt/s .L7
mov #1,r0
mov r4,r0
.L7:
rts
nop
Writing it as:
unsigned int check (unsigned int x)
{
return x + (x == 0);
}
results in:
tst r4,r4
mov #0,r0
rts
addc r4,r0
It seems that ifcvt is trying to utilize the 'add<mode>cc' standard name
pattern. If the 2nd operand of the conditional addition is a constant 1 or -1
the addcc insn can be implemented via addc or subc without a branch.
If the comparison can't be done in one insn (e.g. x != 0) and requires T bit
negation/inversion:
unsigned int check (unsigned int x)
{
return x + (x != 0);
}
results in (non-SH2A):
tst r4,r4
mov #-1,r0
negc r0,r0
rts
add r4,r0
slightly better (one arith insn less):
tst r4,r4
mov #-1,r0
subc r0,r4 // r4 = r4 - (-1) - T = r4 + 1 - T
rts
mov r4,r0
and on SH2A (already minimal):
tst r4,r4
movrt r0
rts
add r4,r0
subc case:
unsigned int check (unsigned int x)
{
return x - (x != 0);
}
non-SH2A:
tst r4,r4
mov #-1,r1
mov r4,r0
negc r1,r1
rts
sub r1,r0 // r0 = r4 - (1 - T) = r4 - 1 + T
SH2A:
tst r4,r4
movrt r1
mov r4,r0
rts
sub r1,r0
better (non-SH2A and SH2A):
tst r4,r4
mov #-1,r0
rts
addc r4,r0 // r0 = -1 + r4 + T = r4 - 1 + T
The equivalent conditional version should result in the same (currently it
isn't):
unsigned int check (unsigned int x)
{
return x != 0 ? (x - 1) : x;
}
Since ifcvt is also ran after combine, combine won't get the chance to combine
patterns such as:
(set (reg:SI 165 [ D.1635 ])
(plus:SI (xor:SI (reg:SI 147 t)
(const_int 1 [0x1]))
(reg/v:SI 164 [ x ])))
which would occur after emitting a comparison, negating the result (T bit) and
then adding/subtracting the T bit via addc/subc. If that happens, the combine
must be done manually in the split pass as it's done with some of the other
insns.
More information about the Gcc-bugs
mailing list