1  /* { dg-do compile } */
       2  /* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */
       3  /* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */
       4  /* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */
       5  
       6  #include <inttypes.h>
       7  
       8  #if __riscv_xlen == 32
       9  typedef uint32_t xlen_t;
      10  #else
      11  typedef uint64_t xlen_t;
      12  #endif
      13  
      14  void foof (xlen_t*, xlen_t, xlen_t);
      15  void foor (xlen_t*, xlen_t, xlen_t);
      16  void foowu (uint32_t*, uint64_t, uint64_t);
      17  void foows (int32_t*, int64_t, int64_t);
      18  
      19  #define LxD_TEST(f, T, i1, i2)		\
      20  void					\
      21  f ## i1 ## i2(T *arr)			\
      22  {					\
      23    foo ## f(arr, arr[i1], arr[i2]);	\
      24  }
      25  
      26  // works
      27  LxD_TEST(f, xlen_t, 0, 1)
      28  // does not work (can't merge with unaligned offset)
      29  LxD_TEST(f, xlen_t, 1, 2)
      30  // works
      31  LxD_TEST(f, xlen_t, 2, 3)
      32  // does not work (can't merge with unaligned offset)
      33  LxD_TEST(f, xlen_t, 3, 4)
      34  // works
      35  LxD_TEST(f, xlen_t, 4, 5)
      36  // does not work (can't merge with unaligned offset)
      37  LxD_TEST(f, xlen_t, 5, 6)
      38  // works
      39  LxD_TEST(f, xlen_t, 6, 7)
      40  // does not work (can't merge with unaligned offset)
      41  LxD_TEST(f, xlen_t, 7, 8)
      42  // does not work (out of range)
      43  LxD_TEST(f, xlen_t, 8, 9)
      44  
      45  // works with reordering
      46  LxD_TEST(r, xlen_t, 1, 0)
      47  // does not work (can't merge with unaligned offset)
      48  LxD_TEST(r, xlen_t, 2, 1)
      49  // works with reordering
      50  LxD_TEST(r, xlen_t, 3, 2)
      51  // does not work (can't merge with unaligned offset)
      52  LxD_TEST(r, xlen_t, 4, 3)
      53  // works with reordering
      54  LxD_TEST(r, xlen_t, 5, 4)
      55  // does not work (can't merge with unaligned offset)
      56  LxD_TEST(r, xlen_t, 6, 5)
      57  // works with reordering
      58  LxD_TEST(r, xlen_t, 7, 6)
      59  // does not work (can't merge with unaligned offset)
      60  LxD_TEST(r, xlen_t, 8, 7)
      61  // does not work (out of range)
      62  LxD_TEST(r, xlen_t, 9, 8)
      63  
      64  #if __riscv_xlen != 32
      65  // works
      66  LxD_TEST(wu, uint32_t, 0, 1)
      67  LxD_TEST(ws, int32_t, 0, 1)
      68  // does not work (can't merge with unaligned offset)
      69  LxD_TEST(wu, uint32_t, 1, 2)
      70  LxD_TEST(ws, int32_t, 1, 2)
      71  // works
      72  LxD_TEST(wu, uint32_t, 2, 3)
      73  LxD_TEST(ws, int32_t, 2, 3)
      74  // does not work (can't merge with unaligned offset)
      75  LxD_TEST(wu, uint32_t, 3, 4)
      76  LxD_TEST(ws, int32_t, 3, 4)
      77  // works
      78  LxD_TEST(wu, uint32_t, 4, 5)
      79  LxD_TEST(ws, int32_t, 4, 5)
      80  // does not work (can't merge with unaligned offset)
      81  LxD_TEST(wu, uint32_t, 5, 6)
      82  LxD_TEST(ws, int32_t, 5, 6)
      83  // works
      84  LxD_TEST(wu, uint32_t, 6, 7)
      85  LxD_TEST(ws, int32_t, 6, 7)
      86  // does not work (can't merge with unaligned offset)
      87  LxD_TEST(wu, uint32_t, 7, 8)
      88  LxD_TEST(ws, int32_t, 7, 8)
      89  // does not work (out of range)
      90  LxD_TEST(wu, uint32_t, 8, 9)
      91  LxD_TEST(ws, int32_t, 8, 9)
      92  #endif
      93  
      94  /* { dg-final { scan-assembler-times "th.ldd\t" 8 { target { rv64 } } } } */
      95  /* { dg-final { scan-assembler-times "th.lwud\t" 4 { target { rv64 } } } } */
      96  /* { dg-final { scan-assembler-times "th.lwd\t" 4 { target { rv64 } } } } */
      97  
      98  /* { dg-final { scan-assembler-times "th.lwd\t" 8 { target { rv32 } } } } */