https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109393
cuilili <lili.cui at intel dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lili.cui at intel dot com
--- Comment #16 from cuilili <lili.cui at intel dot com> ---
I found a regression with commit: "match: Change (A * B) + (-C) to (B - C/A) *
A, if C multiple of A [PR109393]".
Godbolt link: https://godbolt.org/z/qq46h7Wjf
-----------------------------------
Test case:
int func1(int *a, int j) {
int k = j - 1;
return a[j - 1] == a[k];
}
int func2(int *a, int j) {
int k = j - 1;
return a[k] == a[j-1];
}
------------------------------------
Assembly comparison:
Before this commit:
func1(int*, int):
movslq %esi, %rax
subl $1, %esi
movslq %esi, %rsi
movl (%rdi,%rsi,4), %edx
cmpl %edx, -4(%rdi,%rax,4)
sete %al
movzbl %al, %eax
ret
func2(int*, int):
movl $1, %eax
ret
After the commit:
func1(int*, int):
movl $1, %eax
ret
func2(int*, int):
leal -1(%rsi), %eax
movslq %esi, %rsi
cltq
movl -4(%rdi,%rsi,4), %edx
cmpl %edx, (%rdi,%rax,4)
sete %al
movzbl %al, %eax
ret
----------------------------------------
The patch fixes func1 but breaks func2. These are semantically identical
functions - the optimization result should not depend on operand order.
Additionally, this transformation prevents efficient SIB addressing on x86.
I tried to implement backend compensation, but only partial recovery is
possible in some complex benchmarks.
Should we revert this patch? Or alternatively, I can disable this conversion
for x86.