1 /* { dg-require-effective-target vect_int } */
2 
3 #include "tree-vect.h"
4 
5 #define DIV(x,y) ((x)/(y))
6 #define MOD(x,y) ((x)%(y))
7 
8 #define TEMPLATE(PO2,OP)						\
9 void __attribute__ ((noipa))						\
10 f_##PO2##_##OP (int *restrict a, int *restrict b, __INTPTR_TYPE__ n)	\
11 {									\
12   for (__INTPTR_TYPE__ i = 0; i < n; ++i)				\
13     a[i] = OP (b[i], (1 << PO2));					\
14 }
15 #define TEMPLATES(PO2)	\
16 TEMPLATE (PO2,DIV);	\
17 TEMPLATE (PO2,MOD);
18 
19 TEMPLATES (1);
20 TEMPLATES (2);
21 TEMPLATES (3);
22 TEMPLATES (7);
23 TEMPLATES (8);
24 TEMPLATES (10);
25 TEMPLATES (15);
26 TEMPLATES (16);
27 TEMPLATES (20);
28 
29 typedef void (*func_t) (int *, int *, __INTPTR_TYPE__);
30 typedef struct {
31   int po2;
32   func_t div;
33   func_t mod;
34 } fn_t;
35 const fn_t fns[] = {
36 #define FN_PAIR(PO2) { PO2, f_##PO2##_DIV, f_##PO2##_MOD }
37   FN_PAIR (1),
38   FN_PAIR (2),
39   FN_PAIR (3),
40   FN_PAIR (7),
41   FN_PAIR (8),
42   FN_PAIR (10),
43   FN_PAIR (15),
44   FN_PAIR (16),
45   FN_PAIR (20),
46 };
47 
48 int __attribute__ ((noipa, noinline))
power2(int x)49 power2 (int x)
50 {
51   return 1 << x;
52 }
53 
54 #define N 50
55 
56 int
main(void)57 main (void)
58 {
59   int a[N], b[N], c[N];
60 
61   for (int i = 0; i < (sizeof(fns)/sizeof(fns[0])); i++)
62     {
63       int p = power2 (fns[i].po2);
64       for (int j = 0; j < N; j++)
65 	{
66 	  a[j] = ((p << 4) * j) / (N - 1) - (p << 5);
67 	  asm volatile ("" ::: "memory");
68 	}
69 
70       fns[i].div (b, a, N);
71       fns[i].mod (c, a, N);
72 
73       for (int j = 0; j < N; j++)
74 	if (a[j] != (b[j] * p + c[j]))
75           __builtin_abort ();
76     }
77 
78   return 0;
79 }
80 
81 /* { dg-final { scan-tree-dump {\.DIV_POW2} "vect" { target vect_sdiv_pow2_si } } } */
82 /* { dg-final { scan-tree-dump-times "vectorized 1 loop" 18 "vect" { target vect_sdiv_pow2_si } } } */
83