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; }
Confirmed.
Patch: https://gcc.gnu.org/ml/gcc-patches/2019-08/msg00640.html
Author: msebor Date: Wed Oct 9 21:35:11 2019 New Revision: 276773 URL: https://gcc.gnu.org/viewcvs?rev=276773&root=gcc&view=rev Log: PR tree-optimization/90879 - fold zero-equality of strcmp between a longer string and a smaller array gcc/c-family/ChangeLog: PR tree-optimization/90879 * c.opt (-Wstring-compare): New option. gcc/testsuite/ChangeLog: PR tree-optimization/90879 * gcc.dg/Wstring-compare-2.c: New test. * gcc.dg/Wstring-compare.c: New test. * gcc.dg/strcmpopt_3.c: Scan the optmized dump instead of strlen. * gcc.dg/strcmpopt_6.c: New test. * gcc.dg/strlenopt-65.c: Remove uinnecessary declarations, add test cases. * gcc.dg/strlenopt-66.c: Run it. * gcc.dg/strlenopt-68.c: New test. gcc/ChangeLog: PR tree-optimization/90879 * builtins.c (check_access): Avoid using maxbound when null. * calls.c (maybe_warn_nonstring_arg): Adjust to get_range_strlen change. * doc/invoke.texi (-Wstring-compare): Document new warning option. * gimple-fold.c (get_range_strlen_tree): Make setting maxbound conditional. (get_range_strlen): Overwrite initial maxbound when non-null. * gimple-ssa-sprintf.c (get_string_length): Adjust to get_range_strlen changes. * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Same. (used_only_for_zero_equality): New function. (handle_builtin_memcmp): Call it. (determine_min_objsize): Return an integer instead of tree. (get_len_or_size, strxcmp_eqz_result): New functions. (maybe_warn_pointless_strcmp): New function. (handle_builtin_string_cmp): Call it. Fold zero-equality of strcmp between a longer string and a smaller array. (get_range_strlen_dynamic): Overwrite initial maxbound when non-null. Added: trunk/gcc/testsuite/gcc.dg/Wstring-compare-2.c trunk/gcc/testsuite/gcc.dg/Wstring-compare.c trunk/gcc/testsuite/gcc.dg/strcmpopt_6.c trunk/gcc/testsuite/gcc.dg/strlenopt-69.c Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c.opt trunk/gcc/calls.c trunk/gcc/doc/invoke.texi trunk/gcc/gimple-fold.c trunk/gcc/gimple-ssa-sprintf.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/strcmpopt_3.c trunk/gcc/testsuite/gcc.dg/strlenopt-65.c trunk/gcc/testsuite/gcc.dg/strlenopt-66.c trunk/gcc/tree-ssa-strlen.c
Patch committed in r276773.