widening_mul: restrict ops to be defined in the same basic-block when convert plusminus to widen

In the testcase for PR94269, widening_mul moves two multiply
instructions from outside the loop to inside
the loop, merging with two add instructions separately.  This
increases the cost of the loop.  Like FMA detection
in the same pass, simply restrict ops to be defined in the same
basic-block to avoid possibly moving multiply
to a different block with a higher execution frequency.

2020-03-26  Felix Yang  <felix.yang@huawei.com>

	PR tree-optimization/94269
	* tree-ssa-math-opts.c (convert_plusminus_to_widen): Restrict
	this
	operation to single basic block.

	* gcc.dg/pr94269.c: New test.
This commit is contained in:
Richard Biener 2020-03-26 08:33:57 +01:00
parent 27f8c8c4c9
commit d21dff5b4f
4 changed files with 43 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2020-03-26 Felix Yang <felix.yang@huawei.com>
PR tree-optimization/94269
* tree-ssa-math-opts.c (convert_plusminus_to_widen): Restrict
this
operation to single basic block.
2020-03-25 Jeff Law <law@redhat.com>
PR rtl-optimization/90275

View File

@ -1,3 +1,8 @@
2020-03-26 Felix Yang <felix.yang@huawei.com>
PR tree-optimization/94269
* gcc.dg/pr94269.c: New test.
2020-03-25 Andrew Stubbs <ams@codesourcery.com>
* gcc.dg/vect/bb-slp-pr69907.c: Disable the dump scan for amdgcn.

View File

@ -0,0 +1,26 @@
/* { dg-do compile { target aarch64*-*-* } } */
/* { dg-options "-O2 -ftree-loop-vectorize -funsafe-math-optimizations -march=armv8.2-a+sve -msve-vector-bits=256" } */
float
foo(long n, float *x, int inc_x,
float *y, int inc_y)
{
float dot = 0.0;
int ix = 0, iy = 0;
if (n < 0) {
return dot;
}
int i = 0;
while (i < n) {
dot += y[iy] * x[ix];
ix += inc_x;
iy += inc_y;
i++;
}
return dot;
}
/* { dg-final { scan-assembler-not "smaddl" { target aarch64*-*-* } } } */

View File

@ -2715,11 +2715,14 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
multiply-and-accumulate instructions.
If the widened-multiplication result has more than one uses, it is
probably wiser not to do the conversion. */
probably wiser not to do the conversion. Also restrict this operation
to single basic block to avoid moving the multiply to a different block
with a higher execution frequency. */
if (code == PLUS_EXPR
&& (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
{
if (!has_single_use (rhs1)
|| gimple_bb (rhs1_stmt) != gimple_bb (stmt)
|| !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
&type2, &mult_rhs2))
return false;
@ -2729,6 +2732,7 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
{
if (!has_single_use (rhs2)
|| gimple_bb (rhs2_stmt) != gimple_bb (stmt)
|| !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
&type2, &mult_rhs2))
return false;