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

Reply via email to