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

            Bug ID: 119720
           Summary: phiopt introduces out-of-bounds reads
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kristerw at gcc dot gnu.org
  Target Milestone: ---

phiopt2 miscompiles the following program when targeting x86_64 with the
options "-O3 -fno-strict-aliasing":

struct s {
  int a;
  int b;
};

int foo(int c, struct s *p)
{
  int t;
  if (c)
    t = p->a;
  else
    t = p->b;
  return t;
}


The GIMPLE before phiopt2 looks like this:

int foo (int c, struct s * p)
{
  int t;

  <bb 2> :
  if (c_2(D) != 0)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3> :
  t_6 = p_4(D)->a;
  goto <bb 5>;

  <bb 4> :
  t_5 = p_4(D)->b;

  <bb 5> :
  # t_1 = PHI <t_6(3), t_5(4)>
  return t_1;
}

This is valid for c == 1 when p points to a 4-byte buffer, even though the full
structure does not fit. But phiopt2 hoists both loads, causing t_5 to read out
of bounds:

int foo (int c, struct s * p)
{
  int t;

  <bb 2> :
  t_6 = p_4(D)->a;
  t_5 = p_4(D)->b;
  if (c_2(D) != 0)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3> :
  goto <bb 5>; [100.00%]

  <bb 4> :

  <bb 5> :
  # t_1 = PHI <t_6(3), t_5(4)>
  return t_1;
}

Reply via email to