https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83660

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
--- gcc/config/rs6000/rs6000-c.c.jj     2018-03-15 08:36:26.526776571 +0100
+++ gcc/config/rs6000/rs6000-c.c        2018-03-21 17:10:04.340935624 +0100
@@ -6649,6 +6649,14 @@ altivec_resolve_overloaded_builtin (loca
       stmt = convert (innerptrtype, stmt);
       stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
       stmt = build_indirect_ref (loc, stmt, RO_NULL);
+      if (c_dialect_cxx ())
+       {
+         /* Add a CLEANUP_POINT_EXPR for the above TARGET_EXPR, as it doesn't
+            need to live after the INDIRECT_REF.  Force side-effects, so that
+            it isn't optimized away.  */
+         TREE_SIDE_EFFECTS (stmt) = 1;
+         stmt = build1_loc (loc, CLEANUP_POINT_EXPR, TREE_TYPE (stmt), stmt);
+       }

       return stmt;
     }

seems to fix this, maybe in some cases it would be enough to force
TREE_SIDE_EFFECTS, e.g. on this testcase finish_stmt_expr_expr has:
          /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a
             normal statement, but don't convert to void or actually add
             the EXPR_STMT.  */
          if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
            expr = maybe_cleanup_point_expr (expr);

Without TREE_SIDE_EFFECTS though maybe_cleanup_point_expr doesn't add anything,
and even if we add it ourselves (e.g. the above patch with TREE_SIDE_EFFECTS
(stmt) = 1; removed), then cp_fold will optimize the CLEANUP_POINT_EXPR away. 
And the CLEANUP_POINT_EXPR is essential during gimplification, so that we know
where the TARGET_EXPR decl rs6000 has added actually dies and where we can emit
the clobber.

Note, for ALTIVEC_BUILTIN_VEC_INSERT it contains similar code, but I'm afraid I
have no idea where to insert that CLEANUP_POINT_EXPR, because it does:
      stmt = build_indirect_ref (loc, stmt, RO_NULL);
      stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
                     convert (TREE_TYPE (stmt), arg0));
      stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
and decl is the TARGET_EXPRs temporary.  The return value of the builtin is
non-lvalue though, right?  So maybe just wrapping that similarly to the above
would work, or wrap the last argument of the COMPOUND_EXPR into NON_LVALUE_EXPR
or something similar first?

Reply via email to