(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
arm/
simd/
vmaxnmq_f32_1.c
       1  /* Test the `vmaxnmqf32' 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_vmaxnmq_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 = vmaxnmq_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] != b1[i])
      25        abort ();
      26  }
      27  
      28  void __attribute__ ((noinline))
      29  test_vmaxnmq_f32__regular_input2 ()
      30  {
      31    float32_t a1[] = {3,2,7,6};
      32    float32_t b1[] = {1,4,5,8};
      33    float32_t e[] = {3,4,7,8};
      34    float32x4_t a = vld1q_f32 (a1);
      35    float32x4_t b = vld1q_f32 (b1);
      36    float32x4_t c = vmaxnmq_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  
      46  void __attribute__ ((noinline))
      47  test_vmaxnmq_f32__quiet_NaN_one_arg ()
      48  {
      49    /* When given a quiet NaN, vmaxnmq returns the other operand.
      50       In this test case we have NaNs in only one operand.  */
      51    float32_t n = __builtin_nanf ("");
      52    float32_t a1[] = {1,2,3,4};
      53    float32_t b1[] = {n,n,n,n};
      54    float32_t e[] = {1,2,3,4};
      55    float32x4_t a = vld1q_f32 (a1);
      56    float32x4_t b = vld1q_f32 (b1);
      57    float32x4_t c = vmaxnmq_f32 (a, b);
      58    float32_t actual[4];
      59    vst1q_f32 (actual, c);
      60  
      61    for (int i = 0; i < 4; ++i)
      62      if (actual[i] != e[i])
      63        abort ();
      64  }
      65  
      66  void __attribute__ ((noinline))
      67  test_vmaxnmq_f32__quiet_NaN_both_args ()
      68  {
      69    /* When given a quiet NaN, vmaxnmq returns the other operand.
      70       In this test case we have NaNs in both operands.  */
      71    float32_t n = __builtin_nanf ("");
      72    float32_t a1[] = {n,2,n,4};
      73    float32_t b1[] = {1,n,3,n};
      74    float32_t e[] = {1,2,3,4};
      75    float32x4_t a = vld1q_f32 (a1);
      76    float32x4_t b = vld1q_f32 (b1);
      77    float32x4_t c = vmaxnmq_f32 (a, b);
      78    float32_t actual[4];
      79    vst1q_f32 (actual, c);
      80  
      81    for (int i = 0; i < 4; ++i)
      82      if (actual[i] != e[i])
      83        abort ();
      84  }
      85  
      86  void __attribute__ ((noinline))
      87  test_vmaxnmq_f32__zero_both_args ()
      88  {
      89    /* For 0 and -0, vmaxnmq returns 0.  Since 0 == -0, check sign bit.  */
      90    float32_t a1[] = {0.0, 0.0, -0.0, -0.0};
      91    float32_t b1[] = {-0.0, -0.0, 0.0, 0.0};
      92    float32_t e[] = {0.0, 0.0, 0.0, 0.0};
      93  
      94    float32x4_t a = vld1q_f32 (a1);
      95    float32x4_t b = vld1q_f32 (b1);
      96    float32x4_t c = vmaxnmq_f32 (a, b);
      97  
      98    float32_t actual1[4];
      99    vst1q_f32 (actual1, c);
     100  
     101    for (int i = 0; i < 4; ++i)
     102      if (actual1[i] != e[i] || __builtin_signbit (actual1[i]) != 0)
     103        abort ();
     104  }
     105  
     106  void __attribute__ ((noinline))
     107  test_vmaxnmq_f32__inf_both_args ()
     108  {
     109    /* The max of inf and inf is inf.  The max of -inf and -inf is -inf.  */
     110    float32_t inf = __builtin_huge_valf ();
     111    float32_t a1[] = {inf, -inf, inf, inf};
     112    float32_t b1[] = {inf, -inf, -inf, -inf};
     113    float32_t e[] = {inf, -inf, inf, inf};
     114  
     115    float32x4_t a = vld1q_f32 (a1);
     116    float32x4_t b = vld1q_f32 (b1);
     117    float32x4_t c = vmaxnmq_f32 (a, b);
     118  
     119    float32_t actual1[4];
     120    vst1q_f32 (actual1, c);
     121  
     122    for (int i = 0; i < 4; ++i)
     123      if (actual1[i] != e[i])
     124        abort ();
     125  }
     126  
     127  void __attribute__ ((noinline))
     128  test_vmaxnmq_f32__two_quiet_NaNs_both_args ()
     129  {
     130    /* When given 2 NaNs, return a NaN.  Since a NaN is not equal to anything,
     131       not even another NaN, use __builtin_isnan () to check.  */
     132    float32_t n = __builtin_nanf ("");
     133    float32_t a1[] = {n,n,n,n};
     134    float32_t b1[] = {n,n,n,n};
     135    float32_t e[] = {n,n};
     136    float32x4_t a = vld1q_f32 (a1);
     137    float32x4_t b = vld1q_f32 (b1);
     138    float32x4_t c = vmaxnmq_f32 (a, b);
     139    float32_t actual[4];
     140    vst1q_f32 (actual, c);
     141  
     142    for (int i = 0; i < 4; ++i)
     143      if (!__builtin_isnan (actual[i]))
     144        abort ();
     145  }
     146  
     147  int
     148  main ()
     149  {
     150    test_vmaxnmq_f32__regular_input1 ();
     151    test_vmaxnmq_f32__regular_input2 ();
     152    test_vmaxnmq_f32__quiet_NaN_one_arg ();
     153    test_vmaxnmq_f32__quiet_NaN_both_args ();
     154    test_vmaxnmq_f32__zero_both_args ();
     155    test_vmaxnmq_f32__inf_both_args ();
     156    test_vmaxnmq_f32__two_quiet_NaNs_both_args ();
     157    return 0;
     158  }
     159  
     160  /* { dg-final { scan-assembler-times "vmaxnm\.f32\t\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" 7 } } */