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

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

Comments

Andrew Stubbs - July 21, 2011, 1:14 p.m.
On 18/07/11 15:46, Richard Guenther wrote:
> Will signedness be always the same?  Usually the canonical check to
> use would be !useless_type_conversion_p (type, TREE_TYPE (add_rhs)).

The signedness ought to be unimportant - any extend will be based on the 
source type, and the signedness should not affect the addition 
operation. That said, it really ought to remain correct or else bad 
things could happen in later optimizations ....

Here is the patch I plan to commit, when patch 1 is approved, and my 
testing is complete.

Andrew
Andrew Stubbs - Aug. 19, 2011, 3:02 p.m.
On 21/07/11 14:14, Andrew Stubbs wrote:
> Here is the patch I plan to commit, when patch 1 is approved, and my
> testing is complete.

Committed, unchanged.

Andrew

Patch

2011-07-21  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,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target arm_dsp } */
+
+
+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 (!useless_type_conversion_p (type, 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));