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