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.