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