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

            Bug ID: 84470
           Summary: test for address of member being null not eliminated
           Product: gcc
           Version: 8.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: ---

The address of a member subobject can never be null.  If it were, the address
if the enclosing object would either have to be null which would make the
member access expression (i.e., p->member) undefined, or the address of the
object would have such that adding the offset of the member to it would wrap
around zero, which would make the addition undefined.

As a result, tests for the address of a member object being null can be
eliminated.

The test case below shows that GCC doesn't take advantage of this invariant. 
In constrast, Clang does take advantage of it for all but the first member.

$ cat a.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout a.c
struct A
{
  char a[4];
};

void f (struct A *p)
{
  if (p->a == 0)          // could only be true when p is null
    __builtin_abort ();   // can be eliminated
}

struct B
{
  char a[4];
};


void b (struct B *p)
{
  if (p->a == 0)          // can never be true
    __builtin_abort ();   // can be eliminated (as Clang does)
}


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

f (struct A * p)
{
  char[4] * _1;

  <bb 2> [local count: 1073741825]:
  _1 = &p_2(D)->a;
  if (_1 == 0B)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

  <bb 3> [count: 0]:
  __builtin_abort ();

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

}



;; Function b (b, funcdef_no=1, decl_uid=1964, cgraph_uid=1, symbol_order=1)

b (struct B * p)
{
  char[4] * _1;

  <bb 2> [local count: 1073741825]:
  _1 = &p_2(D)->a;
  if (_1 == 0B)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

  <bb 3> [count: 0]:
  __builtin_abort ();

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

}

Reply via email to