]> git.ipfire.org Git - thirdparty/gcc.git/commit
match: Fix wrong code due to `(a ? e : f) !=/== (b ? e : f)` patterns [PR116120]
authorAndrew Pinski <quic_apinski@quicinc.com>
Mon, 29 Jul 2024 21:00:13 +0000 (14:00 -0700)
committerAndrew Pinski <quic_apinski@quicinc.com>
Thu, 1 Aug 2024 15:21:15 +0000 (08:21 -0700)
commitc5ccdfdcab0b24afba2a661af861bec1d63f0595
treefccac517669580e2891b17bfdea0bf55723073e5
parent88fc730efdd31cc4bf13932ff3cc5b097a5eb23c
match: Fix wrong code due to `(a ? e : f) !=/== (b ? e : f)` patterns [PR116120]

When this pattern was converted from being only dealing with 0/-1, we missed that if `e == f` is true
then the optimization is wrong and needs an extra check for that.

This changes the patterns to be:
/* (a ? x : y) != (b ? x : y) --> (a^b & (x != y)) ? TRUE  : FALSE */
/* (a ? x : y) == (b ? x : y) --> (a^b & (x != y)) ? FALSE : TRUE  */
/* (a ? x : y) != (b ? y : x) --> (a^b | (x == y)) ? FALSE : TRUE  */
/* (a ? x : y) == (b ? y : x) --> (a^b | (x == y)) ? TRUE  : FALSE */

Also this can't be done if the X can be a NaNs either. Since that changes the value there too.

This still produces better code than the original case and in many cases (x != y) will
still reduce to either false or true.

With this change we also need to make sure `a`, `b` and the resulting types are all
the same for the same reason as the previous patch.

I updated (well added) to the testcases to make sure there are the right amount of
comparisons left.

Changes since v1:
* v2: Fixed the testcase names and fixed dg-run to be `dg-do run`. Added a check for HONORS_NANS too.

Bootstrapped and tested on x86_64-linux-gnu with no regressions.

PR tree-optimization/116120

gcc/ChangeLog:

* match.pd (`(a ? x : y) eq/ne (b ? x : y)`): Add test for `x != y`
in result.
(`(a ? x : y) eq/ne (b ? y : x)`): Add test for `x == y` in result.

gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/pr111150.C: Add extra checks on the test.
* gcc.dg/tree-ssa/pr111150-1.c: Likewise.
* gcc.dg/tree-ssa/pr111150.c: Likewise.
* g++.dg/torture/pr116120-1.C: New test.
* g++.dg/torture/pr116120-2.C: New test.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
gcc/match.pd
gcc/testsuite/g++.dg/torture/pr116120-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr116120-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tree-ssa/pr111150.C
gcc/testsuite/gcc.dg/tree-ssa/pr111150-1.c
gcc/testsuite/gcc.dg/tree-ssa/pr111150.c