1  /* { dg-do run { target { aarch64*-*-* } } } */
       2  /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
       3  /* { dg-add-options arm_v8_2a_bf16_neon }  */
       4  
       5  #include <arm_neon.h>
       6  
       7  extern void abort (void);
       8  
       9  typedef union
      10  {
      11    bfloat16_t bf16;
      12    uint16_t u16;
      13  } bfloat16_u_t;
      14  
      15  #define VARIANTS(VARIANT, STRUCT)		\
      16  VARIANT (bfloat16, , 4, _bf16, 3, STRUCT)	\
      17  VARIANT (bfloat16, q, 8, _bf16, 7, STRUCT)
      18  
      19  #define TESTMETH(BASE, Q, ELTS, SUFFIX, LANE, STRUCT)			       \
      20    int									       \
      21    test_vld##STRUCT##Q##_lane##SUFFIX (const bfloat16_u_t *data,		       \
      22  				      const bfloat16_u_t *overwrite)	       \
      23    {									       \
      24      BASE##x##ELTS##x##STRUCT##_t vectors;				       \
      25      bfloat16_u_t temp[ELTS];						       \
      26      int i,j;								       \
      27      for (i = 0; i < STRUCT; i++, data += ELTS)				       \
      28        vectors.val[i] = vld1##Q##SUFFIX ((bfloat16_t *)data);		       \
      29      vectors = vld##STRUCT##Q##_lane##SUFFIX ((bfloat16_t *) overwrite,	       \
      30  					     vectors, LANE);		       \
      31      while (--i >= 0)							       \
      32        {									       \
      33  	vst1##Q##SUFFIX ((bfloat16_t *)temp, vectors.val[i]);		       \
      34  	data -= ELTS; /* Point at value loaded before vldN_lane.  */	       \
      35  	for (j = 0; j < ELTS; j++)					       \
      36  	  if (temp[j].u16 != (j == LANE ? overwrite[i].u16 : data[j].u16))     \
      37  	    return 1;							       \
      38        }									       \
      39      return 0;								       \
      40    }
      41  
      42  /* Tests of vld2_lane and vld2q_lane.  */
      43  VARIANTS (TESTMETH, 2)
      44  /* Tests of vld3_lane and vld3q_lane.  */
      45  VARIANTS (TESTMETH, 3)
      46  /* Tests of vld4_lane and vld4q_lane.  */
      47  VARIANTS (TESTMETH, 4)
      48  
      49  #define CHECK(BASE, Q, ELTS, SUFFIX, LANE, STRUCT)			       \
      50    if (test_vld##STRUCT##Q##_lane##SUFFIX ((const bfloat16_u_t *)orig_data,     \
      51  					  BASE##_data) != 0)		       \
      52      abort ();
      53  
      54  int
      55  main (int argc, char **argv)
      56  {
      57    /* Original data for all vector formats.  */
      58    uint64_t orig_data[8] = {0x1234567890abcdefULL, 0x13579bdf02468aceULL,
      59  			   0x012389ab4567cdefULL, 0xdeeddadacafe0431ULL,
      60  			   0x1032547698badcfeULL, 0xbadbadbadbad0badULL,
      61  			   0x0102030405060708ULL, 0x0f0e0d0c0b0a0908ULL};
      62  
      63    /* Data with which vldN_lane will overwrite some of previous.  */
      64    bfloat16_u_t bfloat16_data[4];
      65    bfloat16_data[0].u16 = 0xABAB;
      66    bfloat16_data[1].u16 = 0x0;
      67    bfloat16_data[2].u16 = 0xCAFE;
      68    bfloat16_data[3].u16 = 0x1234;
      69  
      70    VARIANTS (CHECK, 2);
      71    VARIANTS (CHECK, 3);
      72    VARIANTS (CHECK, 4);
      73    return 0;
      74  }