https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67635
Bug ID: 67635
Summary: [SH] ifcvt missed optimization
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: olegendo at gcc dot gnu.org
Target Milestone: ---
Target: sh*-*-*
At least on SH, the following:
bool test (int a, int b, int* r)
{
return __builtin_mul_overflow (a, b, r);
}
compiled with -m4 -ml -O2 results in:
dmuls.l r5,r4
mov #0,r0
sts macl,r1
sts mach,r2
cmp/gt r1,r0
subc r3,r3
cmp/eq r2,r3 <<
bf .L6 <<
.L2:
rts
mov.l r1,@r6
.align 1
.L6:
bra .L2
mov #1,r0
The expected code would be:
dmuls.l r5,r4
mov #0,r0
sts macl,r1
sts mach,r2
cmp/gt r1,r0
subc r3,r3
cmp/eq r2,r3 // T = r2 == r3
mov #-1,r0
negc r0,r0 // T = r2 != r3
rts
mov.l r1,@r6
Alternatively, in cases zero-displacement branches are fast (e.g. SH4):
dmuls.l r5,r4
mov #0,r0
sts macl,r1
sts mach,r2
cmp/gt r1,r0
subc r3,r3
cmp/eq r2,r3
bt 0f
mov #1,r0
0:
rts
mov.l r1,@r6
I think I have seen similar cases before, where something tries to preserve the
zero constant in a reg. Instead of overwriting it with a cstore value {0,1},
conditional branches are created for the non-zero paths.
If conditional move patterns are enabled on SH with -mpretend-cmove the
conditional branches go away:
dmuls.l r5,r4
mov #-1,r0
sts macl,r2
sts mach,r3
sts macl,r1
shll r2
subc r2,r2
cmp/eq r3,r2
mov.l r1,@r6
rts
negc r0,r0
But enabling -mpretend-cmove on SH has some other side effects and currently is
not safe (PR 58517).