1  /* { dg-do run } */
       2  /* { dg-additional-options "-O3 -std=c99 -save-temps" } */
       3  /* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
       4  
       5  #pragma GCC target "+nosve"
       6  
       7  #include <string.h>
       8  
       9  typedef int v4si __attribute__ ((vector_size (16)));
      10  
      11  /*
      12  **foo1:
      13  **	cmgt	v0.4s, v1.4s, v0.4s
      14  **	bsl	v0.16b, v2.16b, v3.16b
      15  **	ret
      16  */
      17  v4si foo1 (v4si a, v4si b, v4si c, v4si d) {
      18      return ((a < b) & c) | ((a >= b) & d);
      19  }
      20  
      21  /*
      22  **foo2:
      23  **	cmgt	v0.4s, v1.4s, v0.4s
      24  **	bsl	v0.16b, v3.16b, v2.16b
      25  **	ret
      26  */
      27  v4si foo2 (v4si a, v4si b, v4si c, v4si d) {
      28      return (~(a < b) & c) | (~(a >= b) & d);
      29  }
      30  
      31  
      32  /**
      33  **bar1:
      34  **...
      35  **	cmge	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
      36  **	bsl	v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
      37  **	and	v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
      38  **...
      39  */
      40  void bar1 (int * restrict a, int * restrict b, int * restrict c,
      41  	  int * restrict d, int * restrict res, int n)
      42  {
      43    for (int i = 0; i < (n & -4); i++)
      44      res[i] = ((a[i] < b[i]) & c[i]) | ((a[i] >= b[i]) & d[i]);
      45  }
      46  
      47  /**
      48  **bar2:
      49  **...
      50  **	cmge	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
      51  **	bsl	v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
      52  **...
      53  */
      54  void bar2 (int * restrict a, int * restrict b, int * restrict c,
      55  	  int * restrict d, int * restrict res, int n)
      56  {
      57    for (int i = 0; i < (n & -4); i++)
      58      res[i] = (-(a[i] < b[i]) & c[i]) | (-(a[i] >= b[i]) & d[i]);
      59  }
      60  
      61  extern void abort ();
      62  
      63  int main ()
      64  {
      65  
      66    v4si a = { -3, -3, -3, -3 };
      67    v4si b = { 3, 3, 3, 3 };
      68    v4si c = { 5, 5, 5, 5 };
      69    v4si d = { 8, 8, 8, 8 };
      70  
      71    v4si res1 = foo1 (a, b, c, d);
      72    if (memcmp (&res1, &c, 16UL) != 0)
      73      abort ();
      74  
      75    v4si res2 = foo2 (a, b, c, d);
      76    if (memcmp (&res2, &d, 16UL) != 0)
      77     abort ();
      78  
      79    int ar[4] = { -3, -3, -3, -3 };
      80    int br[4] = { 3, 3, 3, 3 };
      81    int cr[4] = { 5, 5, 5, 5 };
      82    int dr[4] = { 8, 8, 8, 8 };
      83  
      84    int exp1[4] = { 1, 1, 1, 1 };
      85    int res3[4];
      86    bar1 ((int*)&ar, (int*)&br, (int*)&cr, (int*)&dr, (int*)&res3, 4);
      87    if (memcmp (&res3, &exp1, 16UL) != 0)
      88      abort ();
      89  
      90    int res4[4];
      91    bar2 ((int*)&ar, (int*)&br, (int*)&cr, (int*)&dr, (int*)&res4, 4);
      92    if (memcmp (&res4, &cr, 16UL) != 0)
      93      abort ();
      94  
      95    return 0;
      96  }