https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82911
Bug ID: 82911 Summary: missing strlen optimization for strncpy with constant strings and constant bound 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: --- GCC can figure out the length of the string created by the first two statements in f0() but it doesn't do the same in f1(). The optimization in f1() is possible regardless of which of the constant strings is selected by the conditional expression because they are both longer than the constant bound specified by the third argument to strncpy. By making use of the get_range_strln() function defined in gimple-fold.c the tree-ssa-strlen.c pass could determine the length of the shortest source string and use it to gate the same optimization as in the first case. $ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c void f0 (char *d) { __builtin_strncpy (d, "123", 2); d[2] = 0; if (__builtin_strlen (d) != 2) // eliminated, good __builtin_abort (); } void f1 (char *d, _Bool b) { __builtin_strncpy (d, b ? "123" : "1234", 2); d[2] = 0; if (__builtin_strlen (d) != 2) // not eliminated but could be __builtin_abort (); } ;; Function f0 (f0, funcdef_no=0, decl_uid=1887, cgraph_uid=0, symbol_order=0) f0 (char * d) { <bb 2> [local count: 10000]: __builtin_memcpy (d_3(D), "123", 2); MEM[(char *)d_3(D) + 2B] = 0; return; } ;; Function f1 (f1, funcdef_no=1, decl_uid=1891, cgraph_uid=1, symbol_order=1) f1 (char * d, _Bool b) { long unsigned int _1; const char * iftmp.0_2; <bb 2> [local count: 10000]: if (b_3(D) != 0) goto <bb 4>; [50.00%] else goto <bb 3>; [50.00%] <bb 3> [local count: 5000]: <bb 4> [local count: 10000]: # iftmp.0_2 = PHI <"123"(2), "1234"(3)> __builtin_strncpy (d_5(D), iftmp.0_2, 2); MEM[(char *)d_5(D) + 2B] = 0; _1 = __builtin_strlen (d_5(D)); if (_1 != 2) goto <bb 5>; [0.04%] else goto <bb 6>; [99.96%] <bb 5> [count: 0]: __builtin_abort (); <bb 6> [local count: 9996]: return; }