--- Single bit tests: if ((x & C) == 0) x |= C becomes x |= C if ((x & C) != 0) x ^= C becomes x &= ~C if ((x & C) == 0) x ^= C becomes x |= C if ((x & C) != 0) x &= ~C becomes x &= ~C if ((x & C) == 0) x &= ~C becomes nothing --- %tmp.3 = shr long %tmp.1, ubyte 23 ; [#uses=1] %tmp.6 = cast long %tmp.3 to int ; [#uses=1] to: %X = cast long %tmp.1 to int %Y = shr int %X, 31 Allowing us to fold this: int foo(int a) { return (a & (1LL << 23)) ? 1 : 2; } into: int foo(int a) { return (a < 0) ? 1 : 2; } -------- Simple: A <= 7 && B <= 7 -> (A|B) <= 7 A == 0 && B == 0 -> (A|B) == 0 A < 0 || B < 0 -> (A|B) < 0 (1 << a) & 1 -> a == 0 ----------------- Function that could use some combining: ftp://ftp.ics.uci.edu/pub/spark/benchmarks/adpcm/adpcm_decode-original.c (A & ~B) - (A & B) = (A & ~B) + ~(A & B) + 1 = (A & ~B) + (~A & B) + ~B + 1 = (A & ~B) + (~A & B) - B = (A ^ B) - B. Example: array[(index & ~3) + (3 - (index & 3))] -> array[index ^ 3] -------------------- - if (!((1 << which_alternative) & 0x3)) + if (which_alternative >= 2) also: - if (((1 << which_alternative) & 0x7)) + if (which_alternative < 3)