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

login
register
mail settings
Submitter Andrew Stubbs
Date July 18, 2011, 1:14 p.m.
Message ID <4E24319D.3040607@codesourcery.com>
Download mbox | patch
Permalink /patch/105272/
State New
Headers show

Comments

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
Richard Guenther - July 18, 2011, 2:46 p.m.
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));