1  /* { dg-do run { target vect_simd_clones } } */
       2  /* { dg-additional-options "-msse2" { target sse2_runtime } } */
       3  /* { dg-additional-options "-mavx" { target avx_runtime } } */
       4  
       5  #define N 100
       6  #define EPS 0.000001
       7  
       8  #include <stdlib.h>
       9  #include <stdio.h>
      10  
      11  void init(int *b, float *y, int n)
      12  {
      13     int i, s = -1;
      14     for ( i=0; i<N; i++ )
      15     {
      16        b[i] = i*i*s;
      17        y[i] = b[i] * 0.1f;
      18        s = -s;
      19     }
      20  }
      21  
      22  #pragma omp declare simd linear(p:1) notinbranch
      23  int foo(int *p){
      24    *p = *p + 10;
      25    return *p;
      26  }
      27  
      28  int myaddint(int *a, int *b, int n)
      29  {
      30  #pragma omp simd
      31    for (int i=0; i<n; i++){
      32        a[i]  = foo(&b[i]);  /* foo is not called under a condition */
      33    }
      34    return a[n-1];
      35  }
      36  
      37  int myaddint_ref(int *a, int *b, int n)
      38  {
      39    for (int i=0; i<n; i++){
      40        a[i]  = foo(&b[i]);
      41    }
      42    return a[n-1];
      43  }
      44  
      45  #pragma omp declare simd linear(p:1) inbranch
      46  float goo(float *p){
      47    *p = *p + 18.5f;
      48    return *p;
      49  }
      50  
      51  int myaddfloat(float *x, float *y, int n)
      52  {
      53  #pragma omp simd
      54    for (int i=0; i<n; i++){
      55       x[i] = (x[i] > y[i]) ? goo(&y[i]) : y[i];
      56         /* goo is called under the condition (or within a branch) */
      57    }
      58    return x[n-1];
      59  }
      60  
      61  int myaddfloat_ref(float *x, float *y, int n)
      62  {
      63    for (int i=0; i<n; i++){
      64       x[i] = (x[i] > y[i]) ? goo(&y[i]) : y[i];
      65    }
      66    return x[n-1];
      67  }
      68  
      69  void check_addint (int *a, int *b)
      70  {
      71    int i;
      72    for (i = 0; i < N; i++)
      73      if (a[i] != b[i])
      74        abort ();
      75  }
      76  
      77  void check_addfloat (float *a, float *b)
      78  {
      79    int i;
      80    for (i = 0; i < N; i++)
      81      if (a[i] - b[i] > EPS || b[i] - a[i] > EPS)
      82        abort ();
      83  }
      84  
      85  int main ()
      86  {
      87     int i;
      88     int a[N], a_ref[N], b[N];
      89     float x[N], x_ref[N], y[N];
      90  
      91     init(a, x, N);
      92     init(b, y, N);
      93     myaddint(a, b, N);
      94     myaddfloat(x, y, N);
      95  
      96     init(a_ref, x_ref, N);
      97     init(b, y, N);
      98     myaddint_ref(a_ref, b, N);
      99     myaddfloat_ref(x_ref, y, N);
     100  
     101     check_addint(a, a_ref);
     102     check_addfloat(x, x_ref);
     103  
     104     return 0;
     105  }