1 /* { dg-do run } */
2 /* { dg-options "-O3 --save-temps" } */
3
4 #include <arm_neon.h>
5
6 extern void abort (void);
7
8 #define MAPs(size, xx) int##size##xx##_t
9 #define MAPu(size, xx) uint##size##xx##_t
10
11
12 #define TEST_VMUL(q, su, size, in1_lanes, in2_lanes) \
13 static void \
14 __attribute__((noipa,noinline)) \
15 test_vmulq_lane##q##_##su##size (MAP##su (size, ) * res, \
16 const MAP##su(size, ) *in1, \
17 const MAP##su(size, ) *in2) \
18 { \
19 MAP##su (size, x##in1_lanes) a = vld1q_##su##size (in1); \
20 MAP##su (size, x##in2_lanes) b = vld1##q##_##su##size (in2); \
21 a = vmulq_lane##q##_##su##size (a, b, 1); \
22 vst1q_##su##size (res, a); \
23 }
24
25 #define BUILD_VARS(width, n_lanes, n_half_lanes) \
26 TEST_VMUL (, s, width, n_lanes, n_half_lanes) \
27 TEST_VMUL (q, s, width, n_lanes, n_lanes) \
28 TEST_VMUL (, u, width, n_lanes, n_half_lanes) \
29 TEST_VMUL (q, u, width, n_lanes, n_lanes) \
30
31 BUILD_VARS (32, 4, 2)
32 BUILD_VARS (16, 8, 4)
33
34 #define POOL4 {0, 1, 2, 3}
35 #define POOL8 {0, 1, 2, 3, 4, 5, 6, 7}
36 #define EMPTY4 {0, 0, 0, 0}
37 #define EMPTY8 {0, 0, 0, 0, 0, 0, 0, 0}
38
39 #define BUILD_TEST(su, size, lanes) \
40 static void \
41 test_##su##size (void) \
42 { \
43 int i; \
44 MAP##su (size,) pool[lanes] = POOL##lanes; \
45 MAP##su (size,) res[lanes] = EMPTY##lanes; \
46 MAP##su (size,) res2[lanes] = EMPTY##lanes; \
47 \
48 /* Forecfully avoid optimization. */ \
49 asm volatile ("" : : : "memory"); \
50 test_vmulq_lane_##su##size (res, pool, pool); \
51 for (i = 0; i < lanes; i++) \
52 if (res[i] != pool[i]) \
53 abort (); \
54 \
55 /* Forecfully avoid optimization. */ \
56 asm volatile ("" : : : "memory"); \
57 test_vmulq_laneq_##su##size (res2, pool, pool); \
58 for (i = 0; i < lanes; i++) \
59 if (res2[i] != pool[i]) \
60 abort (); \
61 }
62
63 #undef BUILD_VARS
64 #define BUILD_VARS(size, lanes) \
65 BUILD_TEST (s, size, lanes) \
66 BUILD_TEST (u, size, lanes)
67
68 BUILD_VARS (32, 4)
69 BUILD_VARS (16, 8)
70
71 int
main(int argc,char ** argv)72 main (int argc, char **argv)
73 {
74 test_s32 ();
75 test_u32 ();
76 test_s16 ();
77 test_u16 ();
78 return 0;
79 }
80
81 /* { dg-final { scan-assembler-times "mul\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 4 } } */
82 /* { dg-final { scan-assembler-times "mul\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.h\\\[\[0-9\]+\\\]" 4 } } */
83
84