$ gcc/xgcc -Bgcc/ ../gcc/testsuite/gcc.target/aarch64/subs.c -O2 -S -o subs.s $ grep sub subs.s .file "subs.c" sub w1, w0, w1 subs x1, x0, x1
fd425e6293fb8306af74b3048352d97e1d67b922 is the first bad commit git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225249 138bc75d-0d04-0410-961f-82ee72b054a4
This is x = a - b; if (x != 0) vs. if (a != b) which we now more aggressively produce (the choice is not obvious and we are missing the reverse transform). The usual kind of action is to stick a single_use guard on the minus for /* Transform comparisons of the form X - Y CMP 0 to X CMP Y. ??? The transformation is valid for the other operators if overflow is undefined for the type, but performing it here badly interacts with the transformation in fold_cond_expr_with_comparison which attempts to synthetize ABS_EXPR. */ (for cmp (eq ne) (simplify (cmp (minus @0 @1) integer_zerop) (cmp @0 @1))) but I really don't like that solution (it will cause SCCVN regressions). value-numbering can also perform the reverse transform (though late forwprop will kill that again). I suppose we should look into finding a more general solution for the forwprop issues from inside forwprop.
This case is special in the sense that a - b on some targets already computes a - b != 0 but we don't have any way to represent this on GIMPLE. This also only works when a - b is computed "close" to the comparison.
This also breaks gcc.target/powerpc/405-nmacchw-2.c and gcc.target/powerpc/440-nmacchw-2.c.
*** Bug 66778 has been marked as a duplicate of this bug. ***
The ppc testcase, int f(int a, int b, int c) { a -= (short)b * (c >> 16); if (!a) return 10; return a; } is probably artificially triggering the same issue. Here we do not test for conditional part but for an instruction used implementing a -= (short)b * (c >> 16); But it shows the same issue with the followup transform of sinking the subtraction to the else path of the if. I suppose a single-use test is the way to go together with some means to "override" that when the caller is not going to create the result stmts but will only perform lookups if the result is already computed (that applies to all single-use tests).
I am testing Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 225453) +++ gcc/match.pd (working copy) @@ -1336,8 +1353,9 @@ (define_operator_list CBRT BUILT_IN_CBRT attempts to synthetize ABS_EXPR. */ (for cmp (eq ne) (simplify - (cmp (minus @0 @1) integer_zerop) - (cmp @0 @1))) + (cmp (minus@2 @0 @1) integer_zerop) + (if (single_use (@2)) + (cmp @0 @1)))) /* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the signed arithmetic case. That form is created by the compiler
Author: rguenth Date: Tue Jul 7 07:46:57 2015 New Revision: 225502 URL: https://gcc.gnu.org/viewcvs?rev=225502&root=gcc&view=rev Log: 2015-07-07 Richard Biener <rguenther@suse.de> PR middle-end/66739 * match.pd: Condition A - B ==/!= 0 -> A ==/!= B on single-use A - B. Modified: trunk/gcc/ChangeLog trunk/gcc/match.pd
Should be fixed now.