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?