[(8/7)] Fix a bug in multiply-and-accumulate

Message ID 4E24319D.3040607@codesourcery.com
State New
Headers show

Commit Message

Andrew Stubbs July 18, 2011, 1:14 p.m.
As far as I can tell, the patch series so far works great as long as the 
input type of the accumulate value is the same as the output type. 
Unfortunately you get an ICE otherwise .... doh!

This patch should fix the problem.

I could have inserted this fix into the correct spot in the existing 
series, but I've already regenerated the whole lot several times, it's 
getting confusing, and they're all approved already, so I'm just going 
to tack this one on the end.

Andrew

Comments

Richard Biener July 18, 2011, 2:46 p.m. | #1
On Mon, Jul 18, 2011 at 3:14 PM, Andrew Stubbs <ams@codesourcery.com> wrote:
> As far as I can tell, the patch series so far works great as long as the
> input type of the accumulate value is the same as the output type.
> Unfortunately you get an ICE otherwise .... doh!
>
> This patch should fix the problem.
>
> I could have inserted this fix into the correct spot in the existing series,
> but I've already regenerated the whole lot several times, it's getting
> confusing, and they're all approved already, so I'm just going to tack this
> one on the end.

Will signedness be always the same?  Usually the canonical check to
use would be !useless_type_conversion_p (type, TREE_TYPE (add_rhs)).

Ok if you use that.

Thanks,
Richard.

> Andrew
>

Patch

2011-07-18  Andrew Stubbs  <ams@codesourcery.com>

	gcc/
	* tree-ssa-math-opts.c (convert_plusminus_to_widen): Convert add_rhs
	to the correct type.

	gcc/testsuite/
	* gcc.target/arm/wmul-10.c: New file.

--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/wmul-10.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv7-a" } */
+
+unsigned long long
+foo (unsigned short a, unsigned short *b, unsigned short *c)
+{
+  return (unsigned)a + (unsigned long long)*b * (unsigned long long)*c;
+}
+
+/* { dg-final { scan-assembler "umlal" } } */
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -2375,6 +2375,10 @@  convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
       mult_rhs2 = build_and_insert_cast (gsi, loc, tmp, mult_rhs2);
     }
 
+  if (TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (add_rhs)))
+    add_rhs = build_and_insert_cast (gsi, loc, create_tmp_var (type, NULL),
+				     add_rhs);
+
   gimple_assign_set_rhs_with_ops_1 (gsi, wmult_code, mult_rhs1, mult_rhs2,
 				    add_rhs);
   update_stmt (gsi_stmt (*gsi));