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