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

            Bug ID: 92412
           Summary: excessive errno aliasing assumption defeats
                    optimization
           Product: gcc
           Version: 10.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: ---

GCC folds to false the test for a's contents in f() below but it doesn't do the
same in g().  It appears to be caused by the call to strlen which, when being
optimized by the strlen pass, triggers a call to GCC's
default_ref_may_alias_errno().  Although the default_ref_may_alias_errno()
function called to determine whether errno can alias a variable returns false
for static variables defined in the same translation unit it returns true for
local variables like a.

Other compilers (Clang and Visual C/C++) fold the tests in both functions to
false.

$ cat b.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout b.c
void* f (void)
{ 
  const char a[] = "123";

  void *p = __builtin_malloc (sizeof a);

  if (a[0] != '1' || a[1] != '2' || a[2] != '3' || a[3] != '\0')   // folded to
false
    __builtin_abort ();

  return p;
}

void* g (void)
{
  const char a[] = "123";

  void *p = __builtin_malloc (__builtin_strlen (a) + 1);

  if (a[0] != '1' || a[1] != '2' || a[2] != '3' || a[3] != '\0')   // not
folded
    __builtin_abort ();

  return p;
}


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

f ()
{
  void * p;

  <bb 2> [local count: 1073741824]:
  p_3 = __builtin_malloc (4); [tail call]
  return p_3;

}



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

Removing basic block 8
Removing basic block 9
Removing basic block 10
Removing basic block 11
g ()
{
  void * p;
  const char a[4];
  char _3;
  char _4;
  char _5;
  char _6;

  <bb 2> [local count: 1073741824]:
  a = "123";
  p_10 = __builtin_malloc (4);
  _3 = a[0];
  if (_3 != 49)
    goto <bb 6>; [0.00%]
  else
    goto <bb 3>; [100.00%]

  <bb 3> [local count: 1073741824]:
  _4 = a[1];
  if (_4 != 50)
    goto <bb 6>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 4> [local count: 1073741824]:
  _5 = a[2];
  if (_5 != 51)
    goto <bb 6>; [0.00%]
  else
    goto <bb 5>; [100.00%]

  <bb 5> [local count: 1073741824]:
  _6 = a[3];
  if (_6 != 0)
    goto <bb 6>; [0.00%]
  else
    goto <bb 7>; [100.00%]

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

  <bb 7> [local count: 1073741824]:
  a ={v} {CLOBBER};
  return p_10;

}

Reply via email to