https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103765
Bug ID: 103765 Summary: Missed arithmetic simplification for multiplication + division Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: llvm at rifkin dot dev Target Milestone: --- The following code is optimized strangely: int foo(int x) { return (x * 72) / 3; } int bar(int x) { x *= 72; x /= 3; return x; } foo(int): lea eax, [rdi+rdi*2] sal eax, 3 ret bar(int): lea edx, [rdi+rdi*8] sal edx, 3 movsx rax, edx imul rax, rax, 1431655766 sar edx, 31 shr rax, 32 sub eax, edx ret https://godbolt.org/z/13PxxsM8G For some foo is simplified to return x * 24; but bar is not. It appears the transformation is done before transformation to gimple. Another case: int foo(int x) { return (x * 64) / 8; } int bar(int x) { x *= 64; x /= 8; return x; } foo(int): lea eax, [0+rdi*8] ret bar(int): sal edi, 6 lea eax, [rdi+7] cmovns eax, edi sar eax, 3 ret https://godbolt.org/z/vfG1TP7oG Even with powers of 2 (and thus shift operations down the line), it is not transformed. This would be a good enhancement, and I'd also be interested to learn why this strange behavior is occurring.