1  /* { dg-do run } */
       2  /* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-details -mzarch -march=z13" } */
       3  /* { dg-final { scan-tree-dump-times "generated rawmemchrQI" 2 "ldist" } } */
       4  /* { dg-final { scan-tree-dump-times "generated rawmemchrHI" 2 "ldist" } } */
       5  /* { dg-final { scan-tree-dump-times "generated rawmemchrSI" 2 "ldist" } } */
       6  
       7  #include <string.h>
       8  #include <assert.h>
       9  #include <stdint.h>
      10  #include <stdlib.h>
      11  
      12  #define rawmemchrT(T, pattern)     \
      13  __attribute__((noinline,noclone))  \
      14  T* rawmemchr_##T (T *s)            \
      15  {                                  \
      16    while (*s != pattern)            \
      17      ++s;                           \
      18    return s;                        \
      19  }
      20  
      21  rawmemchrT(int8_t, (int8_t)0xde)
      22  rawmemchrT(uint8_t, 0xde)
      23  rawmemchrT(int16_t, (int16_t)0xdead)
      24  rawmemchrT(uint16_t, 0xdead)
      25  rawmemchrT(int32_t, (int32_t)0xdeadbeef)
      26  rawmemchrT(uint32_t, 0xdeadbeef)
      27  
      28  #define runT(T, pattern)                           \
      29  void run_##T ()                                    \
      30  {                                                  \
      31    T *buf = malloc (4096 * 2 * sizeof(T));          \
      32    assert (buf != NULL);                            \
      33    memset (buf, 0xa, 4096 * 2 * sizeof(T));         \
      34    /* ensure q is 4096-byte aligned */              \
      35    T *q = (T*)((unsigned char *)buf                 \
      36                + (4096 - ((uintptr_t)buf & 4095))); \
      37    T *p;                                            \
      38    /* unaligned + block boundary + 1st load */      \
      39    p = (T *) ((uintptr_t)q - 8);                    \
      40    p[2] = pattern;                                  \
      41    assert ((rawmemchr_##T (&p[0]) == &p[2]));       \
      42    p[2] = (T) 0xaaaaaaaa;                           \
      43    /* unaligned + block boundary + 2nd load */      \
      44    p = (T *) ((uintptr_t)q - 8);                    \
      45    p[6] = pattern;                                  \
      46    assert ((rawmemchr_##T (&p[0]) == &p[6]));       \
      47    p[6] = (T) 0xaaaaaaaa;                           \
      48    /* unaligned + 1st load */                       \
      49    q[5] = pattern;                                  \
      50    assert ((rawmemchr_##T (&q[2]) == &q[5]));       \
      51    q[5] = (T) 0xaaaaaaaa;                           \
      52    /* unaligned + 2nd load */                       \
      53    q[14] = pattern;                                 \
      54    assert ((rawmemchr_##T (&q[2]) == &q[14]));      \
      55    q[14] = (T) 0xaaaaaaaa;                          \
      56    /* unaligned + 3rd load */                       \
      57    q[19] = pattern;                                 \
      58    assert ((rawmemchr_##T (&q[2]) == &q[19]));      \
      59    q[19] = (T) 0xaaaaaaaa;                          \
      60    /* unaligned + 4th load */                       \
      61    q[25] = pattern;                                 \
      62    assert ((rawmemchr_##T (&q[2]) == &q[25]));      \
      63    q[25] = (T) 0xaaaaaaaa;                          \
      64    /* aligned + 1st load */                         \
      65    q[5] = pattern;                                  \
      66    assert ((rawmemchr_##T (&q[0]) == &q[5]));       \
      67    q[5] = (T) 0xaaaaaaaa;                           \
      68    /* aligned + 2nd load */                         \
      69    q[14] = pattern;                                 \
      70    assert ((rawmemchr_##T (&q[0]) == &q[14]));      \
      71    q[14] = (T) 0xaaaaaaaa;                          \
      72    /* aligned + 3rd load */                         \
      73    q[19] = pattern;                                 \
      74    assert ((rawmemchr_##T (&q[0]) == &q[19]));      \
      75    q[19] = (T) 0xaaaaaaaa;                          \
      76    /* aligned + 4th load */                         \
      77    q[25] = pattern;                                 \
      78    assert ((rawmemchr_##T (&q[0]) == &q[25]));      \
      79    q[25] = (T) 0xaaaaaaaa;                          \
      80    free (buf);                                      \
      81  }
      82  
      83  runT(int8_t, (int8_t)0xde)
      84  runT(uint8_t, 0xde)
      85  runT(int16_t, (int16_t)0xdead)
      86  runT(uint16_t, 0xdead)
      87  runT(int32_t, (int32_t)0xdeadbeef)
      88  runT(uint32_t, 0xdeadbeef)
      89  
      90  int main (void)
      91  {
      92    run_uint8_t ();
      93    run_int8_t ();
      94    run_uint16_t ();
      95    run_int16_t ();
      96    run_uint32_t ();
      97    run_int32_t ();
      98    return 0;
      99  }