1  /* { dg-require-effective-target vect_int } */
       2  /* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */
       3  /* { dg-add-options arm_v8_2a_dotprod_neon }  */
       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 signed
      12  #define SIGNEDNESS_3 signed
      13  #define SIGNEDNESS_4 unsigned
      14  #endif
      15  
      16  SIGNEDNESS_1 long long __attribute__ ((noipa))
      17  f (SIGNEDNESS_1 long long res, SIGNEDNESS_3 char *restrict a,
      18     SIGNEDNESS_4 short *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
      34  main (void)
      35  {
      36    check_vect ();
      37  
      38    SIGNEDNESS_3 char a[N];
      39    SIGNEDNESS_4 short b[N];
      40    SIGNEDNESS_1 long long 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" } } */