http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55761
--- Comment #4 from Paulo J. Matos <pa...@matos-sorge.com> 2012-12-20 16:58:08 UTC --- I created a new patch from your comment to gcc-patches: diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 5b1fd2b..8c7d142 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -326,26 +326,14 @@ process_assignment (gimple stmt, gimple_stmt_iterator call return true; case NEGATE_EXPR: - if (FLOAT_TYPE_P (TREE_TYPE (op0))) - *m = build_real (TREE_TYPE (op0), dconstm1); - else - *m = build_int_cst (TREE_TYPE (op0), -1); - + *m = fold_unary (NEGATE_EXPR, TREE_TYPE (op0), op0); *ass_var = dest; return true; case MINUS_EXPR: - if (*ass_var == op0) - *a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); - else - { - if (FLOAT_TYPE_P (TREE_TYPE (non_ass_var))) - *m = build_real (TREE_TYPE (non_ass_var), dconstm1); - else - *m = build_int_cst (TREE_TYPE (non_ass_var), -1); - - *a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); - } + *a = fold_unary (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); + if (*ass_var == op1) + *m = fold_unary (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); *ass_var = dest; return true; However, I am less confident that it works now. Mainly because of the *m in MINUS_EXPR. It seems from the comments in tailcall structure that m should be -1, not (NEGATE non_ass_var). However, we cannot really create a -1 for vectors straightforwardly. I guess that, as per your comment below, we would need a build_minus_one_cst that handles not only scalar types but also vector types.