1  /* { dg-additional-options "-O3" } */
       2  /* { dg-require-effective-target vect_double } */
       3  /* { dg-additional-options "-mprefer-vector-width=128" { target x86_64-*-* i?86-*-* } } */
       4  
       5  #include "tree-vect.h"
       6  
       7  extern void abort (void);
       8  extern void *malloc (__SIZE_TYPE__);
       9  
      10  struct site {
      11      struct {
      12  	struct {
      13  	    double real;
      14  	    double imag;
      15  	} e[3][3];
      16      } link[32];
      17      double phase[32];
      18  } *lattice;
      19  int sites_on_node;
      20  
      21  void rephase (void)
      22  {
      23    int i,j,k,dir;
      24    struct site *s;
      25    for(i=0,s=lattice;i<sites_on_node;i++,s++)
      26      for(dir=0;dir<32;dir++)
      27        for(j=0;j<3;j++)for(k=0;k<3;k++)
      28  	{
      29  	  s->link[dir].e[j][k].real *= s->phase[dir];
      30  	  s->link[dir].e[j][k].imag *= s->phase[dir];
      31  	}
      32  }
      33  
      34  int main()
      35  {
      36    int i,j,k;
      37    check_vect ();
      38    sites_on_node = 1;
      39    lattice = malloc (sizeof (struct site) * sites_on_node);
      40    for (i = 0; i < 32; ++i)
      41      {
      42        lattice->phase[i] = i;
      43        for (j = 0; j < 3; ++j)
      44  	for (k = 0; k < 3; ++k)
      45  	  {
      46  	    lattice->link[i].e[j][k].real = 1.0;
      47  	    lattice->link[i].e[j][k].imag = 1.0;
      48  	    __asm__ volatile ("" : : : "memory");
      49  	  }
      50      }
      51    rephase ();
      52    for (i = 0; i < 32; ++i)
      53      for (j = 0; j < 3; ++j)
      54        for (k = 0; k < 3; ++k)
      55  	if (lattice->link[i].e[j][k].real != i
      56  	    || lattice->link[i].e[j][k].imag != i)
      57  	  abort ();
      58    return 0;
      59  }
      60  
      61  /* We should also be able to use 2-lane SLP to initialize the real and
      62     imaginary components in the first loop of main.  */
      63  /* { dg-final { scan-tree-dump-times "optimized: basic block" 10 "slp1" } } */
      64  /* We should see the s->phase[dir] operand splatted and no other operand built
      65     from scalars.  See PR97334.  */
      66  /* { dg-final { scan-tree-dump "Using a splat" "slp1" } } */
      67  /* { dg-final { scan-tree-dump-times "Building vector operands from scalars" 0 "slp1" } } */