Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3490,6 +3490,21 @@ } } } + + if (BO0) { + // Transform A & (L - 1) `ult` L --> L != 0 + Value *L; + auto LSubOne = m_CombineOr(m_Sub(m_Value(L), m_SpecificInt(1)), + m_Add(m_Value(L), m_AllOnes())); + auto BitwiseAnd = + m_CombineOr(m_And(m_Value(), LSubOne), m_And(LSubOne, m_Value())); + + if (match(BO0, BitwiseAnd) && + I.getPredicate() == ICmpInst::ICMP_ULT) { + auto *Zero = ConstantInt::getSigned(BO0->getType(), 0); + return new ICmpInst(ICmpInst::ICMP_NE, L, Zero); + } + } } { Value *A, *B; Index: test/Transforms/InstCombine/ult-and-bitwise-and.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/ult-and-bitwise-and.ll @@ -0,0 +1,11 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define i1 @f(i32 %val, i32 %lim) { +; CHECK: @f( + %lim.sub = add i32 %lim, -1 + %val.and = and i32 %val, %lim.sub + %r = icmp ult i32 %val.and, %lim +; CHECK: [[RESULT:%[a-z0-9]+]] = icmp ne i32 %lim, 0 +; ret i1 [[RESULT]] + ret i1 %r +}