[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 || (x & 0x70) == 0x10 || (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 --- Comment #6 from Andrew Pinski --- #define shift 4 return ((mask(d) == (0x0 << shift)) || (mask(d) == (0x1 << shift)) || (mask(d) == (0x2 << shift))); static inline unsigned mask(const struct dentry *dentry) { return dentry->d_flags & (0x7 << shift); } ifcombine does: _4 = _5 & 112; // this was already there. _8 = _4 == 16; _7 = _4 == 0; _9 = _7 | _8; _10 = _4 == 32; _11 = _9 | _10; Which is correct. reassoc1 does: _4 = _5 & 112; _8 = _4 == 16; _1 = _4 & 4294967279; // -17 or ~16 _13 = _1 == 0; _7 = _4 == 0; _10 = _4 == 32; _11 = _10 | _13; and that is where it messes up, it misses reassocation of all three ands together. And _4 & 4294967279 removes bit 7 from the original and. Final output: _4 = _5 & 112; // 0b111 _1 = _5 & 96; // 0b110 _13 = _1 == 0; // 0b000 _10 = _4 == 32;// 0b010 _11 = _10 | _13; So we need have another pattern for something like this: (bit_ior (cmp (bit_and @0 INTEGER_CST@2) INTEGER_CST@3) (cmp (bit_and @0 INTEGER_CST@4) INTEGER_CST@5)) And maybe even one like this (which will solve the issue sooner): (bit_ior (cmp (bit_and @0 INTEGER_CST@2) INTEGER_CST@3) (cmp @0 INTEGER_CST@5)))
[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 || (x & 0x70) == 0x10 || (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 --- Comment #5 from dhowells at redhat dot com --- There's a further potential optimisation. If shift is large enough that the bits under test are outside of the LSB, the TESTB changes to a TESTL at the same address: Shift 2: 0: f6 07 1ctestb $0x1c,(%rdi) 3: 0f 94 c0sete %al 6: c3 retq Shift 10: 0: f7 07 00 1c 00 00 testl $0x1c00,(%rdi) 6: 0f 94 c0sete %al 9: c3 retq Shift 18: 0: f7 07 00 00 1c 00 testl $0x1c,(%rdi) 6: 0f 94 c0sete %al 9: c3 retq However, one could do a TESTW or a TESTB instead with a smaller immediate value and a displaced address.
[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 || (x & 0x70) == 0x10 || (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 --- Comment #4 from dhowells at redhat dot com --- (In reply to Andrew Pinski from comment #2) > ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) > > Should be false always. I suspect you had meant || rather than &&. Sorry, yes; I got the examples right, but the bz subject wrong. I've fixed that.
[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 Andrew Pinski changed: What|Removed |Added Severity|normal |enhancement
[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2016-07-27 Ever confirmed|0 |1 Severity|enhancement |normal --- Comment #3 from Andrew Pinski --- Confirmed with any shift >= 1. Shift of 0 works :).
[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 --- Comment #2 from Andrew Pinski --- ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) Should be false always. I suspect you had meant || rather than &&.
[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073 Andrew Pinski changed: What|Removed |Added Severity|normal |enhancement