| /* { dg-do run } */ |
| /* { dg-require-effective-target p8vector_hw } */ |
| /* { dg-options "-mdejagnu-cpu=power8 -O3 " } */ |
| |
| #include <altivec.h> |
| |
| extern void abort (void); |
| |
| vector long long x; |
| vector long long y = { 1024, 2048 }; |
| vector long long z; |
| |
| vector long long |
| foo (void) |
| { |
| return y; /* Remove 1 swap and use lvx. */ |
| } |
| |
| vector long long |
| foo1 (void) |
| { |
| x = y; /* Remove 2 redundant swaps here. */ |
| return x; /* Remove 1 swap and use lvx. */ |
| } |
| |
| void __attribute__ ((noinline)) |
| fill_local (vector long long *vp) |
| { |
| *vp = x; /* Remove 2 redundant swaps here. */ |
| } |
| |
| /* Test aligned load from local. */ |
| vector long long |
| foo2 (void) |
| { |
| vector long long v; |
| |
| /* Need to be clever here because v will normally reside in a |
| register rather than memory. */ |
| fill_local (&v); |
| return v; /* Remove 1 swap and use lvx. */ |
| } |
| |
| |
| /* Test aligned load from pointer. */ |
| vector long long |
| foo3 (vector long long *arg) |
| { |
| return *arg; /* Remove 1 swap and use lvx. */ |
| } |
| |
| /* In this structure, the compiler should insert padding to assure |
| that a_vector is properly aligned. */ |
| struct bar { |
| short a_field; |
| vector long long a_vector; |
| }; |
| |
| vector long long |
| foo4 (struct bar *bp) |
| { |
| return bp->a_vector; /* Remove 1 swap and use lvx. */ |
| } |
| |
| /* Test aligned store to global. */ |
| void |
| baz (vector long long arg) |
| { |
| x = arg; /* Remove 1 swap and use stvx. */ |
| } |
| |
| void __attribute__ ((noinline)) |
| copy_local (vector long long *arg) |
| { |
| x = *arg; /* Remove 2 redundant swaps. */ |
| } |
| |
| |
| /* Test aligned store to local. */ |
| void |
| baz1 (vector long long arg) |
| { |
| vector long long v; |
| |
| /* Need cleverness, because v will normally reside in a register |
| rather than memory. */ |
| v = arg; /* Aligned store to local: remove 1 |
| swap and use stvx. */ |
| copy_local (&v); |
| } |
| |
| /* Test aligned store to pointer. */ |
| void |
| baz2 (vector long long *arg1, vector long long arg2) |
| { |
| /* Assume arg2 resides in register. */ |
| *arg1 = arg2; /* Remove 1 swap and use stvx. */ |
| } |
| |
| void |
| baz3 (struct bar *bp, vector long long v) |
| { |
| /* Assume v resides in register. */ |
| bp->a_vector = v; /* Remove 1 swap and use stvx. */ |
| } |
| |
| int |
| main (long long argc, long long *argv[]) |
| { |
| vector long long fetched_value = foo (); |
| if (fetched_value[0] != 1024 || fetched_value[1] != 2048) |
| abort (); |
| |
| fetched_value = foo1 (); |
| if (fetched_value[1] != 2048 || fetched_value[0] != 1024) |
| abort (); |
| |
| fetched_value = foo2 (); |
| if (fetched_value[0] != 1024 || fetched_value[1] != 2048) |
| abort (); |
| |
| fetched_value = foo3 (&x); |
| if (fetched_value[1] != 2048 || fetched_value[0] != 1024) |
| abort (); |
| |
| struct bar a_struct; |
| a_struct.a_vector = x; /* Remove 2 redundant swaps. */ |
| fetched_value = foo4 (&a_struct); |
| if (fetched_value[1] != 2048 || fetched_value[0] != 1024) |
| abort (); |
| |
| z[0] = 7096; |
| z[1] = 6048; |
| |
| baz (z); |
| if (x[0] != 7096 || x[1] != 6048) |
| abort (); |
| |
| vector long long source = { 8192, 7096}; |
| |
| baz1 (source); |
| if (x[0] != 8192 || x[1] != 7096) |
| abort (); |
| |
| vector long long dest; |
| baz2 (&dest, source); |
| if (dest[0] != 8192 || dest[1] != 7096) |
| abort (); |
| |
| baz3 (&a_struct, source); |
| if (a_struct.a_vector[1] != 7096 || a_struct.a_vector[0] != 8192) |
| abort (); |
| |
| return 0; |
| } |