This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

combine: Undo canonicalizations when splitting (minus x (mult))


A week or two ago I posted a patch which added some new
canonicalizations in the combiner, to change
  (plus (mult X -Y) Z)
to
  (minus Z (mult X Y))

This helped on ARM, and to a lesser degree on x86.  I mentioned at the
time that I was aware of one counterexample, in the 20040709-2 testcase.
 Here, we have two successive pairs of multiply and add insns, which can
be combined to a single multiply and add - however, that becomes
 (minus (const_int) (mult X (const_int))
which is not recognizable on i686 even when split.

Since then I've also found a couple additional examples on x86_64 with
vectorization enabled.

The patch below corrects the problem by tweaking find_split_point.  If
we have
  (minus Z (mult X Y))
at the top level, and Y is not a constant power of 2, assume it is
easier for the target to split the (plus (mult X -Y) Z) form.

-       imull   $1103515245, %ecx, %r8d
-       addl    $12345, %r8d
-       imull   $1103515245, %r8d, %r8d
-       addl    $12345, %r8d
+       imull   $-1029531031, %ecx, %r8d
+       subl    $740551042, %r8d

Bootstrapped and tested on x86_64-linux.  Looking at code generation on
ARMv7 and x86_64, a few sequences were improved, and I did not discover
additional regressions.

Ok?


Bernd

Attachment: undo-canon.diff
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]