1  /* { dg-do compile } */
       2  /* -fno-tree-loop-distribute-patterns prevents conversion to memset.  */
       3  /* { dg-options "-O3 -fno-tree-loop-distribute-patterns" } */
       4  
       5  #include <stdint.h>
       6  
       7  #define NUM_ELEMS(TYPE) (1024 / sizeof (TYPE))
       8  
       9  #define DEF_SET_IMM(TYPE, IMM, SUFFIX)		\
      10  void __attribute__ ((noinline, noclone))	\
      11  set_##TYPE##_##SUFFIX (TYPE *a)			\
      12  {						\
      13    for (int i = 0; i < NUM_ELEMS (TYPE); i++)	\
      14      a[i] = IMM;					\
      15  }
      16  
      17  /* --- VALID --- */
      18  
      19  DEF_SET_IMM (int8_t, 0, imm_0)
      20  DEF_SET_IMM (int16_t, 0, imm_0)
      21  DEF_SET_IMM (int32_t, 0, imm_0)
      22  DEF_SET_IMM (int64_t, 0, imm_0)
      23  
      24  DEF_SET_IMM (int8_t, -1, imm_m1)
      25  DEF_SET_IMM (int16_t, -1, imm_m1)
      26  DEF_SET_IMM (int32_t, -1, imm_m1)
      27  DEF_SET_IMM (int64_t, -1, imm_m1)
      28  
      29  DEF_SET_IMM (int8_t, 1, imm_1)
      30  DEF_SET_IMM (int16_t, 1, imm_1)
      31  DEF_SET_IMM (int32_t, 1, imm_1)
      32  DEF_SET_IMM (int64_t, 1, imm_1)
      33  
      34  DEF_SET_IMM (int8_t, 127, imm_127)
      35  DEF_SET_IMM (int16_t, 127, imm_127)
      36  DEF_SET_IMM (int32_t, 127, imm_127)
      37  DEF_SET_IMM (int64_t, 127, imm_127)
      38  
      39  DEF_SET_IMM (int8_t, -128, imm_m128)
      40  DEF_SET_IMM (int16_t, -128, imm_m128)
      41  DEF_SET_IMM (int32_t, -128, imm_m128)
      42  DEF_SET_IMM (int64_t, -128, imm_m128)
      43  
      44  // No uint8_t variant - size too large for a byte
      45  DEF_SET_IMM (int16_t, 256, imm_256)
      46  DEF_SET_IMM (int32_t, 256, imm_256)
      47  DEF_SET_IMM (int64_t, 256, imm_256)
      48  
      49  // No uint8_t variant - size too large for a byte
      50  DEF_SET_IMM (int16_t, 32512, imm_32512)
      51  DEF_SET_IMM (int32_t, 32512, imm_32512)
      52  DEF_SET_IMM (int64_t, 32512, imm_32512)
      53  
      54  // No uint8_t variant - size too large for a byte
      55  DEF_SET_IMM (int16_t, -32768, imm_m32768)
      56  DEF_SET_IMM (int32_t, -32768, imm_m32768)
      57  DEF_SET_IMM (int64_t, -32768, imm_m32768)
      58  
      59  /* gcc will generate:
      60       dup z0.b, 0x01
      61  */
      62  DEF_SET_IMM (int16_t, 0x0101, imm_01_pat)
      63  DEF_SET_IMM (int32_t, 0x01010101, imm_01_pat)
      64  DEF_SET_IMM (int64_t, 0x0101010101010101LL, imm_01_pat)
      65  
      66  /* gcc will generate:
      67       dup z0.h, 0x01
      68  */
      69  DEF_SET_IMM (int32_t, 0x00010001, imm_0001_pat)
      70  DEF_SET_IMM (int64_t, 0x0001000100010001LL, imm_0001_pat)
      71  
      72  /* gcc will generate:
      73       dup z0.b, 0xFE (-2)
      74  */
      75  DEF_SET_IMM (int16_t, 0xFEFE, imm_FE_pat)
      76  DEF_SET_IMM (int32_t, 0xFEFEFEFE, imm_FE_pat)
      77  DEF_SET_IMM (int64_t, 0xFEFEFEFEFEFEFEFE, imm_FE_pat)
      78  
      79  /* gcc will generate:
      80       dup z0.h, 0xFFFE (-2)
      81  */
      82  DEF_SET_IMM (int32_t, 0xFFFEFFFE, imm_FFFE_pat)
      83  DEF_SET_IMM (int64_t, 0xFFFEFFFEFFFEFFFELL, imm_FFFE_pat)
      84  
      85  /* gcc will generate:
      86       dup z0.h, 0xFE00
      87  */
      88  DEF_SET_IMM (int32_t, 0xFE00FE00, imm_FE00_pat)
      89  DEF_SET_IMM (int64_t, 0xFE00FE00FE00FE00LL, imm_FE00_pat)
      90  
      91  
      92  /* --- INVALID --- */
      93  
      94  // This shouldn't generate a dup as it's out of range, but also the compiler
      95  // shouldn't assert!
      96  DEF_SET_IMM (int32_t, 129, imm_m129)
      97  DEF_SET_IMM (int32_t, 32513, imm_32513)
      98  DEF_SET_IMM (int32_t, -32763, imm_m32763)
      99  
     100  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.b, #-1\n} } } */
     101  
     102  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.b, #0\n} } } */
     103  
     104  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.b, #1\n} } } */
     105  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #1\n} } } */
     106  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.s, #1\n} } } */
     107  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.d, #1\n} } } */
     108  
     109  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.b, #127\n} } } */
     110  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #127\n} } } */
     111  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.s, #127\n} } } */
     112  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.d, #127\n} } } */
     113  
     114  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.b, #-128\n} } } */
     115  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #-128\n} } } */
     116  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.s, #-128\n} } } */
     117  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.d, #-128\n} } } */
     118  
     119  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #256\n} } } */
     120  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.s, #256\n} } } */
     121  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.d, #256\n} } } */
     122  
     123  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #32512\n} } } */
     124  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.s, #32512\n} } } */
     125  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.d, #32512\n} } } */
     126  
     127  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #-32768\n} } } */
     128  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.s, #-32768\n} } } */
     129  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.d, #-32768\n} } } */
     130  
     131  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.b, #-2\n} } } */
     132  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #-2\n} 2 } } */
     133  
     134  /* { dg-final { scan-assembler {\tmov\tz[0-9]+\.h, #-512\n} } } */
     135  
     136  /* { dg-final { scan-assembler-not {#129\n} } } */
     137  /* { dg-final { scan-assembler-not {#32513\n} } } */
     138  /* { dg-final { scan-assembler-not {#-32763\n} } } */