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.

Reply via email to