There are many cases where the widening_mult pass does not recognise widening multiply-and-accumulate cases simply because there is a type conversion step between the multiply and add statements.

This patch should rectify that simply by looking beyond those conversions.

OK?

Andrew

2011-06-23  Andrew Stubbs  <a...@codesourcery.com>

	gcc/
	* tree-ssa-math-opts.c (convert_plusminus_to_widen): Look for
	multiply statement beyond NOP_EXPR statements.

	gcc/testsuite/
	* gcc.target/arm/umlal-1.c: New file.

--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/umlal-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv7-a" } */
+
+long long
+foo (long long a, char *b, char *c)
+{
+  return a + *b * *c;
+}
+
+/* { dg-final { scan-assembler "umlal" } } */
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -2114,26 +2114,39 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
   else
     wmult_code = WIDEN_MULT_PLUS_EXPR;
 
-  rhs1 = gimple_assign_rhs1 (stmt);
-  rhs2 = gimple_assign_rhs2 (stmt);
-
-  if (TREE_CODE (rhs1) == SSA_NAME)
+  rhs1_stmt = stmt;
+  do
     {
-      rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
-      if (is_gimple_assign (rhs1_stmt))
-	rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
+      rhs1_code = ERROR_MARK;
+      rhs1 = gimple_assign_rhs1 (rhs1_stmt);
+
+      if (TREE_CODE (rhs1) == SSA_NAME)
+	{
+	  rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
+	  if (is_gimple_assign (rhs1_stmt))
+	    rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
+	}
+      else
+	return false;
     }
-  else
-    return false;
+  while (rhs1_code == NOP_EXPR);
 
-  if (TREE_CODE (rhs2) == SSA_NAME)
+  rhs2_stmt = stmt;
+  do
     {
-      rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
-      if (is_gimple_assign (rhs2_stmt))
-	rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
+      rhs2_code = ERROR_MARK;
+      rhs2 = gimple_assign_rhs2 (rhs2_stmt);
+
+      if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
+	{
+	  rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
+	  if (is_gimple_assign (rhs2_stmt))
+	    rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
+	}
+      else
+	return false;
     }
-  else
-    return false;
+  while (rhs2_code == NOP_EXPR);
 
   if (code == PLUS_EXPR && rhs1_code == MULT_EXPR)
     {

Reply via email to