mirror of git://gcc.gnu.org/git/gcc.git
tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument 'type'.
2011-08-19 Andrew Stubbs <ams@codesourcery.com> gcc/ * tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument 'type'. Use 'type' from caller, not inferred from 'rhs'. Don't reject non-conversion statements. Do return lhs in this case. (is_widening_mult_p): Add new argument 'type'. Use 'type' from caller, not inferred from 'stmt'. Pass type to is_widening_mult_rhs_p. (convert_mult_to_widen): Pass type to is_widening_mult_p. (convert_plusminus_to_widen): Likewise. gcc/testsuite/ * gcc.target/arm/wmul-8.c: New file. From-SVN: r177907
This commit is contained in:
parent
ff63d754c1
commit
26a855d7e0
|
@ -1,3 +1,15 @@
|
||||||
|
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
||||||
|
|
||||||
|
* tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument
|
||||||
|
'type'.
|
||||||
|
Use 'type' from caller, not inferred from 'rhs'.
|
||||||
|
Don't reject non-conversion statements. Do return lhs in this case.
|
||||||
|
(is_widening_mult_p): Add new argument 'type'.
|
||||||
|
Use 'type' from caller, not inferred from 'stmt'.
|
||||||
|
Pass type to is_widening_mult_rhs_p.
|
||||||
|
(convert_mult_to_widen): Pass type to is_widening_mult_p.
|
||||||
|
(convert_plusminus_to_widen): Likewise.
|
||||||
|
|
||||||
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
||||||
|
|
||||||
* tree-ssa-math-opts.c (is_widening_mult_p): Remove FIXME.
|
* tree-ssa-math-opts.c (is_widening_mult_p): Remove FIXME.
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
||||||
|
|
||||||
|
* gcc.target/arm/wmul-8.c: New file.
|
||||||
|
|
||||||
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
||||||
|
|
||||||
* gcc.target/arm/wmul-7.c: New file.
|
* gcc.target/arm/wmul-7.c: New file.
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
/* { dg-require-effective-target arm_dsp } */
|
||||||
|
|
||||||
|
long long
|
||||||
|
foo (long long a, int *b, int *c)
|
||||||
|
{
|
||||||
|
return a + *b * *c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "smlal" } } */
|
|
@ -1966,7 +1966,8 @@ struct gimple_opt_pass pass_optimize_bswap =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return true if RHS is a suitable operand for a widening multiplication.
|
/* Return true if RHS is a suitable operand for a widening multiplication,
|
||||||
|
assuming a target type of TYPE.
|
||||||
There are two cases:
|
There are two cases:
|
||||||
|
|
||||||
- RHS makes some value at least twice as wide. Store that value
|
- RHS makes some value at least twice as wide. Store that value
|
||||||
|
@ -1976,27 +1977,31 @@ struct gimple_opt_pass pass_optimize_bswap =
|
||||||
but leave *TYPE_OUT untouched. */
|
but leave *TYPE_OUT untouched. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_widening_mult_rhs_p (tree rhs, tree *type_out, tree *new_rhs_out)
|
is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
|
||||||
|
tree *new_rhs_out)
|
||||||
{
|
{
|
||||||
gimple stmt;
|
gimple stmt;
|
||||||
tree type, type1, rhs1;
|
tree type1, rhs1;
|
||||||
enum tree_code rhs_code;
|
enum tree_code rhs_code;
|
||||||
|
|
||||||
if (TREE_CODE (rhs) == SSA_NAME)
|
if (TREE_CODE (rhs) == SSA_NAME)
|
||||||
{
|
{
|
||||||
type = TREE_TYPE (rhs);
|
|
||||||
stmt = SSA_NAME_DEF_STMT (rhs);
|
stmt = SSA_NAME_DEF_STMT (rhs);
|
||||||
if (!is_gimple_assign (stmt))
|
if (is_gimple_assign (stmt))
|
||||||
return false;
|
{
|
||||||
|
rhs_code = gimple_assign_rhs_code (stmt);
|
||||||
|
if (TREE_CODE (type) == INTEGER_TYPE
|
||||||
|
? !CONVERT_EXPR_CODE_P (rhs_code)
|
||||||
|
: rhs_code != FIXED_CONVERT_EXPR)
|
||||||
|
rhs1 = rhs;
|
||||||
|
else
|
||||||
|
rhs1 = gimple_assign_rhs1 (stmt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rhs1 = rhs;
|
||||||
|
|
||||||
rhs_code = gimple_assign_rhs_code (stmt);
|
|
||||||
if (TREE_CODE (type) == INTEGER_TYPE
|
|
||||||
? !CONVERT_EXPR_CODE_P (rhs_code)
|
|
||||||
: rhs_code != FIXED_CONVERT_EXPR)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
rhs1 = gimple_assign_rhs1 (stmt);
|
|
||||||
type1 = TREE_TYPE (rhs1);
|
type1 = TREE_TYPE (rhs1);
|
||||||
|
|
||||||
if (TREE_CODE (type1) != TREE_CODE (type)
|
if (TREE_CODE (type1) != TREE_CODE (type)
|
||||||
|| TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
|
|| TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
|
||||||
return false;
|
return false;
|
||||||
|
@ -2016,28 +2021,27 @@ is_widening_mult_rhs_p (tree rhs, tree *type_out, tree *new_rhs_out)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if STMT performs a widening multiplication. If so,
|
/* Return true if STMT performs a widening multiplication, assuming the
|
||||||
store the unwidened types of the operands in *TYPE1_OUT and *TYPE2_OUT
|
output type is TYPE. If so, store the unwidened types of the operands
|
||||||
respectively. Also fill *RHS1_OUT and *RHS2_OUT such that converting
|
in *TYPE1_OUT and *TYPE2_OUT respectively. Also fill *RHS1_OUT and
|
||||||
those operands to types *TYPE1_OUT and *TYPE2_OUT would give the
|
*RHS2_OUT such that converting those operands to types *TYPE1_OUT
|
||||||
operands of the multiplication. */
|
and *TYPE2_OUT would give the operands of the multiplication. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_widening_mult_p (gimple stmt,
|
is_widening_mult_p (tree type, gimple stmt,
|
||||||
tree *type1_out, tree *rhs1_out,
|
tree *type1_out, tree *rhs1_out,
|
||||||
tree *type2_out, tree *rhs2_out)
|
tree *type2_out, tree *rhs2_out)
|
||||||
{
|
{
|
||||||
tree type;
|
|
||||||
|
|
||||||
type = TREE_TYPE (gimple_assign_lhs (stmt));
|
|
||||||
if (TREE_CODE (type) != INTEGER_TYPE
|
if (TREE_CODE (type) != INTEGER_TYPE
|
||||||
&& TREE_CODE (type) != FIXED_POINT_TYPE)
|
&& TREE_CODE (type) != FIXED_POINT_TYPE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!is_widening_mult_rhs_p (gimple_assign_rhs1 (stmt), type1_out, rhs1_out))
|
if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
|
||||||
|
rhs1_out))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!is_widening_mult_rhs_p (gimple_assign_rhs2 (stmt), type2_out, rhs2_out))
|
if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
|
||||||
|
rhs2_out))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (*type1_out == NULL)
|
if (*type1_out == NULL)
|
||||||
|
@ -2089,7 +2093,7 @@ convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi)
|
||||||
if (TREE_CODE (type) != INTEGER_TYPE)
|
if (TREE_CODE (type) != INTEGER_TYPE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2))
|
if (!is_widening_mult_p (type, stmt, &type1, &rhs1, &type2, &rhs2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
to_mode = TYPE_MODE (type);
|
to_mode = TYPE_MODE (type);
|
||||||
|
@ -2255,7 +2259,7 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
|
||||||
if (code == PLUS_EXPR
|
if (code == PLUS_EXPR
|
||||||
&& (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
|
&& (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
|
||||||
{
|
{
|
||||||
if (!is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
|
if (!is_widening_mult_p (type, rhs1_stmt, &type1, &mult_rhs1,
|
||||||
&type2, &mult_rhs2))
|
&type2, &mult_rhs2))
|
||||||
return false;
|
return false;
|
||||||
add_rhs = rhs2;
|
add_rhs = rhs2;
|
||||||
|
@ -2263,7 +2267,7 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
|
||||||
}
|
}
|
||||||
else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
|
else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
|
||||||
{
|
{
|
||||||
if (!is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
|
if (!is_widening_mult_p (type, rhs2_stmt, &type1, &mult_rhs1,
|
||||||
&type2, &mult_rhs2))
|
&type2, &mult_rhs2))
|
||||||
return false;
|
return false;
|
||||||
add_rhs = rhs1;
|
add_rhs = rhs1;
|
||||||
|
|
Loading…
Reference in New Issue