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

            Bug ID: 123968
           Summary: complex lowering does extra work for VCE<ssa_name>
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: internal-improvement, missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---

Take:
```
typedef _Complex int t;
struct a
{
  int r;
  int i;
};

t f(struct a b)
{
  t c;
  __builtin_memcpy(&c,&b,sizeof(t));
  return c + 1;
}

struct a f1(t b)
{
  struct a c;
  b+=1;
  __builtin_memcpy(&c,&b,sizeof(t));
  return c;
}
```

Looking at f (f1 is fine).

Before complex lowering at -O1 we have:
```
  _1 = MEM <unsigned long> [(char * {ref-all})&b];
  c_3 = VIEW_CONVERT_EXPR<t>(_1);
  _4 = c_3 + __complex__ (1, 0);
```
Which is perfect and good.
After we get:
```
  _1 = MEM <unsigned long> [(char * {ref-all})&b];
  _6 = VIEW_CONVERT_EXPR<t>(_1);
  c$real_7 = REALPART_EXPR <_6>;
  _8 = VIEW_CONVERT_EXPR<t>(_1);
  c$imag_9 = IMAGPART_EXPR <_8>;
  _10 = c$real_7 + 1;
  _4 = COMPLEX_EXPR <_10, c$imag_9>;
```
Notice how we do `VIEW_CONVERT_EXPR<t>(_1)` twice now.
This is because complex lowering decided to expand the VCE and copy it.

I think we could do better using BFR in extract_component. I have not looked
into what float might do with BFR though; I think it should work (fre produces
it).


Note float testcase:
```
typedef _Complex float t;
struct a
{
  float r;
  float i;
};

t f(struct a b, t l)
{
  t c;
  __builtin_memcpy(&c,&b,sizeof(t));
  return c + l;
}

struct a f1(t b, t l)
{
  struct a c;
  b+=l;
  __builtin_memcpy(&c,&b,sizeof(t));
  return c;
}
```

Reply via email to