http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60941
--- Comment #1 from Martin Husemann <martin at netbsd dot org> --- Here is a small test program: ---8<--- #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { unsigned long v[2], *p; int a, b; for (int i = 0; i < 2 && i < argc; i++) { v[i] = atol(argv[i+1]) | 0xfff8800000000000; printf("i = %d, got: %lx\n", i, v[i]); } p = &v[1]; a = *p-- & 0x0ffffffff; b = *p & 0x0ffffffff; printf("a = %08x b= %08x\n", a, b); b = a << (b & 31); *p = ((uint64_t)(uint32_t)b) | 0xfff8800000000000; printf("res: %08lx\n", *p); return 0; } --->8--- compile with c++ -Wall -O2 test.c and run as: > ./a.out 26 1359893119 i = 0, got: fff880000000001a i = 1, got: fff88000510e527f a = 510e527f b= 0000001a res: fffcb949fc000000 I would have expected res: 0xfff88000fc000000 (and on amd64 I get exactly that)