Hi, I'm observing a weird behaviour in PowerPC64 Little Endian that does not seem to occur on other architectures supporting __int128. The following code, when compiled with -O1 generates wrong output.
-- test.c #include <stdio.h> typedef unsigned __int128 uint128_t; #define PRINT(value) \ { union u { uint128_t i; unsigned long long l[2]; } _t = { .i = value }; \ fprintf(stderr, "%s => <%016llx, %016llx>\n", #value, _t.l[1], _t.l[0]); } __attribute__((noinline)) uint128_t get_int(uint128_t value, unsigned int num_bytes) { uint128_t mask = ~(uint128_t)0; mask <<= (uint128_t)(8 * num_bytes); /* assuming 1 byte = 8 bits */ mask = ~mask; value &= mask; return value; } int main(int argc, char* argv[]) { uint128_t x = 0; x = get_int(10, /* num_bytes */ 1); PRINT(x); return 0; } -- end of test.c $ gcc -v Using built-in specs. COLLECT_GCC=/home/Computational/rferrer/gcc/install/bin/gcc COLLECT_LTO_WRAPPER=/home/Computational/rferrer/gcc/install/libexec/gcc/powerpc64le-unknown-linux-gnu/5.0.0/lto-wrapper Target: powerpc64le-unknown-linux-gnu Configured with: ../gcc-src/configure --prefix=/home/Computational/rferrer/gcc/install --enable-languages=c,c++,fortran --with-gmp=/home/Computational/rferrer/gcc/install --with-mpfr=/home/Computational/rferrer/gcc/install --with-mpc=/home/Computational/rferrer/gcc/install --enable-multiarch --disable-multilib Thread model: posix gcc version 5.0.0 20141218 (experimental) (GCC) $ make gcc -O0 -o test.O0 test.c ./test.O0 x => <0000000000000000, 000000000000000a> gcc -O1 -o test.O1 test.c ./test.O1 x => <ffffffffffffffff, ffffffffffffff00> It looks like GCC somehow forgets to perform the logical not in the optimized version. I'd fill a PR but I'm not sure if I'm triggering some sort of undefined behaviour in the shift/not/and sequence in 'get_int'. Is this a bug in GCC or in the code above? Kind regards, -- Roger Ferrer Ibáñez