(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
memcmp-3.c
       1  /* PR middle-end/78257 - missing memcmp optimization with constant arrays
       2     { dg-do compile }
       3     { dg-options "-O -Wall -fdump-tree-optimized" }
       4     { dg-skip-if "missing data representation" { "pdp11-*-*" } }
       5     { dg-skip-if "test assumes structs are not packed" { default_packed } } */
       6  
       7  #define offsetof(T, m) __builtin_offsetof (T, m)
       8  
       9  typedef __INT8_TYPE__  int8_t;
      10  typedef __INT16_TYPE__ int16_t;
      11  typedef __INT32_TYPE__ int32_t;
      12  typedef __INT64_TYPE__ int64_t;
      13  typedef __SIZE_TYPE__  size_t;
      14  
      15  extern int memcmp (const void*, const void*, size_t);
      16  
      17  const int32_t ia4[4] = { 0x11121314, 0x21222324, 0x31323334, 0x41424344 };
      18  const int32_t ia4_des[4] =
      19    { [2] = 0x31323334, [0] = 0x11121314, 0x21222324, [3] = 0x41424344 };
      20  const char ia4_rep[] =
      21    {
      22  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
      23     "\x11\x12\x13\x14" "\x21\x22\x23\x24"
      24     "\x31\x32\x33\x34" "\x41\x42\x43\x44"
      25  #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      26     "\x14\x13\x12\x11" "\x24\x23\x22\x21"
      27     "\x34\x33\x32\x31" "\x44\x43\x42\x41"
      28  #endif
      29    };
      30  
      31  void eq_ia4 (void)
      32  {
      33    int n = 0, b = sizeof ia4;
      34    const char *p = (const char*)ia4, *q = ia4_rep;
      35  
      36    n += memcmp (p,      q,      b);
      37    n += memcmp (p + 1,  q + 1,  b - 1);
      38    n += memcmp (p + 2,  q + 2,  b - 2);
      39    n += memcmp (p + 3,  q + 3,  b - 3);
      40    n += memcmp (p + 4,  q + 4,  b - 4);
      41    n += memcmp (p + 5,  q + 5,  b - 5);
      42    n += memcmp (p + 6,  q + 6,  b - 6);
      43    n += memcmp (p + 7,  q + 7,  b - 7);
      44    n += memcmp (p + 8,  q + 8,  b - 8);
      45    n += memcmp (p + 9,  q + 9,  b - 9);
      46    n += memcmp (p + 10, q + 10, b - 10);
      47    n += memcmp (p + 11, q + 11, b - 11);
      48    n += memcmp (p + 12, q + 12, b - 12);
      49    n += memcmp (p + 13, q + 13, b - 13);
      50    n += memcmp (p + 14, q + 14, b - 14);
      51    n += memcmp (p + 15, q + 15, b - 15);
      52    n += memcmp (p + 16, q + 16, b - 16);
      53  
      54    p = (const char*)ia4_des;
      55  
      56    n += memcmp (p,      q,      b);
      57    n += memcmp (p + 1,  q + 1,  b - 1);
      58    n += memcmp (p + 2,  q + 2,  b - 2);
      59    n += memcmp (p + 3,  q + 3,  b - 3);
      60    n += memcmp (p + 4,  q + 4,  b - 4);
      61    n += memcmp (p + 5,  q + 5,  b - 5);
      62    n += memcmp (p + 6,  q + 6,  b - 6);
      63    n += memcmp (p + 7,  q + 7,  b - 7);
      64    n += memcmp (p + 8,  q + 8,  b - 8);
      65    n += memcmp (p + 9,  q + 9,  b - 9);
      66    n += memcmp (p + 10, q + 10, b - 10);
      67    n += memcmp (p + 11, q + 11, b - 11);
      68    n += memcmp (p + 12, q + 12, b - 12);
      69    n += memcmp (p + 13, q + 13, b - 13);
      70    n += memcmp (p + 14, q + 14, b - 14);
      71    n += memcmp (p + 15, q + 15, b - 15);
      72    n += memcmp (p + 16, q + 16, b - 16);
      73  
      74    if (n != 0)
      75      __builtin_abort ();
      76  }
      77  
      78  const float fa4[4] = { 1.0, 2.0, 3.0, 4.0 };
      79  const float fa4_des[4] = { [0] = fa4[0], [1] = 2.0, [2] = fa4[2], [3] = 4.0 };
      80  
      81  void eq_fa4 (void)
      82  {
      83    int n = 0, b = sizeof fa4;
      84    const char *p = (const char*)fa4, *q = (const char*)fa4_des;
      85  
      86    n += memcmp (p,      q,      b);
      87    n += memcmp (p + 1,  q + 1,  b - 1);
      88    n += memcmp (p + 2,  q + 2,  b - 2);
      89    n += memcmp (p + 3,  q + 3,  b - 3);
      90    n += memcmp (p + 4,  q + 4,  b - 4);
      91    n += memcmp (p + 5,  q + 5,  b - 5);
      92    n += memcmp (p + 6,  q + 6,  b - 6);
      93    n += memcmp (p + 7,  q + 7,  b - 7);
      94    n += memcmp (p + 8,  q + 8,  b - 8);
      95    n += memcmp (p + 9,  q + 9,  b - 9);
      96    n += memcmp (p + 10, q + 10, b - 10);
      97    n += memcmp (p + 11, q + 11, b - 11);
      98    n += memcmp (p + 12, q + 12, b - 12);
      99    n += memcmp (p + 13, q + 13, b - 13);
     100    n += memcmp (p + 14, q + 14, b - 14);
     101    n += memcmp (p + 15, q + 15, b - 15);
     102    n += memcmp (p + 16, q + 16, b - 16);
     103  
     104    if (n != 0)
     105      __builtin_abort ();
     106  }
     107  
     108  /* Verify "greater than" comparison with the difference in the last byte.  */
     109  const char ia4_xrep_16[sizeof ia4] =
     110    {
     111  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     112     0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24,
     113     0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43
     114  #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     115     0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21,
     116     0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42
     117  #endif
     118    };
     119  
     120  void gt_ia4 (void)
     121  {
     122    int n = 0, b = sizeof ia4;
     123    const char *p = (const char*)ia4, *q = ia4_xrep_16;
     124  
     125    n += 0 < memcmp (p,      q,      b);
     126    n += 0 < memcmp (p + 1,  q + 1,  b - 1);
     127    n += 0 < memcmp (p + 2,  q + 2,  b - 2);
     128    n += 0 < memcmp (p + 3,  q + 3,  b - 3);
     129    n += 0 < memcmp (p + 4,  q + 4,  b - 4);
     130    n += 0 < memcmp (p + 5,  q + 5,  b - 5);
     131    n += 0 < memcmp (p + 6,  q + 6,  b - 6);
     132    n += 0 < memcmp (p + 7,  q + 7,  b - 7);
     133    n += 0 < memcmp (p + 8,  q + 8,  b - 8);
     134    n += 0 < memcmp (p + 9,  q + 9,  b - 9);
     135    n += 0 < memcmp (p + 10, q + 10, b - 10);
     136    n += 0 < memcmp (p + 11, q + 11, b - 11);
     137    n += 0 < memcmp (p + 12, q + 12, b - 12);
     138    n += 0 < memcmp (p + 13, q + 13, b - 13);
     139    n += 0 < memcmp (p + 14, q + 14, b - 14);
     140    n += 0 < memcmp (p + 15, q + 15, b - 15);
     141  
     142    if (n != 16)
     143      __builtin_abort ();
     144  }
     145  
     146  struct S8_16_32
     147  {
     148    int8_t  i8;
     149    int16_t i16;
     150    int32_t i32;
     151  };
     152  
     153  _Static_assert (sizeof (struct S8_16_32) == 8);
     154  
     155  const struct S8_16_32 s8_16_32 = { 1, 0x2122, 0x31323334 };
     156  const struct S8_16_32 s8_16_32_des =
     157    { .i8 = 1, .i16 = 0x2122, .i32 = 0x31323334 };
     158  
     159  const char s8_16_32_rep[] =
     160    {
     161  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     162     1, 0, 0x21, 0x22, 0x31, 0x32, 0x33, 0x34
     163  #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     164     1, 0, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31
     165  #endif
     166    };
     167  
     168  void eq_s8_16_32 (void)
     169  {
     170    int n = 0, b = sizeof s8_16_32;
     171    const char *p = (char*)&s8_16_32, *q = s8_16_32_rep;
     172  
     173    n += memcmp (p,     q,     b);
     174    n += memcmp (p + 1, q + 1, b - 1);
     175    n += memcmp (p + 2, q + 2, b - 2);
     176    n += memcmp (p + 3, q + 3, b - 3);
     177    n += memcmp (p + 4, q + 4, b - 4);
     178    n += memcmp (p + 5, q + 5, b - 5);
     179    n += memcmp (p + 6, q + 6, b - 6);
     180    n += memcmp (p + 7, q + 7, b - 7);
     181  
     182    p = (char*)&s8_16_32_des;
     183  
     184    n += memcmp (p,     q,     b);
     185    n += memcmp (p + 1, q + 1, b - 1);
     186    n += memcmp (p + 2, q + 2, b - 2);
     187    n += memcmp (p + 3, q + 3, b - 3);
     188    n += memcmp (p + 4, q + 4, b - 4);
     189    n += memcmp (p + 5, q + 5, b - 5);
     190    n += memcmp (p + 6, q + 6, b - 6);
     191    n += memcmp (p + 7, q + 7, b - 7);
     192  
     193    if (n != 0)
     194      __builtin_abort ();
     195  }
     196  
     197  
     198  struct S8_16_32_64
     199  {
     200    /*  0 */ int8_t   i8;
     201    /*  1 */ int8_t:  1;
     202    /*  2 */ int16_t  i16;
     203    /*  4 */ int32_t: 1;
     204    /*  8 */ int32_t  i32;
     205    /* 12 */ int32_t: 1;
     206    /* 16 */ int64_t  i64;
     207    /* 24 */ int8_t:  0;
     208  };
     209  
     210  _Static_assert (offsetof (struct S8_16_32_64, i16) == 2);
     211  _Static_assert (offsetof (struct S8_16_32_64, i32) == 8);
     212  _Static_assert (offsetof (struct S8_16_32_64, i64) == 16);
     213  _Static_assert (sizeof (struct S8_16_32_64) == 24);
     214  
     215  const struct S8_16_32_64 s8_16_32_64 =
     216    { 1, 0x2122, 0x31323334, 0x4142434445464748LLU };
     217  
     218  const char s8_16_32_64_rep[sizeof s8_16_32_64] =
     219    {
     220  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     221     "\x01" "\x00" "\x21\x22" "\x00\x00\x00\x00" "\x31\x32\x33\x34"
     222     "\x00\x00\x00\x00" "\x41\x42\x43\x44\x45\x46\x47\x48"
     223  #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     224     "\x01" "\x00" "\x22\x21" "\x00\x00\x00\x00" "\x34\x33\x32\x31"
     225     "\x00\x00\x00\x00" "\x48\x47\x46\x45\x44\x43\x42\x41"
     226  #endif
     227    };
     228  
     229  const struct S8_16_32_64 s8_16_32_64_des =
     230    { .i64 = 0x4142434445464748LLU, .i16 = 0x2122, .i32 = 0x31323334, .i8 = 1 };
     231  
     232  
     233  void eq_8_16_32_64 (void)
     234  {
     235    int n = 0, b = sizeof s8_16_32_64;
     236    const char *p = (char*)&s8_16_32_64, *q = s8_16_32_64_rep;
     237  
     238    n += memcmp (p, q, b);
     239    n += memcmp (p + 1,  q + 1,  b - 1);
     240    n += memcmp (p + 2,  q + 2,  b - 2);
     241    n += memcmp (p + 3,  q + 3,  b - 3);
     242    n += memcmp (p + 4,  q + 4,  b - 4);
     243    n += memcmp (p + 5,  q + 5,  b - 5);
     244    n += memcmp (p + 6,  q + 6,  b - 6);
     245    n += memcmp (p + 7,  q + 7,  b - 7);
     246    n += memcmp (p + 8,  q + 8,  b - 8);
     247    n += memcmp (p + 9,  q + 9,  b - 9);
     248    n += memcmp (p + 10, q + 10, b - 10);
     249    n += memcmp (p + 11, q + 11, b - 11);
     250    n += memcmp (p + 12, q + 12, b - 12);
     251    n += memcmp (p + 13, q + 13, b - 13);
     252    n += memcmp (p + 14, q + 14, b - 14);
     253    n += memcmp (p + 15, q + 15, b - 15);
     254    n += memcmp (p + 16, q + 16, b - 16);
     255    n += memcmp (p + 17, q + 17, b - 17);
     256    n += memcmp (p + 18, q + 18, b - 18);
     257    n += memcmp (p + 19, q + 19, b - 19);
     258    n += memcmp (p + 20, q + 20, b - 20);
     259    n += memcmp (p + 21, q + 21, b - 21);
     260    n += memcmp (p + 22, q + 22, b - 22);
     261    n += memcmp (p + 23, q + 23, b - 23);
     262  
     263    p = (char*)&s8_16_32_64_des;
     264  
     265    n += memcmp (p, q, b);
     266    n += memcmp (p + 1,  q + 1,  b - 1);
     267    n += memcmp (p + 2,  q + 2,  b - 2);
     268    n += memcmp (p + 3,  q + 3,  b - 3);
     269    n += memcmp (p + 4,  q + 4,  b - 4);
     270    n += memcmp (p + 5,  q + 5,  b - 5);
     271    n += memcmp (p + 6,  q + 6,  b - 6);
     272    n += memcmp (p + 7,  q + 7,  b - 7);
     273    n += memcmp (p + 8,  q + 8,  b - 8);
     274    n += memcmp (p + 9,  q + 9,  b - 9);
     275    n += memcmp (p + 10, q + 10, b - 10);
     276    n += memcmp (p + 11, q + 11, b - 11);
     277    n += memcmp (p + 12, q + 12, b - 12);
     278    n += memcmp (p + 13, q + 13, b - 13);
     279    n += memcmp (p + 14, q + 14, b - 14);
     280    n += memcmp (p + 15, q + 15, b - 15);
     281    n += memcmp (p + 16, q + 16, b - 16);
     282    n += memcmp (p + 17, q + 17, b - 17);
     283    n += memcmp (p + 18, q + 18, b - 18);
     284    n += memcmp (p + 19, q + 19, b - 19);
     285    n += memcmp (p + 20, q + 20, b - 20);
     286    n += memcmp (p + 21, q + 21, b - 21);
     287    n += memcmp (p + 22, q + 22, b - 22);
     288    n += memcmp (p + 23, q + 23, b - 23);
     289  
     290    if (n != 0)
     291      __builtin_abort ();
     292  }
     293  
     294  struct S64_x_3
     295  {
     296    int64_t i64a[3];
     297  };
     298  
     299  _Static_assert (sizeof (struct S64_x_3) == 24);
     300  
     301  const struct S64_x_3 s64_x_3 =
     302    { { 0x0000000021220001LLU, 0x0000000031323334LLU, 0x4142434445464748LLU } };
     303  
     304  const char s64_x_3_rep[sizeof s64_x_3] =
     305    {
     306  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     307     "\x00\x00\x00\x00\x21\x22\x00\x01"
     308     "\x00\x00\x00\x00\x31\x32\x33\x34"
     309     "\x41\x42\x43\x44\x45\x46\x47\x48"
     310  #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     311     "\x01\x00\x22\x21\x00\x00\x00\x00"
     312     "\x34\x33\x32\x31\x00\x00\x00\x00"
     313     "\x48\x47\x46\x45\x44\x43\x42\x41"
     314  #endif
     315    };
     316  
     317  void eq_64_x_3 (void)
     318  {
     319    int n = 0, b = sizeof s8_16_32_64;
     320    const char *p = (char*)&s8_16_32_64, *q = s64_x_3_rep;
     321    n += memcmp (p, q, b);
     322    n += memcmp (p + 1,  q + 1,  b - 1);
     323    n += memcmp (p + 2,  q + 2,  b - 2);
     324    n += memcmp (p + 3,  q + 3,  b - 3);
     325    n += memcmp (p + 4,  q + 4,  b - 4);
     326    n += memcmp (p + 5,  q + 5,  b - 5);
     327    n += memcmp (p + 6,  q + 6,  b - 6);
     328    n += memcmp (p + 7,  q + 7,  b - 7);
     329    n += memcmp (p + 8,  q + 8,  b - 8);
     330    n += memcmp (p + 9,  q + 9,  b - 9);
     331    n += memcmp (p + 10, q + 10, b - 10);
     332    n += memcmp (p + 11, q + 11, b - 11);
     333    n += memcmp (p + 12, q + 12, b - 12);
     334    n += memcmp (p + 13, q + 13, b - 13);
     335    n += memcmp (p + 14, q + 14, b - 14);
     336    n += memcmp (p + 15, q + 15, b - 15);
     337    n += memcmp (p + 16, q + 16, b - 16);
     338    n += memcmp (p + 17, q + 17, b - 17);
     339    n += memcmp (p + 18, q + 18, b - 18);
     340    n += memcmp (p + 19, q + 19, b - 19);
     341    n += memcmp (p + 20, q + 20, b - 20);
     342    n += memcmp (p + 21, q + 21, b - 21);
     343    n += memcmp (p + 22, q + 22, b - 22);
     344    n += memcmp (p + 23, q + 23, b - 23);
     345  
     346    if (n != 0)
     347      __builtin_abort ();
     348  }
     349  
     350  /* { dg-final { scan-tree-dump-not "abort" "optimized" } } */