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

            Bug ID: 81454
           Summary: missing strcmp optimization on duplicate call with an
                    unknown string
           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 second call to strcmp() in the following function is redundant.: either the
first call returns zero and the second call isn't reached, or it returns a
non-zero value in which case so must the second.  The second call can be safely
eliminated.  This is a missed optimization opportunity.

This type of duplicate comparison is often a logic error.  In addition to
optimizing the redundant call, GCC should issue a warning pointing the
redundancy out.

$ cat x.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout x.c

const char foo[] = "123";
const char bar[] = "123";

int f (const char *s)
{
  if (!__builtin_strcmp (s, foo))
    return 0;
  if (!__builtin_strcmp (s, bar))   // redundant, can be eliminated
    return 1;

  return -1;
}

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

Removing basic block 4
Removing basic block 6
f (const char * s)
{
  int _1;
  int _2;
  int _3;

  <bb 2> [100.00%] [count: INV]:
  _1 = __builtin_strcmp (s_5(D), &foo);
  if (_1 == 0)
    goto <bb 5>; [34.00%] [count: INV]
  else
    goto <bb 3>; [66.00%] [count: INV]

  <bb 3> [66.00%] [count: INV]:
  _2 = __builtin_strcmp (s_5(D), &bar);
  if (_2 == 0)
    goto <bb 4>; [96.19%] [count: INV]
  else
    goto <bb 5>; [3.81%] [count: INV]

  <bb 4> [63.49%] [count: INV]:

  <bb 5> [100.00%] [count: INV]:
  # _3 = PHI <_1(2), 1(4), -1(3)>
  return _3;

}

Reply via email to