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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |missed-optimization
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-11-09
                 CC|                            |rguenth at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
With public members the C++ FE emits

;; Function pair my::get(const other&) (null)
;; enabled by -tree-original


<<cleanup_point <<< Unknown tree: expr_stmt
  (void) (*NON_LVALUE_EXPR <((struct my *) this)->target> = *(struct pair &)
&TARGET_EXPR <D.2297, other::get ((const struct other *) other)>) >>>>>;
<<cleanup_point return <retval> = TARGET_EXPR <D.2337, ((struct my *)
this)->current>>>;

while with private members we end up with

<<cleanup_point <<< Unknown tree: expr_stmt
  MEM[(struct pair *)NON_LVALUE_EXPR <((struct my *) this)->target>] =
MEM[(struct pair *)(struct pair &) &TARGET_EXPR <D.2301, other::get ((const
struct other *) other)>];, <<< Unknown tree: void_cst >>> >>>>>;
<<cleanup_point return <retval> = TARGET_EXPR <D.2341, ((struct my *)
this)->current>>>;

that is, the only difference is we use a different type.  That's enough to
trigger
gimplification differences - with private members we emit

pair my::get(const other&) (struct my * const this, const struct other & other)
{
  struct pair D.2301;
  struct pair D.2343;

  D.2301 = other::get (other);
  try
    {
      _1 = this->target;
      MEM[(struct pair *)_1] = MEM[(struct pair *)&D.2301];
    }
  finally
    {
      D.2301 = {CLOBBER};
    }
  D.2343 = this->current;
  return D.2343;
}

while with public:

pair my::get(const other&) (struct my * const this, const struct other & other)
{
  struct pair D.2339;

  _1 = this->target;
  *_1 = other::get (other);
  D.2339 = this->current;
  return D.2339;
}

so we have an extra temporary forced upon us.  Not sure if middle-end
gimplification is confused by the different GENERIC or FE gimplification.

Reply via email to