https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89018
Bug ID: 89018 Summary: common subexpression present in both branches of condition is not factored out Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: wojciech_mula at poczta dot onet.pl Target Milestone: --- A common transformation used in a C condition expression is not detected and code is duplicated. Below are a few examples: ---condition.c--- long transform(long); long negative_max(long a, long b) { return (a >= b) ? -a : -b; } long fun_max(long a, long b) { return (a >= b) ? 47*a : 47*b; } long transform_max(long a, long b) { return (a >= b) ? transform(a) : transform(b); } ---eof--- In both branches a scalar value is a part of the same expression. So, it would be more profitable when, for instance "(a >= b) ? -a : -b" would be compiled as "-((a >= b) ? a : b))". Of course, a programmer might factor it out, but in case of macros or auto-generated code such silly repetition might occur. Below is assembly code generated for x86 by a pretty fresh GCC 9. BTW the jump instruction from `fun_max` and `transform_max` can be replaced with a condition move. $ gcc --version gcc (GCC) 9.0.0 20190117 (experimental) $ gcc -O3 -march=skylake -c -S condition.c && cat condition.s negative_max: movq %rdi, %rdx movq %rsi, %rax negq %rdx negq %rax cmpq %rsi, %rdi cmovge %rdx, %rax ret fun_max: cmpq %rsi, %rdi jl .L6 imulq $47, %rdi, %rax ret .L6: imulq $47, %rsi, %rax ret transform_max: cmpq %rsi, %rdi jge .L11 movq %rsi, %rdi .L11: jmp transform