1 /* { dg-require-effective-target vect_int } */
2 /* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */
3 /* { dg-add-options arm_v8_2a_i8mm }  */
4 
5 #include "tree-vect.h"
6 
7 #define N 50
8 
9 #ifndef SIGNEDNESS_1
10 #define SIGNEDNESS_1 unsigned
11 #define SIGNEDNESS_2 unsigned
12 #define SIGNEDNESS_3 signed
13 #define SIGNEDNESS_4 unsigned
14 #endif
15 
16 SIGNEDNESS_1 int __attribute__ ((noipa))
f(SIGNEDNESS_1 int res,SIGNEDNESS_3 char * restrict a,SIGNEDNESS_4 char * restrict b)17 f (SIGNEDNESS_1 int res, SIGNEDNESS_3 char *restrict a,
18    SIGNEDNESS_4 char *restrict b)
19 {
20   for (__INTPTR_TYPE__ i = 0; i < N; ++i)
21     {
22       int av = a[i];
23       int bv = b[i];
24       SIGNEDNESS_2 int mult = av * bv;
25       res += mult;
26     }
27   return res;
28 }
29 
30 #define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4)
31 #define OFFSET 20
32 
33 int
main(void)34 main (void)
35 {
36   check_vect ();
37 
38   SIGNEDNESS_3 char a[N];
39   SIGNEDNESS_4 char b[N];
40   SIGNEDNESS_1 int expected = 0x12345;
41   for (int i = 0; i < N; ++i)
42     {
43       a[i] = BASE + i * 5;
44       b[i] = BASE + OFFSET + i * 4;
45       asm volatile ("" ::: "memory");
46       expected += (SIGNEDNESS_2 int) (a[i] * b[i]);
47     }
48   if (f (0x12345, a, b) != expected)
49     __builtin_abort ();
50 }
51 
52 /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */
53 /* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */
54