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

            Bug ID: 107709
           Summary: IVOPTs is introducing a non-zero assumption
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amacleod at redhat dot com
  Target Milestone: ---

Ive been working on fixing https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78655 ,
which basically adds an inferred range to

  ptr1 = ptr2 + non-zero-const

such that ptr2 will be non-zero after this statement.  Ive spent the last
couple of days trying to figure out why fortran is failing in a bootstrap, and
I think I finally have it figured out.  fortran/scanner.c is being miscompiled
at -O2, and it boils down to the following testcase:

char *nextc;

void huh ()
{
  int i;
  char c;

  for (i = 0; i < 5; i++)
    {
      c = (nextc == 0) ? '\n' : *nextc++;
      if (c != ' ')
        break;
    }
}

The very beginning of this function, just before going into ivopts, looks like:

  char * prephitmp_3;
  char * pretmp_4;
  unsigned int ivtmp_14;
  unsigned int ivtmp_15;

  <bb 2> [local count: 243289824]:
  pretmp_4 = nextc;

  <bb 3> [local count: 894749065]:
  # prephitmp_3 = PHI <_2(7), pretmp_4(2)>
  # ivtmp_14 = PHI <ivtmp_15(7), 5(2)>
  if (prephitmp_3 != 0B)
    goto <bb 5>; [96.34%]
  else
    goto <bb 8>; [3.66%]

  <bb 8> [local count: 32747817]:

  <bb 4> [local count: 243289824]:
  return;

note that prephitmp_3 will be pretmp4 to start the loop (edge 2->3), and then
it is checked against 0 (NULL) and processing only continues to BB5 if it isnt
NULL.

After IVOPTS runs, this is transformed into:

 <bb 2> [local count: 243289824]:
  pretmp_4 = nextc;
  _12 = pretmp_4 + 5;              <-- New introduction

  <bb 3> [local count: 894749065]:
  # prephitmp_3 = PHI <_2(7), pretmp_4(2)>
  if (prephitmp_3 != 0B)
    goto <bb 5>; [96.34%]
  else
    goto <bb 8>; [3.66%]

  <bb 8> [local count: 32747817]:

  <bb 4> [local count: 243289824]:
  return;

Note it has added
   _12 = pretmp_4 + 5
to basic block 2.

With the new code to instruct VRP that ptr1 = ptr2 + const  means ptr2 is
non-null,  it now propagates a range of [+1, +INF] for pretmp_4 on the edge
2->3, and that allows the condition which checks prephitmp_3 != 0 to be folded,
as _2 is always non-zero as well.

It seems that IVOPTS should not be adding that statement into BB2? It is
introducing a non-zero assumption that is not there before.

Reply via email to