Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3068,16 +3068,23 @@ } } break; + case Instruction::UDiv: case Instruction::LShr: - if (I.isSigned()) + if (I.isSigned() || !BO0->isExact() || !BO1->isExact()) break; - LLVM_FALLTHROUGH; + return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); + case Instruction::SDiv: + if (!I.isEquality() || !BO0->isExact() || !BO1->isExact()) + break; + return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); + case Instruction::AShr: if (!BO0->isExact() || !BO1->isExact()) break; return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); + case Instruction::Shl: { bool NUW = BO0->hasNoUnsignedWrap() && BO1->hasNoUnsignedWrap(); bool NSW = BO0->hasNoSignedWrap() && BO1->hasNoSignedWrap(); Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -695,11 +695,13 @@ ret i1 %C } -; FIXME: The above transform only works for equality predicates. +; The above transform only works for equality predicates. define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) { ; CHECK-LABEL: @PR32949( -; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 %X, %Y +; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 %X, %Z +; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 %Y, %Z +; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]] ; CHECK-NEXT: ret i1 [[C]] ; %A = sdiv exact i32 %X, %Z