https://gcc.gnu.org/g:16082bdc6beef1ca1485ed5ccdc0c52aabbe0f4c
commit r16-24-g16082bdc6beef1ca1485ed5ccdc0c52aabbe0f4c Author: Andrew Pinski <quic_apin...@quicinc.com> Date: Thu Feb 13 20:23:48 2025 -0800 gimple: Canonical order for invariants [PR118902] So unlike constants, address invariants are currently put first if used with a SSA NAME. It would be better if address invariants are consistent with constants and this patch changes that. gcc.dg/tree-ssa/pr118902-1.c is an example where this canonicalization can help. In it if `p` variable was a global variable, FRE (VN) would have figured it out that `a` could never be equal to `&p` inside the loop. But without the canonicalization we end up with `&p == a.0_1` which VN does try to handle for conditional VN. Bootstrapped and tested on x86_64. PR tree-optimization/118902 gcc/ChangeLog: * fold-const.cc (tree_swap_operands_p): Place invariants in the first operand if not used with constants. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr118902-1.c: New test. Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> Diff: --- gcc/fold-const.cc | 6 ++++++ gcc/testsuite/gcc.dg/tree-ssa/pr118902-1.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 1275ef75315a..c9471ea44b01 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -7246,6 +7246,12 @@ tree_swap_operands_p (const_tree arg0, const_tree arg1) if (TREE_CONSTANT (arg0)) return true; + /* Put invariant address in arg1. */ + if (is_gimple_invariant_address (arg1)) + return false; + if (is_gimple_invariant_address (arg0)) + return true; + /* It is preferable to swap two SSA_NAME to ensure a canonical form for commutative and comparison operators. Ensuring a canonical form allows the optimizers to find additional redundancies without diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr118902-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr118902-1.c new file mode 100644 index 000000000000..fa21b8a74ef8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr118902-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void foo(int); +void l(int**); +int f1(int j, int t) +{ + int p = 0; + int *a = &p; + l(&a); + if (a == &p) + return 0; + for(int i = 0; i < j; i++) + { + if (a == &p) foo(p); + } + return 0; +} + +/* We should be able to remove the call to foo because a is never equal to &p inside the loop. */ +/* { dg-final { scan-tree-dump-not "foo " "optimized"} } */