(split from PR19431)

#include <tr1/functional>
#include <algorithm>
extern void assign( long* variable, long v )
{
        std::transform( variable, variable + 1, variable,
                std::tr1::bind( std::plus< long >(), 0L, v ) );
}
extern void assign( long& variable, long v )
{
        std::transform( &variable, &variable + 1, &variable,
                std::tr1::bind( std::plus< long >(), 0L, v ) );
}

at -O3 gcc 4.2 produces:

assign(long&, long):
        movq    -40(%rsp), %rax
        movq    %rsi, -24(%rsp)
        movq    $0, -32(%rsp)
        movq    $0, -64(%rsp)
        movq    %rsi, -56(%rsp)
        movq    %rsi, (%rdi)
        movq    %rax, -72(%rsp)
        ret

assign(long*, long):
        movq    %rsi, (%rdi)
        ret

The problem is:

We start with

  D.59982_3 = variable_2(D) + 4B;
  __unary_op = __unary_op.65;
  goto <bb 4> (<L1>);

<L0>:;
  D.61146_10 = __unary_op._M_arg1;
  D.61147_11 = __unary_op._M_arg2;
  D.61093_12 = D.61146_10 + D.61147_11;
  *variable_13 = D.61093_12;
  variable_14 = variable_7 + 4B;
  variable_15 = variable_13 + 4B;

  # variable_7 = PHI <variable_2(D)(2), variable_14(3)>
  # variable_13 = PHI <variable_2(D)(2), variable_15(3)>
<L1>:;
  if (D.59982_3 != variable_7) goto <L0>; else goto <L2>;

and loop header copying and DOM make it optimizable:

  D.59982_3 = variable_2(D) + 4B;
  __unary_op.65._M_arg2 = v_1(D);
  __unary_op.65._M_arg1 = 0;
  __unary_op = __unary_op.65;
  __unary_op$_M_arg2_54 = __unary_op._M_arg2;
  __unary_op$_M_arg1_53 = __unary_op._M_arg1;
  if (variable_2(D) != D.59982_3) goto <L7>; else goto <L2>;

<L2>:;
  return;

  # variable_49 = PHI <variable_2(D)(2)>
  # variable_27 = PHI <variable_2(D)(2)>
<L7>:;
  __unary_op$_M_arg1_25 = __unary_op$_M_arg1_53;
  __unary_op$_M_arg2_17 = __unary_op$_M_arg2_54;
  D.61093_18 = __unary_op$_M_arg1_53 + __unary_op$_M_arg2_54;
  *variable_49 = D.61093_18;
  variable_20 = variable_27 + 4B;
  variable_21 = variable_49 + 4B;
  goto <bb 3> (<L2>);

so a tweaked forwprop fixes it at least before PRE.  But dunno if we want
to do tree combining on conditions here.  The code is optimized at
RTL expansion time.


-- 
           Summary: Fails to tree-combine conditions in COND_EXPRs
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Keywords: missed-optimization, TREE
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rguenth at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30965

Reply via email to