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).