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

Submitted by Andrew Stubbs on July 18, 2011, 1:14 p.m.

Details

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 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 hide | download patch | download mbox

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));