Commit 6a228c2c by Andrew Stubbs Committed by Andrew Stubbs

tree-ssa-math-opts.c (convert_mult_to_widen): Better handle unsigned inputs of different modes.

2011-08-19  Andrew Stubbs  <ams@codesourcery.com>

	gcc/
	* tree-ssa-math-opts.c (convert_mult_to_widen): Better handle
	unsigned inputs of different modes.
	(convert_plusminus_to_widen): Likewise.

	gcc/testsuite/
	* gcc.target/arm/wmul-9.c: New file.
	* gcc.target/arm/wmul-bitfield-2.c: New file.

From-SVN: r177908
parent 26a855d7
2011-08-19 Andrew Stubbs <ams@codesourcery.com> 2011-08-19 Andrew Stubbs <ams@codesourcery.com>
* tree-ssa-math-opts.c (convert_mult_to_widen): Better handle
unsigned inputs of different modes.
(convert_plusminus_to_widen): Likewise.
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
* tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument * tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument
'type'. 'type'.
Use 'type' from caller, not inferred from 'rhs'. Use 'type' from caller, not inferred from 'rhs'.
......
2011-08-19 Andrew Stubbs <ams@codesourcery.com> 2011-08-19 Andrew Stubbs <ams@codesourcery.com>
* gcc.target/arm/wmul-9.c: New file.
* gcc.target/arm/wmul-bitfield-2.c: New file.
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
* gcc.target/arm/wmul-8.c: New file. * gcc.target/arm/wmul-8.c: New file.
2011-08-19 Andrew Stubbs <ams@codesourcery.com> 2011-08-19 Andrew Stubbs <ams@codesourcery.com>
......
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-require-effective-target arm_dsp } */
long long
foo (long long a, short *b, char *c)
{
return a + *b * *c;
}
/* { dg-final { scan-assembler "smlalbb" } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-require-effective-target arm_dsp } */
struct bf
{
int a : 3;
unsigned int b : 15;
int c : 3;
};
long long
foo (long long a, struct bf b, struct bf c)
{
return a + b.b * c.c;
}
/* { dg-final { scan-assembler "smlalbb" } } */
...@@ -2115,9 +2115,18 @@ convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi) ...@@ -2115,9 +2115,18 @@ convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi)
{ {
if (op != smul_widen_optab) if (op != smul_widen_optab)
{ {
from_mode = GET_MODE_WIDER_MODE (from_mode); /* We can use a signed multiply with unsigned types as long as
if (GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode)) there is a wider mode to use, or it is the smaller of the two
return false; types that is unsigned. Note that type1 >= type2, always. */
if ((TYPE_UNSIGNED (type1)
&& TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
|| (TYPE_UNSIGNED (type2)
&& TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
{
from_mode = GET_MODE_WIDER_MODE (from_mode);
if (GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
return false;
}
op = smul_widen_optab; op = smul_widen_optab;
handler = find_widening_optab_handler_and_mode (op, to_mode, handler = find_widening_optab_handler_and_mode (op, to_mode,
...@@ -2284,14 +2293,20 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, ...@@ -2284,14 +2293,20 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
/* There's no such thing as a mixed sign madd yet, so use a wider mode. */ /* There's no such thing as a mixed sign madd yet, so use a wider mode. */
if (from_unsigned1 != from_unsigned2) if (from_unsigned1 != from_unsigned2)
{ {
enum machine_mode mode = GET_MODE_WIDER_MODE (from_mode); /* We can use a signed multiply with unsigned types as long as
if (GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (to_mode)) there is a wider mode to use, or it is the smaller of the two
types that is unsigned. Note that type1 >= type2, always. */
if ((from_unsigned1
&& TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
|| (from_unsigned2
&& TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
{ {
from_mode = mode; from_mode = GET_MODE_WIDER_MODE (from_mode);
from_unsigned1 = from_unsigned2 = false; if (GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
return false;
} }
else
return false; from_unsigned1 = from_unsigned2 = false;
} }
/* If there was a conversion between the multiply and addition /* If there was a conversion between the multiply and addition
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment