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

--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>:

https://gcc.gnu.org/g:12de1942a0a673f9f2f1c2bfce4279a666061ffc

commit r15-6052-g12de1942a0a673f9f2f1c2bfce4279a666061ffc
Author: Marek Polacek <pola...@redhat.com>
Date:   Thu Aug 29 12:58:41 2024 -0400

    c++: compile time evaluation of prvalues [PR116416]

    This PR reports a missed optimization.  When we have:

      Str str{"Test"};
      callback(str);

    as in the test, we're able to evaluate the Str::Str() call at compile
    time.  But when we have:

      callback(Str{"Test"});

    we are not.  With this patch (in fact, it's Patrick's patch with a little
    tweak), we turn

      callback (TARGET_EXPR <D.2890, <<< Unknown tree: aggr_init_expr
        5
        __ct_comp
        D.2890
        (struct Str *) <<< Unknown tree: void_cst >>>
        (const char *) "Test" >>>>)

    into

      callback (TARGET_EXPR <D.2890, {.str=(const char *) "Test", .length=4}>)

    I explored the idea of calling maybe_constant_value for the whole
    TARGET_EXPR in cp_fold.  That has three problems:
    - we can't always elide a TARGET_EXPR, so we'd have to make sure the
      result is also a TARGET_EXPR;
    - the resulting TARGET_EXPR must have the same flags, otherwise Bad
      Things happen;
    - getting a new slot is also problematic.  I've seen a test where we
      had "TARGET_EXPR<D.2680, ...>, D.2680", and folding the whole TARGET_EXPR
      would get us "TARGET_EXPR<D.2681, ...>", but since we don't see the outer
      D.2680, we can't replace it with D.2681, and things break.

    With this patch, two tree-ssa tests regressed: pr78687.C and pr90883.C.

    FAIL: g++.dg/tree-ssa/pr90883.C   scan-tree-dump dse1 "Deleted redundant
store: .*.a = {}"
    is easy.  Previously, we would call C::C, so .gimple has:

      D.2590 = {};
      C::C (&D.2590);
      D.2597 = D.2590;
      return D.2597;

    Then .einline inlines the C::C call:

      D.2590 = {};
      D.2590.a = {}; // #1
      D.2590.b = 0;  // #2
      D.2597 = D.2590;
      D.2590 ={v} {CLOBBER(eos)};
      return D.2597;

    then #2 is removed in .fre1, and #1 is removed in .dse1.  So the test
    passes.  But with the patch, .gimple won't have that C::C call, so the
    IL is of course going to look different.  The .optimized dump looks the
    same though so there's no problem.

    pr78687.C is XFAILed because the test passes with r15-5746 but not with
    r15-5747 as well.  I opened <https://gcc.gnu.org/PR117971>.

            PR c++/116416

    gcc/cp/ChangeLog:

            * cp-gimplify.cc (cp_fold_r) <case TARGET_EXPR>: Try to fold
            TARGET_EXPR_INITIAL and replace it with the folded result if
            it's TREE_CONSTANT.

    gcc/testsuite/ChangeLog:

            * g++.dg/analyzer/pr97116.C: Adjust dg-message.
            * g++.dg/tree-ssa/pr78687.C: Add XFAIL.
            * g++.dg/tree-ssa/pr90883.C: Adjust dg-final.
            * g++.dg/cpp0x/constexpr-prvalue1.C: New test.
            * g++.dg/cpp1y/constexpr-prvalue1.C: New test.

    Co-authored-by: Patrick Palka <ppa...@redhat.com>
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Reply via email to