1  /* PR tree-optimization/86711 - wrong folding of memchr
       2  
       3     Verify that calls to memchr() with constant arrays initialized
       4     with wide string literals are folded.
       5  
       6     { dg-do compile }
       7     { dg-options "-O1 -Wall -fdump-tree-optimized" } */
       8  
       9  #include "strlenopt.h"
      10  
      11  typedef __WCHAR_TYPE__ wchar_t;
      12  
      13  extern void* memchr (const void*, int, size_t);
      14  
      15  #define CONCAT(x, y) x ## y
      16  #define CAT(x, y) CONCAT (x, y)
      17  #define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__)
      18  
      19  #define FAIL(name) do {				\
      20      extern void FAILNAME (name) (void);		\
      21      FAILNAME (name)();				\
      22    } while (0)
      23  
      24  /* Macro to emit a call to funcation named
      25     call_in_true_branch_not_eliminated_on_line_NNN()
      26     for each call that's expected to be eliminated.  The dg-final
      27     scan-tree-dump-time directive at the bottom of the test verifies
      28     that no such call appears in output.  */
      29  #define ELIM(expr)							\
      30    if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
      31  
      32  #define T(s, n) ELIM (strlen (s) == n)
      33  
      34  
      35  static const wchar_t wc = L'1';
      36  static const wchar_t ws1[] = L"1";
      37  static const wchar_t wsx[] = L"\x12345678";		/* { dg-warning "hex escape" "" { target { ! 4byte_wchar_t } } } */
      38  static const wchar_t ws4[] = L"\x00123456\x12005678\x12340078\x12345600";		/* { dg-warning "hex escape" "" { target { ! 4byte_wchar_t } } } */
      39  
      40  void test_wide (void)
      41  {
      42    int i0 = 0;
      43    int i1 = i0 + 1;
      44    int i2 = i1 + 1;
      45    int i3 = i2 + 1;
      46    int i4 = i3 + 1;
      47  
      48    ELIM (memchr (L"" + 1, 0, 0) == 0);
      49    ELIM (memchr (&wc + 1, 0, 0) == 0);
      50    ELIM (memchr (L"\x12345678", 0, sizeof (wchar_t)) == 0);		/* { dg-warning "hex escape" "" { target { ! 4byte_wchar_t } } } */
      51  
      52    const size_t nb = sizeof ws4;
      53    const size_t nwb = sizeof (wchar_t);
      54  
      55    const char *pws1 = (const char*)ws1;
      56    const char *pws4 = (const char*)ws4;
      57    const char *pwsx = (const char*)wsx;
      58  
      59  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      60    ELIM (memchr (ws1, 0, sizeof ws1) == pws1 + 1);
      61    ELIM (memchr (wsx, 0, sizeof wsx) == pwsx + sizeof *wsx);
      62  
      63    ELIM (memchr (&ws4[0], 0, nb) == pws4 + 3);
      64    ELIM (memchr (&ws4[1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 2);
      65    ELIM (memchr (&ws4[2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 1);
      66    ELIM (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 0);
      67    ELIM (memchr (&ws4[4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
      68  
      69    ELIM (memchr (&ws4[i0], 0, nb) == pws4 + 3);
      70    ELIM (memchr (&ws4[i1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 2);
      71    ELIM (memchr (&ws4[i2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 1);
      72    ELIM (memchr (&ws4[i3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 0);
      73    ELIM (memchr (&ws4[i4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
      74  #else
      75    ELIM (memchr (ws1, 0, sizeof ws1) == pws1 + 0);
      76    ELIM (memchr (wsx, 0, sizeof wsx) == pwsx + sizeof *wsx);
      77  
      78    ELIM (memchr (&ws4[0], 0, nb) == pws4 + 0);
      79    ELIM (memchr (&ws4[1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 1);
      80    ELIM (memchr (&ws4[2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 2);
      81    ELIM (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3);
      82    ELIM (memchr (&ws4[4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
      83  
      84    ELIM (memchr (&ws4[i0], 0, nb) == pws4 + 0);
      85    ELIM (memchr (&ws4[i1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 1);
      86    ELIM (memchr (&ws4[i2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 2);
      87    ELIM (memchr (&ws4[i3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3);
      88    ELIM (memchr (&ws4[i4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
      89  #endif
      90  }
      91  
      92  /* { dg-final { scan-tree-dump-times "memchr" 0 "optimized" } }
      93     { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */