https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82665
Bug ID: 82665 Summary: missing value range optimization for memchr 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: --- VRP optimizes the first three out of the four equivalent functions below into no-ops. In f3() it's possible to make the same assumption about the argument of memchr() (and thus the result) as for that of all the other calls: that it contains a zero byte in the first PTRDIFF_MAX - 1 bytes, and thus that the difference between a pointer to the zero byte and the beginning of the array is less than PTRDIFF_MAX. $ cat y.c && gcc -O2 -S -Wall -fdump-tree-vrp=/dev/stdout y.c void f0 (char *p) { unsigned long n = 0; while (*p) ++n; if (n >= __PTRDIFF_MAX__) __builtin_abort (); } void f1 (char *p) { unsigned long n = __builtin_strlen (p); if (n >= __PTRDIFF_MAX__) __builtin_abort (); } void f2 (char *p) { char *q = __builtin_strchr (p, 0); unsigned long n = q - p; if (n >= __PTRDIFF_MAX__) __builtin_abort (); } void f3 (char *p) { char *q = __builtin_memchr (p, 0, __SIZE_MAX__); unsigned long n = q - p; if (n >= __PTRDIFF_MAX__) __builtin_abort (); } ... Value ranges after VRP: q.2_1: VARYING p.3_2: ~[0, 0] _3: VARYING p_5(D): VARYING q_6: VARYING n_7: [0, +INF] p_9: ~[0B, 0B] EQUIVALENCES: { p_5(D) } (1 elements) f3 (char * p) { long unsigned int n; char * q; long int q.2_1; long int p.3_2; long int _3; <bb 2> [100.00%] [count: INV]: q_6 = __builtin_memchr (p_5(D), 0, 18446744073709551615); q.2_1 = (long int) q_6; p.3_2 = (long int) p_5(D); _3 = q.2_1 - p.3_2; n_7 = (long unsigned int) _3; if (n_7 > 9223372036854775806) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [0.04%] [count: 0]: __builtin_abort (); <bb 4> [99.96%] [count: INV]: return; } y.c: In function ‘f3’: y.c:31:13: warning: ‘__builtin_memchr’ specified size 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] char *q = __builtin_memchr (p, 0, __SIZE_MAX__); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~