Bug 66739 - [6 regression] FAIL: gcc.target/aarch64/subs.c scan-assembler subs\tw[0-9]
Summary: [6 regression] FAIL: gcc.target/aarch64/subs.c scan-assembler subs\tw[0-9]
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: 6.0
Assignee: Richard Biener
URL:
Keywords: missed-optimization
: 66778 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-07-02 12:35 UTC by Andreas Schwab
Modified: 2015-07-07 08:01 UTC (History)
4 users (show)

See Also:
Host:
Target: aarch64-*-* powerpc-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-07-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Schwab 2015-07-02 12:35:34 UTC
$ 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
Comment 1 Andreas Schwab 2015-07-02 12:37:27 UTC
fd425e6293fb8306af74b3048352d97e1d67b922 is the first bad commit

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225249 138bc75d-0d04-0410-961f-82ee72b054a4
Comment 2 Richard Biener 2015-07-02 12:42:15 UTC
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.
Comment 3 Richard Biener 2015-07-02 12:44:43 UTC
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.
Comment 4 Andreas Schwab 2015-07-05 12:34:36 UTC
This also breaks gcc.target/powerpc/405-nmacchw-2.c and gcc.target/powerpc/440-nmacchw-2.c.
Comment 5 Andreas Schwab 2015-07-06 14:15:14 UTC
*** Bug 66778 has been marked as a duplicate of this bug. ***
Comment 6 Richard Biener 2015-07-06 14:39:00 UTC
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).
Comment 7 Richard Biener 2015-07-06 14:43:50 UTC
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
Comment 8 Richard Biener 2015-07-07 07:47:29 UTC
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
Comment 9 Richard Biener 2015-07-07 08:01:41 UTC
Should be fixed now.