John Regehr reports that GCC is folding X*2&1 to zero. ComputedMaskedBits and SimplifyDemandedBits should know that multiplications by powers of two leave predictable zeros in the low bits of the result.
The bug John reported is: "int a, b; void fn1() { b = a * ~1 == 1; }" and missed IR pattern is: %mul = mul nsw i32 %0, -2 %cmp = icmp eq i32 %mul, 1 What we're missing is that ctz(x*y) >= max(ctz(x), ctz(y)). For %mul that gets us one trailing zero. Fortunately we get x*2&1 right, and both ComputeMaskedBits and SimplifyDemandedBits know about that one ...
> What we're missing is that ctz(x*y) >= max(ctz(x), ctz(y)). For %mul that gets > us one trailing zero. ComputeMaskedBitsMul already does that. Maybe (in)equality comparisons need to be taught that their operands can't be equal if one has a known zero where the other has a known one?
> Maybe (in)equality comparisons need to be taught that their operands can't be > equal if one has a known zero where the other has a known one? Proposed patch here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140519/218082.html
Both the test case in the first and the second post seem to be fixed on trunk.
This probably got fixed by https://reviews.llvm.org/D12801 "[ValueTracking] Add a new predicate: isKnownNonEqual()".
Resolving, this was fixed around 3.5: https://c.godbolt.org/z/h7EK93q6T