From: Sanjay Patel Date: Mon, 15 May 2017 19:27:53 +0000 (+0000) Subject: [InstCombine] restrict icmp fold with 2 sdiv exact operands (PR32949) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d2022f1d3e2bd776e9f7098ccb63f4fd0bd87ec;p=llvm [InstCombine] restrict icmp fold with 2 sdiv exact operands (PR32949) This is the InstCombine counterpart to D32954. I added some comments about the code duplication in: rL302436 Alive-based verification: http://rise4fun.com/Alive/dPw This is a 2nd fix for the problem reported in: https://bugs.llvm.org/show_bug.cgi?id=32949 Differential Revision: https://reviews.llvm.org/D32970 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303105 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index e3639db544a..60ed4057ced 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3068,16 +3068,23 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) { } } 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(); diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index b29931c69d3..6f657b19045 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -695,11 +695,13 @@ define i1 @test48(i32 %X, i32 %Y, i32 %Z) { 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