Take this little program: int f (unsigned long a, unsigned long b, unsigned long c) { return (a & (c - 1)) != 0 || (b & (c - 1)) != 0; }
Compiled on x86-64 with gcc 4.0.2 (but I think also with the current mainline) yields with -O2 the following code: 0000000000000000 <f>: 0: 48 ff ca dec %rdx 3: 48 85 d7 test %rdx,%rdi 6: 75 07 jne f <f+0xf> 8: 31 c0 xor %eax,%eax a: 48 85 d6 test %rdx,%rsi d: 74 05 je 14 <f+0x14> f: b8 01 00 00 00 mov $0x1,%eax 14: f3 c3 repz retq As can be seen, both comparisons are executed individually. This is unnecessarily slow. Since the right operand for & is the same and this is a pure bit-test it is perfectly fine to compile the code to the equivalent of int f (unsigned long a, unsigned long b, unsigned long c) { return ((a | b) & (c - 1)) != 0; } This would be significantly faster. On archs like x86-64 no conditional jump (just a setne) would be needed. -- Summary: missing optimization in comparison of results of bit operations Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: drepper at redhat dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24696