https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89772
Bug ID: 89772 Summary: memchr for a character not in constant nul-padded string not folded 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: --- Only the first of the two calls to memchr below is folded, the second one isn't. Looks like it's simply because fold_const_call considers only string lengths (it calls c_getstr()) and doesn't take advantage of the knowledge that all the other characters past the terminating NUL are also NUL. If fold_const_call either called string_constant instead, or if c_getstr() exposed the size of the constant string in addition to its length, it would be able to fold the second call as well. $ cat u.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout u.c const char a[5] = "123"; void f3 (void) { if (!__builtin_memchr (a, '3', sizeof a)) // folded to false __builtin_abort (); } void f7 (void) { if (__builtin_memchr (a, '7', sizeof a)) // not folded __builtin_abort (); } ;; Function f3 (f3, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=1) f3 () { <bb 2> [local count: 1073741824]: return; } ;; Function f7 (f7, funcdef_no=1, decl_uid=1910, cgraph_uid=2, symbol_order=2) f7 () { void * _1; <bb 2> [local count: 1073741824]: _1 = __builtin_memchr (&a, 55, 5); if (_1 != 0B) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; }