1  /* Test the `vminnmqf32' ARM Neon intrinsic.  */
       2  
       3  /* { dg-do run } */
       4  /* { dg-require-effective-target arm_v8_neon_hw } */
       5  /* { dg-options "-save-temps -O3 -march=armv8-a" } */
       6  /* { dg-add-options arm_v8_neon } */
       7  
       8  #include "arm_neon.h"
       9  
      10  extern void abort ();
      11  
      12  void __attribute__ ((noinline))
      13  test_vminnmq_f32__regular_input1 ()
      14  {
      15    float32_t a1[] = {1,2,5,6};
      16    float32_t b1[] = {3,4,7,8};
      17    float32x4_t a = vld1q_f32 (a1);
      18    float32x4_t b = vld1q_f32 (b1);
      19    float32x4_t c = vminnmq_f32 (a, b);
      20    float32_t actual[4];
      21    vst1q_f32 (actual, c);
      22  
      23    for (int i = 0; i < 4; ++i)
      24      if (actual[i] != a1[i])
      25        abort ();
      26  }
      27  
      28  void __attribute__ ((noinline))
      29  test_vminnmq_f32__regular_input2 ()
      30  {
      31    float32_t a1[] = {3,2,7,6};
      32    float32_t b1[] = {1,4,5,8};
      33    float32_t e[] = {1,2,5,6};
      34    float32x4_t a = vld1q_f32 (a1);
      35    float32x4_t b = vld1q_f32 (b1);
      36    float32x4_t c = vminnmq_f32 (a, b);
      37    float32_t actual[4];
      38    vst1q_f32 (actual, c);
      39  
      40    for (int i = 0; i < 4; ++i)
      41      if (actual[i] != e[i])
      42        abort ();
      43  }
      44  
      45  void __attribute__ ((noinline))
      46  test_vminnmq_f32__quiet_NaN_one_arg ()
      47  {
      48    /* When given a quiet NaN, vminnmq returns the other operand.
      49       In this test case we have NaNs in only one operand.  */
      50    float32_t n = __builtin_nanf ("");
      51    float32_t a1[] = {1,2,3,4};
      52    float32_t b1[] = {n,n,n,n};
      53    float32_t e[] = {1,2,3,4};
      54    float32x4_t a = vld1q_f32 (a1);
      55    float32x4_t b = vld1q_f32 (b1);
      56    float32x4_t c = vminnmq_f32 (a, b);
      57    float32_t actual[4];
      58    vst1q_f32 (actual, c);
      59  
      60    for (int i = 0; i < 4; ++i)
      61      if (actual[i] != e[i])
      62        abort ();
      63  }
      64  
      65  void __attribute__ ((noinline))
      66  test_vminnmq_f32__quiet_NaN_both_args ()
      67  {
      68    /* When given a quiet NaN, vminnmq returns the other operand.
      69       In this test case we have NaNs in both operands.  */
      70    float32_t n = __builtin_nanf ("");
      71    float32_t a1[] = {n,2,n,4};
      72    float32_t b1[] = {1,n,3,n};
      73    float32_t e[] = {1,2,3,4};
      74    float32x4_t a = vld1q_f32 (a1);
      75    float32x4_t b = vld1q_f32 (b1);
      76    float32x4_t c = vminnmq_f32 (a, b);
      77    float32_t actual[4];
      78    vst1q_f32 (actual, c);
      79  
      80    for (int i = 0; i < 4; ++i)
      81      if (actual[i] != e[i])
      82        abort ();
      83  }
      84  
      85  void __attribute__ ((noinline))
      86  test_vminnmq_f32__zero_both_args ()
      87  {
      88    /* For 0 and -0, vminnmq returns -0.  Since 0 == -0, check sign bit.  */
      89    float32_t a1[] = {0.0, 0.0, -0.0, -0.0};
      90    float32_t b1[] = {-0.0, -0.0, 0.0, 0.0};
      91    float32_t e[] = {-0.0, -0.0, -0.0, -0.0};
      92  
      93    float32x4_t a = vld1q_f32 (a1);
      94    float32x4_t b = vld1q_f32 (b1);
      95    float32x4_t c = vminnmq_f32 (a, b);
      96  
      97    float32_t actual1[4];
      98    vst1q_f32 (actual1, c);
      99  
     100    for (int i = 0; i < 4; ++i)
     101      if (actual1[i] != e[i] || __builtin_signbit (actual1[i]) == 0)
     102        abort ();
     103  }
     104  
     105  void __attribute__ ((noinline))
     106  test_vminnmq_f32__inf_both_args ()
     107  {
     108    /* The min of inf and inf is inf.  The min of -inf and -inf is -inf.  */
     109    float32_t inf = __builtin_huge_valf ();
     110    float32_t a1[] = {inf, -inf, inf, inf};
     111    float32_t b1[] = {inf, -inf, -inf, -inf};
     112    float32_t e[] = {inf, -inf, -inf, -inf};
     113  
     114    float32x4_t a = vld1q_f32 (a1);
     115    float32x4_t b = vld1q_f32 (b1);
     116    float32x4_t c = vminnmq_f32 (a, b);
     117  
     118    float32_t actual1[4];
     119    vst1q_f32 (actual1, c);
     120  
     121    for (int i = 0; i < 4; ++i)
     122      if (actual1[i] != e[i])
     123        abort ();
     124  }
     125  
     126  void __attribute__ ((noinline))
     127  test_vminnmq_f32__two_quiet_NaNs_both_args ()
     128  {
     129    /* When given 2 NaNs, return a NaN.  Since a NaN is not equal to anything,
     130       not even another NaN, use __builtin_isnan () to check.  */
     131    float32_t n = __builtin_nanf ("");
     132    float32_t a1[] = {n,n,n,n};
     133    float32_t b1[] = {n,n,n,n};
     134    float32_t e[] = {n,n};
     135    float32x4_t a = vld1q_f32 (a1);
     136    float32x4_t b = vld1q_f32 (b1);
     137    float32x4_t c = vminnmq_f32 (a, b);
     138    float32_t actual[4];
     139    vst1q_f32 (actual, c);
     140  
     141    for (int i = 0; i < 4; ++i)
     142      if (!__builtin_isnan (actual[i]))
     143        abort ();
     144  }
     145  
     146  int
     147  main ()
     148  {
     149    test_vminnmq_f32__regular_input1 ();
     150    test_vminnmq_f32__regular_input2 ();
     151    test_vminnmq_f32__quiet_NaN_one_arg ();
     152    test_vminnmq_f32__quiet_NaN_both_args ();
     153    test_vminnmq_f32__zero_both_args ();
     154    test_vminnmq_f32__inf_both_args ();
     155    test_vminnmq_f32__two_quiet_NaNs_both_args ();
     156    return 0;
     157  }
     158  
     159  /* { dg-final { scan-assembler-times "vminnm\.f32\t\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" 7 } } */