diff --git a/gcc/testsuite/gcc.dg/pr113722.c b/gcc/testsuite/gcc.dg/pr113722.c new file mode 100644 index 0000000000000000000000000000000000000000..74b9e49cef61433c781c7434e8b8c983fde86c8e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr113722.c @@ -0,0 +1,22 @@ +/* PR middle-end/113722 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2" } */ + +int +main () +{ + unsigned __int128 a = __builtin_bswap128 ((unsigned __int128) 2); + if (a != ((unsigned __int128) 2) << 120) + __builtin_abort (); + a = __builtin_bswap128 ((unsigned __int128) 0xdeadbeefULL); + if (a != ((unsigned __int128) 0xefbeaddeULL) << 96) + __builtin_abort (); + a = __builtin_bswap128 (((unsigned __int128) 0xdeadbeefULL) << 64); + if (a != ((unsigned __int128) 0xefbeaddeULL) << 32) + __builtin_abort (); + a = __builtin_bswap128 ((((unsigned __int128) 0xdeadbeefULL) << 64) + | 0xcafed00dfeedbac1ULL); + if (a != ((((unsigned __int128) 0xc1baedfe0dd0fecaULL) << 64) + | (((unsigned __int128) 0xefbeaddeULL) << 32))) + __builtin_abort (); +} diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc index af6c0e006ea825202dab4cf8a790902b1e3b69fd..5067493d5084b3f4448c599a898f10733dc1c62a 100644 --- a/gcc/wide-int.cc +++ b/gcc/wide-int.cc @@ -729,20 +729,19 @@ wi::set_bit_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval, } } -/* Byte swap the integer represented by XVAL and LEN into VAL. Return +/* Byte swap the integer represented by XVAL and XLEN into VAL. Return the number of blocks in VAL. Both XVAL and VAL have PRECISION bits. */ unsigned int wi::bswap_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval, - unsigned int len, unsigned int precision) + unsigned int xlen, unsigned int precision) { - unsigned int i, s; + unsigned int s, len = BLOCKS_NEEDED (precision); /* This is not a well defined operation if the precision is not a multiple of 8. */ gcc_assert ((precision & 0x7) == 0); - for (i = 0; i < len; i++) - val[i] = 0; + memset (val, 0, sizeof (unsigned HOST_WIDE_INT) * len); /* Only swap the bytes that are not the padding. */ for (s = 0; s < precision; s += 8) @@ -753,7 +752,7 @@ wi::bswap_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval, unsigned int block = s / HOST_BITS_PER_WIDE_INT; unsigned int offset = s & (HOST_BITS_PER_WIDE_INT - 1); - byte = (safe_uhwi (xval, len, block) >> offset) & 0xff; + byte = (safe_uhwi (xval, xlen, block) >> offset) & 0xff; block = d / HOST_BITS_PER_WIDE_INT; offset = d & (HOST_BITS_PER_WIDE_INT - 1);