https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86364
Bug ID: 86364 Summary: strnlen before strlen of same argument not folded Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- When a strlen() call is followed by strnlen() with the same argument of unknown length GCC folds the latter call into a MIN_EXPR involving the bound and the length computed by the strlen() call. But when the order of the two calls is reversed, GCC doesn't perform the same optimization, even though in principle it could by reordering the two calls and starting with strlen() instead. $ cat c.c && gcc -O2 -S -fdump-tree-optimized=/dev/stdout c.c char a[] = "12345"; __attribute__ ((noipa)) int f1 (void) { int n0 = __builtin_strlen (a); // call (unavoidably) emitted int n1 = __builtin_strnlen (a, 1); // folded into a MIN_EXPR return n0 + n1; } __attribute__ ((noipa)) int f2 (void) { int n0 = __builtin_strnlen (a, 1); // not folded int n1 = __builtin_strlen (a); // call emitted return n0 + n1; } ;; Function f1 (f1, funcdef_no=0, decl_uid=1899, cgraph_uid=1, symbol_order=1) __attribute__((noipa, noinline, noclone, no_icf)) f1 () { int n1; int n0; long unsigned int _1; long unsigned int _2; int _6; <bb 2> [local count: 1073741825]: _1 = __builtin_strlen (&a); n0_4 = (int) _1; _2 = MIN_EXPR <_1, 1>; n1_5 = (int) _2; _6 = n0_4 + n1_5; return _6; } ;; Function f2 (f2, funcdef_no=1, decl_uid=1904, cgraph_uid=2, symbol_order=2) __attribute__((noipa, noinline, noclone, no_icf)) f2 () { int n1; int n0; long unsigned int _1; long unsigned int _2; int _6; <bb 2> [local count: 1073741825]: _1 = __builtin_strnlen (&a, 1); n0_4 = (int) _1; _2 = __builtin_strlen (&a); n1_5 = (int) _2; _6 = n0_4 + n1_5; return _6; }