Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2235,13 +2235,19 @@ bool IsAShr = Shr->getOpcode() == Instruction::AShr; const APInt *ShiftValC; - if (match(Shr->getOperand(0), m_APInt(ShiftValC))) { + if (match(X, m_APInt(ShiftValC))) { if (Cmp.isEquality()) return foldICmpShrConstConst(Cmp, Shr->getOperand(1), C, *ShiftValC); + // (ShiftValC >> Y) >s -1 --> Y != 0 with ShiftValC < 0 + if (!IsAShr && Pred == CmpInst::ICMP_SGT && C.isAllOnes() && + ShiftValC->isNegative()) + return new ICmpInst(CmpInst::ICMP_NE, Shr->getOperand(1), + ConstantInt::getNullValue(X->getType())); + // If the shifted constant is a power-of-2, test the shift amount directly: - // (ShiftValC >> X) >u C --> X > X) X >=u (LZ(C-1) - LZ(ShiftValC)) + // (ShiftValC >> Y) >u C --> X > Y) X >=u (LZ(C-1) - LZ(ShiftValC)) if (!IsAShr && ShiftValC->isPowerOf2() && (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_ULT)) { bool IsUGT = Pred == CmpInst::ICMP_UGT; Index: llvm/test/Transforms/InstCombine/icmp-shr.ll =================================================================== --- llvm/test/Transforms/InstCombine/icmp-shr.ll +++ llvm/test/Transforms/InstCombine/icmp-shr.ll @@ -1146,12 +1146,9 @@ ret i1 %r } -; TODO: This should reduce to X != 0. - define i1 @lshr_pow2_ult_smin(i8 %x) { ; CHECK-LABEL: @lshr_pow2_ult_smin( -; CHECK-NEXT: [[S:%.*]] = lshr i8 -128, [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[S]], -1 +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 0 ; CHECK-NEXT: ret i1 [[R]] ; %s = lshr i8 128, %x