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.

Reply via email to