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

            Bug ID: 89772
           Summary: memchr for a character not in constant nul-padded
                    string not folded
           Product: gcc
           Version: 9.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: ---

Only the first of the two calls to memchr below is folded, the second one
isn't.  Looks like it's simply because fold_const_call considers only string
lengths (it calls c_getstr()) and doesn't take advantage of the knowledge that
all the other characters past the terminating NUL are also NUL.

If fold_const_call either called string_constant instead, or if c_getstr()
exposed the size of the constant string in addition to its length, it would be
able to fold the second call as well.

$ cat u.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout u.c
const char a[5] = "123";

void f3 (void)
{
  if (!__builtin_memchr (a, '3', sizeof a))   // folded to false
    __builtin_abort ();
}

void f7 (void)
{
  if (__builtin_memchr (a, '7', sizeof a))   // not folded
    __builtin_abort ();
}

;; Function f3 (f3, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=1)

f3 ()
{
  <bb 2> [local count: 1073741824]:
  return;

}



;; Function f7 (f7, funcdef_no=1, decl_uid=1910, cgraph_uid=2, symbol_order=2)

f7 ()
{
  void * _1;

  <bb 2> [local count: 1073741824]:
  _1 = __builtin_memchr (&a, 55, 5);
  if (_1 != 0B)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

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

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

}

Reply via email to