https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71690
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|absence of integer |some integer conversions |conversion defeats memcpy |defeat memcpy optimizaton |optimizaton | --- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> --- While debugging this I noticed other cases where VRP either doesn't make the range information available at all, or makes a "super-range" of the actual range available. I used the script below to see what types defeat the optimization in what languages (C in the second column and C++ in the third). Based on the results a more accurate description of the problem might be that some integer conversions (including the identity conversion if there were such a thing) defeat VRP. An interesting case is unsigned short in C++ where VRP misses the value range altogether but exposes the range of the type instead. $ cat vrp.c && for t in signed unsigned; do for u in char short int long 'long long'; do printf "%-20s " "$t $u"; for l in c c++; do m=$(/build/gcc-6-branch/gcc/xgcc -B/build/gcc-6-branch/gcc -DT="$t $u" -O2 -S -Wall -Wextra -Wpedantic -o/dev/stdout -x$l vrp.c 2>/dev/null | grep memcpy); if [ "$m" ]; then printf "%-8s" call; else printf "%-8s" inline; fi; done; echo; done; done char d [10]; char s [10]; void f (T n) { if (n < 0 || n >= 10) return; __builtin_memcpy (d, s, n); } signed char inline inline signed short inline inline signed int inline inline signed long call call signed long long call call unsigned char inline inline unsigned short inline call unsigned int inline inline unsigned long call call unsigned long long call call