This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix multiply-add regressions after expand-from-SSA
- From: Adam Nemet <anemet at caviumnetworks dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: matz at suse dot de, rguenther at suse dot de
- Date: Thu, 30 Apr 2009 00:34:15 -0700
- Subject: [PATCH] Fix multiply-add regressions after expand-from-SSA
This fixes the MIPS madd* and msub* regressions from:
http://gcc.gnu.org/ml/gcc-testresults/2009-04/msg03063.html
We now need to look at the TERed expressions for the operands to find the
underlying multiplications and casts.
OK if regtest/bootstrap passes on mips64octeon-linux?
Adam
* expr.c (substitute_ter_expr): New function.
(expand_expr_real_1) <PLUS_EXPR, MINUS_EXPR>: Use it when looking
at operands.
Index: expr.c
===================================================================
--- expr.c (revision 146915)
+++ expr.c (working copy)
@@ -6992,6 +6992,23 @@ expand_constructor (tree exp, rtx target
return target;
}
+/* If EXP is an SSA_NAME and has a TER expression return that.
+ Otherwise return EXP. */
+
+static tree
+substitute_ter_expr (tree exp)
+{
+ gimple g;
+
+ if (TREE_CODE (exp) != SSA_NAME)
+ return exp;
+ g = get_gimple_for_ssa_name (exp);
+ if (!g)
+ return exp;
+
+ return gimple_assign_rhs_to_tree (g);
+}
+
/* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
@@ -8322,14 +8339,14 @@ expand_expr_real_1 (tree exp, rtx target
/* Check if this is a case for multiplication and addition. */
if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == FIXED_POINT_TYPE)
- && TREE_CODE (TREE_OPERAND (exp, 0)) == MULT_EXPR)
+ && (subexp0 = substitute_ter_expr (TREE_OPERAND (exp, 0)))
+ && TREE_CODE (subexp0) == MULT_EXPR)
{
tree subsubexp0, subsubexp1;
enum tree_code code0, code1, this_code;
- subexp0 = TREE_OPERAND (exp, 0);
- subsubexp0 = TREE_OPERAND (subexp0, 0);
- subsubexp1 = TREE_OPERAND (subexp0, 1);
+ subsubexp0 = substitute_ter_expr (TREE_OPERAND (subexp0, 0));
+ subsubexp1 = substitute_ter_expr (TREE_OPERAND (subexp0, 1));
code0 = TREE_CODE (subsubexp0);
code1 = TREE_CODE (subsubexp1);
this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR
@@ -8485,14 +8502,14 @@ expand_expr_real_1 (tree exp, rtx target
/* Check if this is a case for multiplication and subtraction. */
if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == FIXED_POINT_TYPE)
- && TREE_CODE (TREE_OPERAND (exp, 1)) == MULT_EXPR)
+ && (subexp1 = substitute_ter_expr (TREE_OPERAND (exp, 1)))
+ && TREE_CODE (subexp1) == MULT_EXPR)
{
tree subsubexp0, subsubexp1;
enum tree_code code0, code1, this_code;
- subexp1 = TREE_OPERAND (exp, 1);
- subsubexp0 = TREE_OPERAND (subexp1, 0);
- subsubexp1 = TREE_OPERAND (subexp1, 1);
+ subsubexp0 = substitute_ter_expr (TREE_OPERAND (subexp1, 0));
+ subsubexp1 = substitute_ter_expr (TREE_OPERAND (subexp1, 1));
code0 = TREE_CODE (subsubexp0);
code1 = TREE_CODE (subsubexp1);
this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR