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

            Bug ID: 79119
           Summary: absolute value of a pointer difference can be assumed
                    to be less than or equal to PTRDIFF_MAX
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

C and C++ guarantee that the difference between two pointers into the same
array must be representable in ptrdiff_t.  In addition, the absolute value of
the difference must be less than or equal to PTRDIFF_MAX / sizeof (T) where T
is the type of the array element.  The test case below shows that GCC doesn't
make use of the guarantee.  If it did, it should be able to determine that the
condition guarding the abort() statement in each of the functions below can
never evaluate to true.

$ cat t.c && gcc -O2 -S -fdump-tree-optimized=/dev/stdout t.c
void f (int *a, __SIZE_TYPE__ i, __SIZE_TYPE__ j)
{
  int *p = a + i;
  int *q = a + j;

  __SIZE_TYPE__ n = p < q ? q - p : p - q;

  if (n > __PTRDIFF_MAX__ / sizeof (int))
    __builtin_abort ();
}

void g (int *a, __SIZE_TYPE__ i, __SIZE_TYPE__ j)
{
  int *p = a + i;
  int *q = a + j;

  __SIZE_TYPE__ n = p < q ? q - p : p - q;

  if (n > __PTRDIFF_MAX__)
    __builtin_abort ();
}


;; Function f (f, funcdef_no=0, decl_uid=1445, cgraph_uid=0, symbol_order=0)

f (int * a, long unsigned int i, long unsigned int j)
{
  int * q;
  int * p;
  long unsigned int _1;
  long unsigned int _2;
  long int _3;
  long int _4;
  long int _5;
  long int _6;
  long unsigned int iftmp.0_7;
  long unsigned int iftmp.0_13;
  long unsigned int iftmp.0_14;
  long int _21;
  long int _22;

  <bb 2> [100.00%]:
  _1 = i_8(D) * 4;
  p_10 = a_9(D) + _1;
  _2 = j_11(D) * 4;
  q_12 = a_9(D) + _2;
  _21 = (long int) _1;
  _22 = (long int) _2;
  if (p_10 < q_12)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [50.00%]:
  _3 = _22 - _21;
  _4 = _3 /[ex] 4;
  iftmp.0_14 = (long unsigned int) _4;
  goto <bb 5>; [100.00%]

  <bb 4> [50.00%]:
  _5 = _21 - _22;
  _6 = _5 /[ex] 4;
  iftmp.0_13 = (long unsigned int) _6;

  <bb 5> [100.00%]:
  # iftmp.0_7 = PHI <iftmp.0_14(3), iftmp.0_13(4)>
  if (iftmp.0_7 > 536870911)
    goto <bb 6>; [0.04%]
  else
    goto <bb 7>; [99.96%]

  <bb 6> [0.04%]:
  __builtin_abort ();

  <bb 7> [99.96%]:
  return;

}



;; Function g (g, funcdef_no=1, decl_uid=1453, cgraph_uid=1, symbol_order=1)

g (int * a, long unsigned int i, long unsigned int j)
{
  int * q;
  int * p;
  long unsigned int _1;
  long unsigned int _2;
  long int _3;
  long int _4;
  long int _5;
  long int _6;
  signed int n.10_7;
  long unsigned int iftmp.5_8;
  long unsigned int iftmp.5_14;
  long unsigned int iftmp.5_15;
  long int _22;
  long int _23;

  <bb 2> [100.00%]:
  _1 = i_9(D) * 4;
  p_11 = a_10(D) + _1;
  _2 = j_12(D) * 4;
  q_13 = a_10(D) + _2;
  _22 = (long int) _1;
  _23 = (long int) _2;
  if (p_11 < q_13)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [50.00%]:
  _3 = _23 - _22;
  _4 = _3 /[ex] 4;
  iftmp.5_15 = (long unsigned int) _4;
  goto <bb 5>; [100.00%]

  <bb 4> [50.00%]:
  _5 = _22 - _23;
  _6 = _5 /[ex] 4;
  iftmp.5_14 = (long unsigned int) _6;

  <bb 5> [100.00%]:
  # iftmp.5_8 = PHI <iftmp.5_15(3), iftmp.5_14(4)>
  n.10_7 = (signed int) iftmp.5_8;
  if (n.10_7 < 0)
    goto <bb 6>; [0.04%]
  else
    goto <bb 7>; [99.96%]

  <bb 6> [0.04%]:
  __builtin_abort ();

  <bb 7> [99.96%]:
  return;

}

Reply via email to