(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
powerpc/
swaps-p8-29.c
       1  /* { dg-do run } */
       2  /* { dg-require-effective-target p8vector_hw } */
       3  /* { dg-options "-mdejagnu-cpu=power8 -O3 " } */
       4  
       5  #include <altivec.h>
       6  
       7  extern void abort (void);
       8  
       9  const vector char y = { 0, 1, 2, 3,
      10  			4, 5, 6, 7,
      11  			8, 9, 10, 11,
      12  			12, 13, 14, 15 };
      13  
      14  vector char x, z;
      15  
      16  vector char
      17  foo (void)
      18  {
      19    return y;			/* Remove 1 swap and use lvx.  */
      20  }
      21  
      22  vector char
      23  foo1 (void)
      24  {
      25    x = y;			/* Remove 2 redundant swaps here.  */
      26    return x;			/* Remove 1 swap and use lvx.  */
      27  }
      28  
      29  void __attribute__ ((noinline))
      30  fill_local (vector char *vp)
      31  {
      32    *vp = x;			/* Remove 2 redundant swaps here.  */
      33  }
      34  
      35  /* Test aligned load from local.  */
      36  vector char
      37  foo2 (void)
      38  {
      39    vector char v;
      40  
      41    /* Need to be clever here because v will normally reside in a
      42       register rather than memory.  */
      43    fill_local (&v);
      44    return v;			/* Remove 1 swap and use lvx.  */
      45  }
      46  
      47  
      48  /* Test aligned load from pointer.  */
      49  vector char
      50  foo3 (vector char *arg)
      51  {
      52    return *arg;			/* Remove 1 swap and use lvx.  */
      53  }
      54  
      55  /* In this structure, the compiler should insert padding to assure
      56     that a_vector is properly aligned.  */
      57  struct bar {
      58    char a_field;
      59    vector char a_vector;
      60  };
      61  
      62  vector char
      63  foo4 (struct bar *bp)
      64  {
      65    return bp->a_vector;		/* Remove 1 swap and use lvx.  */
      66  }
      67  
      68  /* Test aligned store to global.  */
      69  void
      70  baz (vector char arg)
      71  {
      72    x = arg;			/* Remove 1 swap and use stvx.  */
      73  }
      74  
      75  void __attribute__ ((noinline))
      76  copy_local (vector char *arg)
      77  {
      78    x = *arg;			/* Remove 2 redundant swaps.  */
      79  }
      80  
      81  
      82  /* Test aligned store to local.  */
      83  void
      84  baz1 (vector char arg)
      85  {
      86    vector char v;
      87  
      88    /* Need cleverness, because v will normally reside in a register
      89       rather than memory.  */
      90    v = arg;			/* Aligned store to local: remove 1
      91  				   swap and use stvx.  */
      92    copy_local (&v);
      93  }
      94  
      95  /* Test aligned store to pointer.  */
      96  void
      97  baz2 (vector char *arg1, vector char arg2)
      98  {
      99    /* Assume arg2 resides in register.  */
     100    *arg1 = arg2;			/* Remove 1 swap and use stvx.  */
     101  }
     102  
     103  void
     104  baz3 (struct bar *bp, vector char v)
     105  {
     106    /* Assume v resides in register.  */
     107    bp->a_vector = v;		/* Remove 1 swap and use stvx.  */
     108  }
     109  
     110  int
     111  main (int argc, char *argv[])
     112  {
     113    vector char fetched_value = foo ();
     114    if (fetched_value[0] != 0 || fetched_value[15] != 15)
     115      abort ();
     116  
     117    fetched_value = foo1 ();
     118    if (fetched_value[1] != 1 || fetched_value[14] != 14)
     119      abort ();
     120  
     121    fetched_value = foo2 ();
     122    if (fetched_value[2] != 2 || fetched_value[13] != 13)
     123      abort ();
     124  
     125    fetched_value = foo3 (&x);
     126    if (fetched_value[3] != 3 || fetched_value[12] != 12)
     127      abort ();
     128  
     129    struct bar a_struct;
     130    a_struct.a_vector = x;	/* Remove 2 redundant swaps.  */
     131    fetched_value = foo4 (&a_struct);
     132    if (fetched_value[4] != 4 || fetched_value[11] != 11)
     133      abort ();
     134  
     135    for (int i = 0; i < 16; i++)
     136      z[i] = 15 - i;
     137  
     138    baz (z);
     139    if (x[0] != 15 || x[15] != 0)
     140      abort ();
     141  
     142    vector char source = { 8, 7, 6, 5, 4, 3, 2, 1,
     143  			 0, 9, 10, 11, 12, 13, 14, 15 };
     144  
     145    baz1 (source);
     146    if (x[3] != 5 || x[8] != 0)
     147      abort ();
     148  
     149    vector char dest;
     150    baz2 (&dest, source);
     151    if (dest[4] != 4 || dest[1] != 7)
     152      abort ();
     153  
     154    baz3 (&a_struct, source);
     155    if (a_struct.a_vector[7] != 1 || a_struct.a_vector[15] != 15)
     156      abort ();
     157  
     158    return 0;
     159  }