https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90879
Bug ID: 90879 Summary: fold zero-equality of strcmp between a longer string and a smaller array 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: --- Here's another strcmp optimization opportunity (besides pr90626 and pr90876) that could easily be taken advantage of on top of the solution for pr83026. When strncmp is called with a bound in excess of the sizes of the pointed-to arrays, GCC eliminates the pointless excessive bound and transforms the strncpy call to strcpy (in a subset of the cases when this is possible). This can be seen in function f in the test case below. But when, in a call to strcmp or strncmp, a string argument is longer than the size of the array it's being compared with for equality, the optimization fails to take advantage of the fact that a string that long cannot be equal to one stored in a smaller array. This can be seen in function g in the test case. The existing optimization has all the smarts to go this extra step, it just doesn't do it. $ cat a.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout a.c extern char a[4]; void f (void) { if (0 == __builtin_strncmp (a, "12345", 8)) // transformed to strcmp __builtin_abort (); // when the whole expression could be folded to zero } void g (void) { if (0 == __builtin_strcmp (a, "123456")) // not folded __builtin_abort (); } ;; Function f (f, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=0) f () { int _1; <bb 2> [local count: 1073741824]: _1 = __builtin_strcmp (&a, "12345"); if (_1 == 0) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; } ;; Function g (g, funcdef_no=1, decl_uid=1910, cgraph_uid=2, symbol_order=1) g () { int _1; <bb 2> [local count: 1073741824]: _1 = __builtin_strcmp (&a, "123456"); if (_1 == 0) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; }