To generate simplified IR, make sure fold
(X & ~C) ==/!= 0 > X u</u>= C+1
is scheduled before fold
((X << Y) & C) == 0 > (X & (C >> Y)) == 0.
To generate simplified IR, make sure fold
(X & ~C) ==/!= 0 > X u</u>= C+1
is scheduled before fold
((X << Y) & C) == 0 > (X & (C >> Y)) == 0.
Looks good for IR, but looks like this needs an undo fold for backend?
https://godbolt.org/z/giY9Cp
At least for aarch64 this seems to result in worse ASM?
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1643–1645 ↗  (On Diff #205403)  Why are we restricting this fold to singleuse and? 
1655 ↗  (On Diff #205403)  ((%x & C) == 0) > %x u< (C) iff (C) is power of two. 
1656–1657 ↗  (On Diff #205403)  Why do we care about that? Seems rather arbitrary. 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1643–1645 ↗  (On Diff #205403)  Same reason in D63026 (resolving PR10267) 
1656–1657 ↗  (On Diff #205403)  take this test as example define i1 @test_shift_and_cmp_changed2(i8 %p) { %shlp = shl i8 %p, 5 %andp = and i8 %shlp, 64 %cmp = icmp ult i8 %andp, 32 ret i1 %cmp } we do miss fold for (X >> C3) & C2 != C1 > (X & (C2 << C3)) != (C1 << C3) 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1647 ↗  (On Diff #205409)  Despite how pointless it will look, please add the comment to each of the folds. 
1656–1657 ↗  (On Diff #205403)  Is that IR without this restriction? 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  for this test, should be better transforming into this define i1 @test_shift_and_cmp_changed2(i8 %p) { %andp = and i8 %p, 6 %cmp = icmp eq i8 %andp, 0 ret i1 %cmp } However, by scheduling ((%x & C) == 0) > %x u< (C) iff (C) is power of two earlier, define i1 @test_shift_and_cmp_changed2(i8 %p) { %shlp = shl i8 %p, 5 %cmp = icmp ult i8 %shlp, 64 ret i1 %cmp } 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  Yes , that is the IR without add this restriction. define i1 @test_shift_and_cmp_changed2(i8 %p) { %shlp = shl i8 %p, 5 %cmp = icmp ult i8 %shlp, 64 ret i1 %cmp } 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  Well, nice find. 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  Can you give me a spoiler, if you drop this restriction, are there any other regressions in checkllvm? 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  Here are the failing tests when dropping this restriction:
test_shift_and_cmp_changed2 and its vector version
scalar_i32_lshr_and_negC_eq_X_is_constant1 define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant1(i32 %y) { ; CHECKLABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant1( ; CHECKNEXT: [[LSHR:%.*]] = lshr i32 12345, [[Y:%.*]] ; CHECKNEXT: [[AND:%.*]] = and i32 [[LSHR]], 8 ; CHECKNEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0 +; CHECKNEXT: [[R:%.*]] = icmp ult i32 [[LSHR]], 8 ; CHECKNEXT: ret i1 [[R]] ; %lshr = lshr i32 12345, %y %and = and i32 %lshr, 4294967288 ; ~7 %r = icmp eq i32 %and, 0 ret i1 %r } define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) { ; CHECKLABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant2( ; CHECKNEXT: [[LSHR:%.*]] = lshr i32 268435456, [[Y:%.*]] ; CHECKNEXT: [[AND:%.*]] = and i32 [[LSHR]], 8 ; CHECKNEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0 +; CHECKNEXT: [[R:%.*]] = icmp ult i32 [[LSHR]], 8 ; CHECKNEXT: ret i1 [[R]] ; %lshr = lshr i32 268435456, %y %and = and i32 %lshr, 4294967288 ; ~7 %r = icmp eq i32 %and, 0 ret i1 %r }

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  I'm confused, 2. and 3. are improvements, right? 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  test file 2 and 3 are improvements. But the improved test cases are created mostly to check for correctness, I am not sure the improved test cases are actually popular in real applications. test file 1 is regression, the failing test is simplified from bit filed test bug in pr17827. Probably more prevalent in application code. Adding restriction tend to benefit more cases. 
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp  

1656–1657 ↗  (On Diff #205403)  (TLDR: It's all such a mess, isn't it?)
Given just how many these transforms are, it's not particularly relevant what can be and what can't be
So naturally, if that new pattern is now being encountered in a testcase reduced from an actual code,
But do we know that? Sadly all this patternmatching is done blindly, with no attempt at cost modelling, 
Yes , this reorder expose yet another missing fold. As regression in test/Transforms/InstCombine/pr17827.ll
Simplify 'shl' inequality test into 'and' equality test should fix this issue. I am posting this into another differential, link shortly.
icmp ult/uge (shl %x, C2), C1 iff C1 is power of two > icmp eq/ne (and %x, (lshr C1, C2)), 0
llvm/test/Transforms/InstCombine/pr17827.ll  

7 ↗  (On Diff #206042)  Please can you regenerate this test (and just directly commit, no review) to get rid of this noise. 