1  /* Make sure that the reverse permute patterns are optimized
       2     correctly.  */
       3  /* { dg-do run { target { s390*-*-* } } } */
       4  /* { dg-options "-O2 -march=z14 -mzarch -fno-unroll-loops -save-temps" } */
       5  
       6  /* { dg-final { scan-assembler-times "vpdi\t" 4 } } */
       7  /* { dg-final { scan-assembler-times "verllg\t" 2 } } */
       8  
       9  #include <assert.h>
      10  
      11  __attribute__((noipa))
      12  void reversel (long long *restrict a, long long *restrict b, int n)
      13  {
      14    for (int i = 0; i < n; i += 2)
      15      {
      16        a[i + 1] = b[i + 0];
      17        a[i + 0] = b[i + 1];
      18      }
      19  }
      20  
      21  __attribute__((noipa))
      22  void reversed (double *restrict a, double *restrict b, int n)
      23  {
      24    for (int i = 0; i < n; i += 2)
      25      {
      26        a[i + 1] = b[i + 0];
      27        a[i + 0] = b[i + 1];
      28      }
      29  }
      30  
      31  __attribute__((noipa))
      32  void reversei (unsigned int *restrict a, unsigned int *restrict b, int n)
      33  {
      34    for (int i = 0; i < n; i += 4)
      35      {
      36        a[i + 3] = b[i + 0];
      37        a[i + 2] = b[i + 1];
      38        a[i + 1] = b[i + 2];
      39        a[i + 0] = b[i + 3];
      40      }
      41  }
      42  
      43  __attribute__((noipa))
      44  void reversef (float *restrict a, float *restrict b, int n)
      45  {
      46    for (int i = 0; i < n; i += 4)
      47      {
      48        a[i + 3] = b[i + 0];
      49        a[i + 2] = b[i + 1];
      50        a[i + 1] = b[i + 2];
      51        a[i + 0] = b[i + 3];
      52      }
      53  }
      54  
      55  int main()
      56  {
      57    const int n = 1024;
      58    unsigned int u[n], u2[n];
      59    long long l[n], l2[n];
      60    double d[n], d2[n];
      61    float f[n], f2[n];
      62  
      63    for (int i = 0; i < n; i++)
      64      {
      65        u[i] = i;
      66        l[i] = i;
      67        d[i] = i;
      68        f[i] = i;
      69        u2[i] = i;
      70        l2[i] = i;
      71        d2[i] = i;
      72        f2[i] = i;
      73      }
      74  
      75    reversei (u2, u, n);
      76    reversel (l2, l, n);
      77    reversed (d2, d, n);
      78    reversef (f2, f, n);
      79  
      80    for (int i = 0; i < n - 16; i++)
      81      {
      82        assert (u[i] == u2[i / (16 / sizeof (u[0])) * (16 / sizeof (u[0])) + 16 / sizeof (u[0]) - 1 - i % (16 / sizeof (u[0]))]);
      83        assert (l[i] == l2[i / (16 / sizeof (l[0])) * (16 / sizeof (l[0])) + 16 / sizeof (l[0]) - 1 - i % (16 / sizeof (l[0]))]);
      84        assert (d[i] == d2[i / (16 / sizeof (d[0])) * (16 / sizeof (d[0])) + 16 / sizeof (d[0]) - 1 - i % (16 / sizeof (d[0]))]);
      85        assert (f[i] == f2[i / (16 / sizeof (f[0])) * (16 / sizeof (f[0])) + 16 / sizeof (f[0]) - 1 - i % (16 / sizeof (f[0]))]);
      86      }
      87  }