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