https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70467
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- For the logicals, e.g. the following works: --- gcc/optabs.c.jj 2016-02-16 16:15:17.000000000 +0100 +++ gcc/optabs.c 2016-03-31 12:53:37.571337401 +0200 @@ -1136,6 +1136,37 @@ expand_binop (machine_mode mode, optab b op1 = force_reg (GET_MODE_INNER (mode), op1); } + /* Optimize some bitwise operations; these can be not optimized + away by GIMPLE optimizations when expanding wider bitwise operations + a word at a time. */ + + if (optimize) + { + if (binoptab == and_optab) + { + if (op1 == CONST0_RTX (mode) && ! side_effects_p (op0)) + return op1; + if (INTEGRAL_MODE_P (mode) && op1 == CONSTM1_RTX (mode)) + return op0; + } + if (binoptab == ior_optab) + { + if (op1 == CONST0_RTX (mode)) + return op0; + if (INTEGRAL_MODE_P (mode) + && op1 == CONSTM1_RTX (mode) + && ! side_effects_p (op0)) + return op1; + } + if (binoptab == xor_optab) + { + if (op1 == CONST0_RTX (mode)) + return op0; + if (INTEGRAL_MODE_P (mode) && op1 == CONSTM1_RTX (mode)) + return expand_unop (mode, one_cmpl_optab, op0, target, 0); + } + } + /* Record where to delete back to if we backtrack. */ last = get_last_insn (); Tested on void foo (unsigned long long *); void bar (void) { unsigned long long a; foo (&a); a &= 0x7fffffffffffffffULL; foo (&a); a &= 0xffffffff7fffffffULL; foo (&a); a &= 0x7fffffff00000000ULL; foo (&a); a &= 0x000000007fffffffULL; foo (&a); a &= 0x00000000ffffffffULL; foo (&a); a &= 0xffffffff00000000ULL; foo (&a); a |= 0x7fffffffffffffffULL; foo (&a); a |= 0xffffffff7fffffffULL; foo (&a); a |= 0x7fffffff00000000ULL; foo (&a); a |= 0x000000007fffffffULL; foo (&a); a |= 0x00000000ffffffffULL; foo (&a); a |= 0xffffffff00000000ULL; foo (&a); a ^= 0x7fffffffffffffffULL; foo (&a); a ^= 0xffffffff7fffffffULL; foo (&a); a ^= 0x7fffffff00000000ULL; foo (&a); a ^= 0x000000007fffffffULL; foo (&a); a ^= 0x00000000ffffffffULL; foo (&a); a ^= 0xffffffff00000000ULL; foo (&a); } Though, apparently CSE1 is able to optimize some of these (& 0, | -1, ^ -1), but not the others. So another option is to handle & -1, | 0 and ^ 0 in CSE.