]> git.ipfire.org Git - thirdparty/gcc.git/commit
match: Change (A * B) + (-C) to (B - C/A) * A, if C multiple of A [PR109393]
authorKonstantinos Eleftheriou <konstantinos.eleftheriou@vrull.eu>
Thu, 5 Sep 2024 13:59:59 +0000 (15:59 +0200)
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>
Wed, 25 Sep 2024 13:47:05 +0000 (15:47 +0200)
commit08b8341f209be7c7e301853bdbbcad4f8e1695f5
tree4337b6fe5bc9076079d3db00d36669db0b5e2bc2
parentaf8ff0047e45b95c8b7b9dd291b4978fcdf9001d
match: Change (A * B) + (-C) to (B - C/A) * A, if C multiple of A [PR109393]

The following function:

int foo(int *a, int j)
{
  int k = j - 1;
  return a[j - 1] == a[k];
}

does not fold to `return 1;` using -O2 or higher. The cause of this is that
the expression `4 * j + (-4)` for the index computation is not folded to
`4 * (j - 1)`. Existing simplifications that handle similar cases are applied
when A == C, which is not the case in this instance.

A previous attempt to address this issue is
https://gcc.gnu.org/pipermail/gcc-patches/2024-April/649896.html

This patch adds the following simplification in match.pd:
(A * B) + (-C) -> (B - C/A) * A, if C a multiple of A

which also handles cases where the index is j - 2, j - 3, etc.

Bootstrapped for all languages and regression tested on x86-64 and aarch64.

PR tree-optimization/109393

gcc/ChangeLog:

* match.pd: (A * B) + (-C) -> (B - C/A) * A, if C a multiple of A.

gcc/testsuite/ChangeLog:

* gcc.dg/pr109393.c: New test.

Tested-by: Christoph Müllner <christoph.muellner@vrull.eu>
Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Konstantinos Eleftheriou <konstantinos.eleftheriou@vrull.eu>
gcc/match.pd
gcc/testsuite/gcc.dg/pr109393.c [new file with mode: 0644]