Bug 25979 - [4.0 Regression] incorrect codegen for conditional [SVO issue]
Summary: [4.0 Regression] incorrect codegen for conditional [SVO issue]
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.1
: P1 critical
Target Milestone: 4.0.3
Assignee: Jason Merrill
URL:
Keywords: wrong-code
Depends on: 25977
Blocks: 16405
  Show dependency treegraph
 
Reported: 2006-01-26 17:29 UTC by Howard Hinnant
Modified: 2006-02-11 00:51 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.0
Known to fail: 4.0.3 4.1.0 4.2.0
Last reconfirmed: 2006-01-27 20:09:50


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Howard Hinnant 2006-01-26 17:29:36 UTC
I'm not positive whether or not this is a duplicate of 25895.  I figured I'd better enter it just in case it wasn't.  Test case:

#include <stdio.h>

struct A
{
    A() : data1_(0), data2_(0) {}
    A(int i, int j) : data1_(i), data2_(j) {}
    A operator+(int);
    friend A operator+(int, const A&);
    ~A() {}
//private:
    int data1_;
    int data2_;
};

extern bool x;

void display(const A& x)
{
    printf("%d %d\n", x.data1_, x.data2_);
}

int main()
{
    A a1(1,2);
    a1 = (x ? a1 + 3 : 3 + a1);
    display(a1);
}

bool x = false;

A
A::operator+(int i)
{
    A a;
    a = *this;
    a.data2_ = i;
    return a;
}

A
operator+(int i, const A& x)
{
    A a;
    a = x;
    a.data1_ = i;
    return a;
}

Output:

3 0

Expected output:

3 2

The gimple tree (-fdump-tree-gimple) is showing statements like:

              operator+ (&a1, 3, &a1) [return slot addr];

which shoud instead be:

             operator+ (temp, 3, &a1) [return slot addr];
             ...
             a1 = temp;

The bad codegen is sensitive to the presence or absence of special member functions.  For example if you comment out ~A(), you get the expected output.
Comment 1 Andrew Pinski 2006-01-26 17:31:19 UTC
This is actually a dup of bug 25977.  But I think it was worked around in 4.0.2 (or maybe just 4.0.3, I have to double check that).
Comment 2 Andrew Pinski 2006-01-26 17:36:40 UTC
It was worked around in 4.0.2 (done on 2005-04-05 23:13:35) by:

        PR c++/19317
        * calls.c (expand_call): Disable return slot optimization.

Which just disabled the return slot optimization for 4.0.x

Now 4.1.0 never got that patch but a different one which fixed a similar bug (PR 19317) but it did not fix this one or the duplicated one.

*** This bug has been marked as a duplicate of 25977 ***
Comment 3 Andrew Pinski 2006-01-26 17:39:56 UTC
Actually this is not a full dup as this one is also still broken on the 4.0 branch.
Comment 4 Andrew Pinski 2006-01-26 17:43:24 UTC
Confirmed, very much related to PR 25977.  Though I think this and PR 25977 are almost the same bug as we get:
TARGET_EXPR <D.3014, <<< Unknown tree: aggr_init_expr
  operator+
  3, (struct A &) (struct A *) &a1
  D.3014 >>>

We are losing some piece of information.
Comment 5 Mark Mitchell 2006-02-01 03:07:56 UTC
Jason, do you have an ETA on this bug?
Comment 6 Jason Merrill 2006-02-03 21:56:07 UTC
Subject: Bug 25979

Author: jason
Date: Fri Feb  3 21:56:03 2006
New Revision: 110564

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110564
Log:
        PR c++/25979
        * gimplify.c (gimplify_modify_expr_rhs): Disable *& optimization for now.

        PR middle-end/25977
        * gimplify.c (gimplify_modify_expr_rhs): It's not always safe to do RVO
        on the return slot if it's an NRV.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/nrv10.C
    branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/nrv11.C
Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/gimplify.c
    branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/temp1.C

Comment 7 Jason Merrill 2006-02-03 21:57:11 UTC
Subject: Bug 25979

Author: jason
Date: Fri Feb  3 21:57:08 2006
New Revision: 110565

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110565
Log:
        PR c++/25979
        * gimplify.c (gimplify_modify_expr_rhs): Disable *& optimization for now.

        PR middle-end/25977
        * gimplify.c (gimplify_modify_expr_rhs): It's not always safe to do RVO
        on the return slot if it's an NRV.

Added:
    trunk/gcc/testsuite/g++.dg/opt/nrv10.C
    trunk/gcc/testsuite/g++.dg/opt/nrv11.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimplify.c
    trunk/gcc/testsuite/g++.dg/opt/temp1.C

Comment 8 Jason Merrill 2006-02-03 21:59:17 UTC
Fixed in 4.1 and 4.2 by disabling the fix for c++/16405 (a missed optimization regression).  Working on a better fix.
Comment 9 Steven Bosscher 2006-02-04 10:34:47 UTC
No longer a 4.1/4.2 regression.
Comment 10 Jason Merrill 2006-02-09 09:54:42 UTC
Subject: Bug 25979

Author: jason
Date: Thu Feb  9 09:54:36 2006
New Revision: 110789

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110789
Log:
        PR c++/25979
        * tree.def: Elaborate on difference from MODIFY_EXPR.
        * doc/c-tree.texi (INIT_EXPR): Likewise.
        * gimplify.c (internal_get_tmp_var): Use INIT_EXPR.
        (gimplify_decl_expr, gimplify_init_ctor_eval): Likewise.
        (gimplify_target_expr): Likewise.
        (gimplify_cond_expr): Remove target handling.
        (gimplify_modify_expr): Don't clobber INIT_EXPR code here.
        (gimplify_expr): Clobber it here.
        (gimplify_modify_expr_rhs): Push assignment into COND_EXPR here.
        Do return slot optimization if we have an INIT_EXPR.

        PR tree-opt/24365
        * tree-inline.c (declare_return_variable): Also clear
        DECL_COMPLEX_GIMPLE_REG_P as needed in the modify_dest case.

        PR c++/16405
        * gimplify.c (gimplify_modify_expr_rhs): Re-enable *& handling.

        PR middle-end/22439
        * gimplify.c (gimplify_one_sizepos): Fix typo.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-gimplify.c
    trunk/gcc/cp/typeck2.c
    trunk/gcc/doc/c-tree.texi
    trunk/gcc/gimplify.c
    trunk/gcc/testsuite/g++.dg/opt/temp1.C
    trunk/gcc/tree-inline.c
    trunk/gcc/tree.def

Comment 11 Jason Merrill 2006-02-10 17:32:14 UTC
Subject: Bug 25979

Author: jason
Date: Fri Feb 10 17:32:10 2006
New Revision: 110838

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110838
Log:
        PR c++/25979
        * tree.def: Elaborate on difference from MODIFY_EXPR.
        * doc/c-tree.texi (INIT_EXPR): Likewise.
        * gimplify.c (internal_get_tmp_var): Use INIT_EXPR.
        (gimplify_decl_expr, gimplify_init_ctor_eval): Likewise.
        (gimplify_target_expr): Likewise.
        (gimplify_cond_expr): Remove target handling.
        (gimplify_modify_expr): Don't clobber INIT_EXPR code here.
        (gimplify_expr): Clobber it here.
        (gimplify_modify_expr_rhs): Push assignment into COND_EXPR here.
        Do return slot optimization if we have an INIT_EXPR.

        PR tree-opt/24365
        * tree-inline.c (declare_return_variable): Also clear
        DECL_COMPLEX_GIMPLE_REG_P as needed in the modify_dest case.

        PR c++/16405
        * gimplify.c (gimplify_modify_expr_rhs): Re-enable *& handling.

        PR middle-end/22439
        * gimplify.c (gimplify_one_sizepos): Fix typo.

Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/cp/ChangeLog
    branches/gcc-4_1-branch/gcc/cp/cp-gimplify.c
    branches/gcc-4_1-branch/gcc/cp/typeck2.c
    branches/gcc-4_1-branch/gcc/doc/c-tree.texi
    branches/gcc-4_1-branch/gcc/gimplify.c
    branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/temp1.C
    branches/gcc-4_1-branch/gcc/tree-inline.c
    branches/gcc-4_1-branch/gcc/tree.def

Comment 12 Jason Merrill 2006-02-11 00:19:35 UTC
Subject: Bug 25979

Author: jason
Date: Sat Feb 11 00:19:30 2006
New Revision: 110864

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110864
Log:
        PR c++/25979
        * tree.def: Elaborate on difference from MODIFY_EXPR.
        * doc/c-tree.texi (INIT_EXPR): Likewise.
        * cp/cp-gimplify.c (cp_gimplify_expr): Don't call
        cp_gimplify_init_expr for MODIFY_EXPRs.
        * cp/typeck2.c (split_nonconstant_init_1): Use INIT_EXPR.
        * gimplify.c (internal_get_tmp_var): Likewise.
        (gimplify_decl_expr, gimplify_init_ctor_eval): Likewise.
        (gimplify_target_expr): Likewise.
        (gimplify_cond_expr): Remove target handling.
        (gimplify_modify_expr): Don't clobber INIT_EXPR code here.
        (gimplify_expr): Clobber it here.
        (gimplify_modify_expr_rhs): Push assignment into COND_EXPR here.
        Do return slot optimization if we have an INIT_EXPR.

        PR middle-end/22439
        * gimplify.c (gimplify_one_sizepos): Fix typo.

Modified:
    branches/gcc-4_0-branch/gcc/ChangeLog
    branches/gcc-4_0-branch/gcc/cp/ChangeLog
    branches/gcc-4_0-branch/gcc/cp/cp-gimplify.c
    branches/gcc-4_0-branch/gcc/cp/typeck2.c
    branches/gcc-4_0-branch/gcc/doc/c-tree.texi
    branches/gcc-4_0-branch/gcc/gimplify.c
    branches/gcc-4_0-branch/gcc/tree.def

Comment 13 Andrew Pinski 2006-02-11 00:51:46 UTC
Fixed.