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

            Bug ID: 90625
           Summary: fold strcmp(a, b) == 0 to zero for strings of unequal
                    but non-const lengths
           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: ---

The following was prompted by pr83431 that seems harder to solve than I
expected.  In the test case below, the lengths of the two strings are either
the same and the function returns 0, or they are different and the function
also returns zero because strcmp of two strings of unequal lengths must return
non-zero.  So the strcmp equality can be folded to zero, and the whole function
body then replaced with 'return 0.'

GCC already tries to optimize strcmp equalities in handle_builtin_string_cmp()
in strlen.c (thanks to the solutin for pr83026 committed in r261039) but it
only handles simple cases.

gcc -O2 -S -Wall -fdump-tree-strlen=/dev/stdout b.c
typedef __SIZE_TYPE__ size_t;

int f (const char *a, const char *b)
{
  size_t m = __builtin_strlen (a);
  size_t n = __builtin_strlen (b);

  if (m == n)
    return 0;

  return __builtin_strcmp (a, b) == 0;
}

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

f (const char * a, const char * b)
{
  size_t n;
  size_t m;
  int _1;
  _Bool _2;
  int _3;
  int _9;

  <bb 2> [local count: 1073741824]:
  m_6 = __builtin_strlen (a_5(D));
  n_8 = __builtin_strlen (b_7(D));
  if (m_6 == n_8)
    goto <bb 4>; [20.97%]
  else
    goto <bb 3>; [79.03%]

  <bb 3> [local count: 848578164]:
  _1 = __builtin_strcmp (a_5(D), b_7(D));
  _2 = _1 == 0;
  _9 = (int) _2;

  <bb 4> [local count: 1073741824]:
  # _3 = PHI <_9(3), 0(2)>
  return _3;

}

Reply via email to