1 /* { dg-additional-options "-fdump-tree-optimized" } */
2 
3 #include "tree-vect.h"
4 
5 #define N (VECTOR_BITS * 11 / 64 + 4)
6 
7 #define add(A, B) ((A) + (B))
8 #define sub(A, B) ((A) - (B))
9 #define mul(A, B) ((A) * (B))
10 #define div(A, B) ((A) / (B))
11 
12 #define DEF(OP)								\
13   void __attribute__ ((noipa))						\
14   f_##OP (double *restrict a, double *restrict b, double x)		\
15   {									\
16     for (int i = 0; i < N; i += 2)					\
17       {									\
18 	a[i] = b[i] < 100 ? OP (b[i], x) : b[i];			\
19 	a[i + 1] = b[i + 1] < 70 ? OP (b[i + 1], x) : b[i + 1];		\
20       }									\
21   }
22 
23 #define TEST(OP)						\
24   {								\
25     f_##OP (a, b, 10);						\
26     for (int i = 0; i < N; ++i)					\
27       {								\
28 	int bval = (i % 17) * 10;				\
29 	int truev = OP (bval, 10);				\
30 	if (a[i] != (bval < (i & 1 ? 70 : 100) ? truev : bval))	\
31 	__builtin_abort ();					\
32 	asm volatile ("" ::: "memory");				\
33       }								\
34   }
35 
36 #define FOR_EACH_OP(T)				\
37   T (add)					\
38   T (sub)					\
39   T (mul)					\
40   T (div)
41 
FOR_EACH_OP(DEF)42 FOR_EACH_OP (DEF)
43 
44 int
45 main (void)
46 {
47   double a[N], b[N];
48   for (int i = 0; i < N; ++i)
49     {
50       b[i] = (i % 17) * 10;
51       asm volatile ("" ::: "memory");
52     }
53   FOR_EACH_OP (TEST)
54   return 0;
55 }
56 
57 /* { dg-final { scan-tree-dump-times {vectorizing stmts using SLP} 4 "vect" { target vect_double_cond_arith } } } */
58 /* { dg-final { scan-tree-dump-times { = \.COND_ADD} 1 "optimized" { target vect_double_cond_arith } } } */
59 /* { dg-final { scan-tree-dump-times { = \.COND_SUB} 1 "optimized" { target vect_double_cond_arith } } } */
60 /* { dg-final { scan-tree-dump-times { = \.COND_MUL} 1 "optimized" { target vect_double_cond_arith } } } */
61 /* { dg-final { scan-tree-dump-times { = \.COND_RDIV} 1 "optimized" { target vect_double_cond_arith } } } */
62 /* { dg-final { scan-tree-dump-not {VEC_COND_EXPR} "optimized" { target vect_double_cond_arith } } } */
63