(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.c-torture/
execute/
pr38051.c
       1  typedef __SIZE_TYPE__ size_t;
       2  static int mymemcmp1 (unsigned long int, unsigned long int)
       3    __attribute__ ((__nothrow__));
       4  
       5  __inline static int
       6  mymemcmp1 (unsigned long int a, unsigned long int b)
       7  {
       8    long int srcp1 = (long int) &a;
       9    long int srcp2 = (long int) &b;
      10    unsigned long int a0, b0;
      11    do
      12      {
      13        a0 = ((unsigned char *) srcp1)[0];
      14        b0 = ((unsigned char *) srcp2)[0];
      15        srcp1 += 1;
      16        srcp2 += 1;
      17      }
      18    while (a0 == b0);
      19    return a0 - b0;
      20  }
      21  
      22  static int mymemcmp2 (long, long, size_t) __attribute__ ((__nothrow__));
      23  
      24  static int
      25  mymemcmp2 (long int srcp1, long int srcp2, size_t len)
      26  {
      27    unsigned long int a0, a1;
      28    unsigned long int b0, b1;
      29    switch (len % 4)
      30      {
      31      default:
      32      case 2:
      33        a0 = ((unsigned long int *) srcp1)[0];
      34        b0 = ((unsigned long int *) srcp2)[0];
      35        srcp1 -= 2 * (sizeof (unsigned long int));
      36        srcp2 -= 2 * (sizeof (unsigned long int));
      37        len += 2;
      38        goto do1;
      39      case 3:
      40        a1 = ((unsigned long int *) srcp1)[0];
      41        b1 = ((unsigned long int *) srcp2)[0];
      42        srcp1 -= (sizeof (unsigned long int));
      43        srcp2 -= (sizeof (unsigned long int));
      44        len += 1;
      45        goto do2;
      46      case 0:
      47        if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
      48          return 0;
      49        a0 = ((unsigned long int *) srcp1)[0];
      50        b0 = ((unsigned long int *) srcp2)[0];
      51        goto do3;
      52      case 1:
      53        a1 = ((unsigned long int *) srcp1)[0];
      54        b1 = ((unsigned long int *) srcp2)[0];
      55        srcp1 += (sizeof (unsigned long int));
      56        srcp2 += (sizeof (unsigned long int));
      57        len -= 1;
      58        if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
      59          goto do0;
      60      }
      61    do
      62      {
      63        a0 = ((unsigned long int *) srcp1)[0];
      64        b0 = ((unsigned long int *) srcp2)[0];
      65        if (a1 != b1)
      66          return mymemcmp1 ((a1), (b1));
      67      do3:
      68        a1 = ((unsigned long int *) srcp1)[1];
      69        b1 = ((unsigned long int *) srcp2)[1];
      70        if (a0 != b0)
      71          return mymemcmp1 ((a0), (b0));
      72      do2:
      73        a0 = ((unsigned long int *) srcp1)[2];
      74        b0 = ((unsigned long int *) srcp2)[2];
      75        if (a1 != b1)
      76          return mymemcmp1 ((a1), (b1));
      77      do1:
      78        a1 = ((unsigned long int *) srcp1)[3];
      79        b1 = ((unsigned long int *) srcp2)[3];
      80        if (a0 != b0)
      81          return mymemcmp1 ((a0), (b0));
      82        srcp1 += 4 * (sizeof (unsigned long int));
      83        srcp2 += 4 * (sizeof (unsigned long int));
      84        len -= 4;
      85      }
      86    while (len != 0);
      87  do0:
      88    if (a1 != b1)
      89      return mymemcmp1 ((a1), (b1));
      90    return 0;
      91  }
      92  
      93  static int mymemcmp3 (long, long, size_t) __attribute__ ((__nothrow__));
      94  
      95  static int
      96  mymemcmp3 (long int srcp1, long int srcp2, size_t len)
      97  {
      98    unsigned long int a0, a1, a2, a3;
      99    unsigned long int b0, b1, b2, b3;
     100    unsigned long int x;
     101    int shl, shr;
     102    shl = 8 * (srcp1 % (sizeof (unsigned long int)));
     103    shr = 8 * (sizeof (unsigned long int)) - shl;
     104    srcp1 &= -(sizeof (unsigned long int));
     105    switch (len % 4)
     106      {
     107      default:
     108      case 2:
     109        a1 = ((unsigned long int *) srcp1)[0];
     110        a2 = ((unsigned long int *) srcp1)[1];
     111        b2 = ((unsigned long int *) srcp2)[0];
     112        srcp1 -= 1 * (sizeof (unsigned long int));
     113        srcp2 -= 2 * (sizeof (unsigned long int));
     114        len += 2;
     115        goto do1;
     116      case 3:
     117        a0 = ((unsigned long int *) srcp1)[0];
     118        a1 = ((unsigned long int *) srcp1)[1];
     119        b1 = ((unsigned long int *) srcp2)[0];
     120        srcp2 -= 1 * (sizeof (unsigned long int));
     121        len += 1;
     122        goto do2;
     123      case 0:
     124        if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
     125          return 0;
     126        a3 = ((unsigned long int *) srcp1)[0];
     127        a0 = ((unsigned long int *) srcp1)[1];
     128        b0 = ((unsigned long int *) srcp2)[0];
     129        srcp1 += 1 * (sizeof (unsigned long int));
     130        goto do3;
     131      case 1:
     132        a2 = ((unsigned long int *) srcp1)[0];
     133        a3 = ((unsigned long int *) srcp1)[1];
     134        b3 = ((unsigned long int *) srcp2)[0];
     135        srcp1 += 2 * (sizeof (unsigned long int));
     136        srcp2 += 1 * (sizeof (unsigned long int));
     137        len -= 1;
     138        if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
     139          goto do0;
     140      }
     141    do
     142      {
     143        a0 = ((unsigned long int *) srcp1)[0];
     144        b0 = ((unsigned long int *) srcp2)[0];
     145        x = (((a2) >> (shl)) | ((a3) << (shr)));
     146        if (x != b3)
     147          return mymemcmp1 ((x), (b3));
     148      do3:
     149        a1 = ((unsigned long int *) srcp1)[1];
     150        b1 = ((unsigned long int *) srcp2)[1];
     151        x = (((a3) >> (shl)) | ((a0) << (shr)));
     152        if (x != b0)
     153          return mymemcmp1 ((x), (b0));
     154      do2:
     155        a2 = ((unsigned long int *) srcp1)[2];
     156        b2 = ((unsigned long int *) srcp2)[2];
     157        x = (((a0) >> (shl)) | ((a1) << (shr)));
     158        if (x != b1)
     159          return mymemcmp1 ((x), (b1));
     160      do1:
     161        a3 = ((unsigned long int *) srcp1)[3];
     162        b3 = ((unsigned long int *) srcp2)[3];
     163        x = (((a1) >> (shl)) | ((a2) << (shr)));
     164        if (x != b2)
     165          return mymemcmp1 ((x), (b2));
     166        srcp1 += 4 * (sizeof (unsigned long int));
     167        srcp2 += 4 * (sizeof (unsigned long int));
     168        len -= 4;
     169      }
     170    while (len != 0);
     171  do0:
     172    x = (((a2) >> (shl)) | ((a3) << (shr)));
     173    if (x != b3)
     174      return mymemcmp1 ((x), (b3));
     175    return 0;
     176  }
     177  
     178  __attribute__ ((noinline))
     179  int mymemcmp (const void *s1, const void *s2, size_t len)
     180  {
     181    unsigned long int a0;
     182    unsigned long int b0;
     183    long int srcp1 = (long int) s1;
     184    long int srcp2 = (long int) s2;
     185    if (srcp1 % (sizeof (unsigned long int)) == 0)
     186      return mymemcmp2 (srcp1, srcp2, len / (sizeof (unsigned long int)));
     187    else
     188      return mymemcmp3 (srcp1, srcp2, len / (sizeof (unsigned long int)));
     189  }
     190  
     191  char buf[256];
     192  
     193  int
     194  main (void)
     195  {
     196    char *p;
     197    union { long int l; char c[sizeof (long int)]; } u;
     198  
     199    /* The test above assumes little endian and long being the same size
     200       as pointer.  */
     201    if (sizeof (long int) != sizeof (void *) || sizeof (long int) < 4)
     202      return 0;
     203    u.l = 0x12345678L;
     204    if (u.c[0] != 0x78 || u.c[1] != 0x56 || u.c[2] != 0x34 || u.c[3] != 0x12)
     205      return 0;
     206  
     207    p = buf + 16 - (((long int) buf) & 15);
     208    __builtin_memcpy (p + 9,
     209  "\x1\x37\x82\xa7\x55\x49\x9d\xbf\xf8\x44\xb6\x55\x17\x8e\xf9", 15);
     210    __builtin_memcpy (p + 128 + 24,
     211  "\x1\x37\x82\xa7\x55\x49\xd0\xf3\xb7\x2a\x6d\x23\x71\x49\x6a", 15);
     212    if (mymemcmp (p + 9, p + 128 + 24, 33) != -51)
     213      __builtin_abort ();
     214    return 0;
     215  }