(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-80.c
       1  /* PR tree-optimization/91996 - fold strlen relational expressions
       2  
       3     The optimization is only implemented for MEM_REF stores and other
       4     targets than those below may not transform the memcpy call into
       5     such a store.
       6     { dg-do compile { target { { aarch64*-*-* i?86-*-* x86_64-*-* } || { { powerpc*-*-* } && lp64 } } } }
       7  
       8     { dg-options "-O2 -Wall -fdump-tree-optimized" }
       9     { dg-additional-options "-msse" { target i?86-*-* x86_64-*-* } } */
      10  
      11  #define CHAR_BIT      __CHAR_BIT__
      12  #define SIZE_MAX      __SIZE_MAX__
      13  #define LEN_MAX       (__PTRDIFF_MAX__ - 2)
      14  
      15  typedef __PTRDIFF_TYPE__ ptrdiff_t;
      16  typedef __SIZE_TYPE__    size_t;
      17  
      18  extern void* memcpy (void*, const void*, size_t);
      19  extern size_t strlen (const char*);
      20  
      21  #define CONCAT(a, b) a ## b
      22  #define CAT(a, b)    CONCAT (a, b)
      23  
      24  extern void sink (void*, ...);
      25  extern void failure_on_line (int);
      26  
      27  extern char src[];
      28  extern char dst[];
      29  
      30  /* Copy (1 << NCPYLOG) bytes from an unknown string SRC with strlen (SRC)
      31     in the range [MINSRCLEN, MAXSRCLEN] into DST + DSTOFF and verify that
      32     strlen (DST + DSTOFF) is in the range [MINDSTLEN, MAXDSTLEN].  */
      33  #define MIN_MAX(dst, dstoff, src,					\
      34  	     minsrclen, maxsrclen, mindstlen, maxdstlen, ncpylog)	\
      35    void CAT (test_on_line_, __LINE__) (void)				\
      36    {									\
      37      size_t srclen = strlen (src);					\
      38      if ((minsrclen) <= srclen && srclen <= (maxsrclen)) {		\
      39        char *d = (dst) + (dstoff);					\
      40        memcpy (d, src, (size_t)1 << (ncpylog));				\
      41        size_t dstlen = strlen (d);					\
      42        if (dstlen < (mindstlen) || (maxdstlen) < dstlen)			\
      43  	{								\
      44  	  failure_on_line (__LINE__);					\
      45  	}								\
      46        sink (dst, src);							\
      47      }									\
      48    } typedef void dummy_type
      49  
      50  // Verify the lower bound of the resulting strlen range.
      51  #define MIN(dst, dstoff, src, minsrclen, mindstlen, ncpylog)		\
      52    MIN_MAX (dst, dstoff, src, minsrclen, LEN_MAX, mindstlen, LEN_MAX, ncpylog)
      53  
      54  MIN (dst, 0, src, 2, 1, 0);
      55  MIN (dst, 0, src, 3, 1, 0);
      56  MIN (dst, 0, src, 3, 2, 1);
      57  MIN (dst, 0, src, 3, 2, 2);
      58  MIN (dst, 0, src, 3, 2, 3);
      59  
      60  MIN (dst, 1, src, 2, 1, 0);
      61  MIN (dst, 1, src, 3, 1, 0);
      62  MIN (dst, 1, src, 3, 2, 1);
      63  MIN (dst, 1, src, 3, 2, 2);
      64  MIN (dst, 1, src, 3, 2, 3);
      65  
      66  MIN (dst, 2, src, 2, 1, 0);
      67  MIN (dst, 3, src, 3, 1, 0);
      68  MIN (dst, 4, src, 3, 2, 1);
      69  MIN (dst, 5, src, 3, 2, 2);
      70  MIN (dst, 6, src, 3, 2, 3);
      71  
      72  
      73  MIN (dst, 0, src, 5, 1, 0);
      74  MIN (dst, 0, src, 5, 2, 1);
      75  MIN (dst, 0, src, 5, 4, 2);
      76  MIN (dst, 0, src, 5, 5, 3);
      77  
      78  #if __aarch64__ || __x86_64__
      79  /* Of the targets above only aarch64 and x86_64 transform memcpy calls
      80     of (2 << 4) bytes into MEM_REF.  */
      81  MIN (dst, 0, src, 5, 5, 4);
      82  #endif
      83  
      84  MIN (dst, 11, src, 5, 1, 0);
      85  MIN (dst, 22, src, 5, 2, 1);
      86  MIN (dst, 33, src, 5, 4, 2);
      87  MIN (dst, 44, src, 5, 5, 3);
      88  
      89  #if __aarch64__ || __x86_64__
      90  MIN (dst, 55, src, 5, 5, 4);
      91  #endif
      92  
      93  MIN (dst, 11, src, LEN_MAX, 1, 0);
      94  MIN (dst, 22, src, LEN_MAX, 2, 1);
      95  MIN (dst, 33, src, LEN_MAX, 4, 2);
      96  MIN (dst, 44, src, LEN_MAX, 5, 3);
      97  MIN (dst, 55, src, LEN_MAX, 5, 4);
      98  MIN (dst, 66, src, LEN_MAX, 9, 8);
      99  MIN (dst, 66, src, LEN_MAX, LEN_MAX, sizeof (ptrdiff_t) * CHAR_BIT - 1);
     100  
     101  
     102  MIN_MAX (dst, 0, src, 3, 5, 1, LEN_MAX, 0);
     103  MIN_MAX (dst, 0, src, 3, 5, 2, LEN_MAX, 1);
     104  MIN_MAX (dst, 0, src, 3, 5, 3, LEN_MAX, 2);
     105  
     106  /* Upper bound not implemented yet.
     107     MIN_MAX (dst, 0, src, 3, 5, 3, 5, 3);  */
     108  
     109  /* { dg-final { scan-tree-dump-times "failure_on_line \\(" 0 "optimized" } } */