Appearantly we didn't exercise this before and thus it has gone
unnoticed that we don't properly special case single-RHSs on
GIMPLE.

Fixed as follows.

Bootstrapped on x86_64-unknown-linux-gnu, applied.

Richard.

2014-09-02  Richard Biener  <rguent...@suse.de>

        * gimple-match-head.c (maybe_build_generic_op): New function.
        (maybe_push_res_to_seq): Use it.
        * gimple-match.h (maybe_build_generic_op): Declare.
        * gimple-fold.c (fold_stmt_1): Use maybe_build_generic_op.

Index: gcc/gimple-match-head.c
===================================================================
--- gcc/gimple-match-head.c     (revision 214795)
+++ gcc/gimple-match-head.c     (working copy)
@@ -267,6 +267,27 @@ gimple_resimplify3 (gimple_seq *seq,
 }
 
 
+/* If in GIMPLE expressions with CODE go as single-rhs build
+   a GENERIC tree for that expression into *OP0.  */
+
+void
+maybe_build_generic_op (enum tree_code code, tree type,
+                       tree *op0, tree op1, tree op2)
+{
+  switch (code)
+    {
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
+    case VIEW_CONVERT_EXPR:
+      *op0 = build1 (code, type, *op0);
+      break;
+    case BIT_FIELD_REF:
+      *op0 = build3 (code, type, *op0, op1, op2);
+      break;
+    default:;
+    }
+}
+
 /* Push the exploded expression described by RCODE, TYPE and OPS
    as a statement to SEQ if necessary and return a gimple value
    denoting the value of the expression.  If RES is not NULL
@@ -286,8 +307,6 @@ maybe_push_res_to_seq (code_helper rcode
        return ops[0];
       if (!seq)
        return NULL_TREE;
-      if (!res)
-       res = make_ssa_name (type, NULL);
       /* Play safe and do not allow abnormals to be mentioned in
          newly created statements.  */
       if ((TREE_CODE (ops[0]) == SSA_NAME
@@ -299,6 +318,9 @@ maybe_push_res_to_seq (code_helper rcode
              && TREE_CODE (ops[2]) == SSA_NAME
              && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
        return NULL_TREE;
+      if (!res)
+       res = make_ssa_name (type, NULL);
+      maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
       gimple new_stmt = gimple_build_assign_with_ops (rcode, res,
                                                      ops[0], ops[1], ops[2]);
       gimple_seq_add_stmt_without_update (seq, new_stmt);
@@ -311,8 +333,6 @@ maybe_push_res_to_seq (code_helper rcode
       tree decl = builtin_decl_implicit (rcode);
       if (!decl)
        return NULL_TREE;
-      if (!res)
-       res = make_ssa_name (type, NULL);
       unsigned nargs = type_num_arguments (TREE_TYPE (decl));
       gcc_assert (nargs <= 3);
       /* Play safe and do not allow abnormals to be mentioned in
@@ -326,6 +346,8 @@ maybe_push_res_to_seq (code_helper rcode
              && TREE_CODE (ops[2]) == SSA_NAME
              && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
        return NULL_TREE;
+      if (!res)
+       res = make_ssa_name (type, NULL);
       gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], 
ops[2]);
       gimple_call_set_lhs (new_stmt, res);
       gimple_seq_add_stmt_without_update (seq, new_stmt);
Index: gcc/gimple-match.h
===================================================================
--- gcc/gimple-match.h  (revision 214795)
+++ gcc/gimple-match.h  (working copy)
@@ -44,6 +44,7 @@ bool gimple_simplify (gimple, code_helpe
                      tree (*)(tree));
 tree maybe_push_res_to_seq (code_helper, tree, tree *,
                            gimple_seq *, tree res = NULL_TREE);
+void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
 
 
 #endif  /* GCC_GIMPLE_MATCH_H */
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   (revision 214795)
+++ gcc/gimple-fold.c   (working copy)
@@ -2904,6 +2904,9 @@ fold_stmt_1 (gimple_stmt_iterator *gsi,
                           && TREE_CODE (ops[2]) == SSA_NAME
                           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2]))))
                {
+                 maybe_build_generic_op (rcode,
+                                         TREE_TYPE (gimple_assign_lhs (stmt)),
+                                         &ops[0], ops[1], ops[2]);
                  gimple_assign_set_rhs_with_ops_1 (gsi, rcode,
                                                    ops[0], ops[1], ops[2]);
                  if (dump_file && (dump_flags & TDF_DETAILS))

Reply via email to