Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -2007,18 +2007,19 @@ Worklist.push_back(std::make_pair(Op0, Op1)); } + uint32_t NextNum = VN.getNextUnusedValueNumber(); + // If "A >= B" is known true, replace "A < B" with false everywhere. CmpInst::Predicate NotPred = Cmp->getInversePredicate(); Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse); // Since we don't have the instruction "A < B" immediately to hand, work // out the value number that it would have and use that to find an // appropriate instruction (if any). - uint32_t NextNum = VN.getNextUnusedValueNumber(); - uint32_t Num = VN.lookupOrAddCmp(Cmp->getOpcode(), NotPred, Op0, Op1); + uint32_t NotNum = VN.lookupOrAddCmp(Cmp->getOpcode(), NotPred, Op0, Op1); // If the number we were assigned was brand new then there is no point in // looking for an instruction realizing it: there cannot be one! - if (Num < NextNum) { - Value *NotCmp = findLeader(Root.getEnd(), Num); + if (NotNum < NextNum) { + Value *NotCmp = findLeader(Root.getEnd(), NotNum); if (NotCmp && isa(NotCmp)) { unsigned NumReplacements = DominatesByEdge @@ -2034,7 +2035,73 @@ // The leader table only tracks basic blocks, not edges. Only add to if we // have the simple case where the edge dominates the end. if (RootDominatesEnd) - addToLeaderTable(Num, NotVal, Root.getEnd()); + addToLeaderTable(NotNum, NotVal, Root.getEnd()); + + // If "A > B" is known true, replace "A == B" with false and + // "A != B" with true. + if (isa(Cmp) && cast(Cmp)->isRelational() && + ((isKnownTrue && Cmp->isFalseWhenEqual()) || + (isKnownFalse && Cmp->isTrueWhenEqual()))) { + uint32_t FalseNum = VN.lookupOrAddCmp( + Cmp->getOpcode(), + CmpInst::Predicate::ICMP_EQ, + Op0, + Op1 + ); + uint32_t TrueNum = VN.lookupOrAddCmp( + Cmp->getOpcode(), + CmpInst::Predicate::ICMP_NE, + Op0, + Op1 + ); + if (TrueNum < NextNum) { + Value *TrueCmp = findLeader(Root.getEnd(), TrueNum); + if (TrueCmp && isa(TrueCmp)) { + unsigned NumReplacements = + DominatesByEdge + ? replaceDominatedUsesWith(TrueCmp, + ConstantInt::getTrue( + Cmp->getContext() + ), + *DT, + Root) + : replaceDominatedUsesWith(TrueCmp, + ConstantInt::getTrue( + Cmp->getContext() + ), + *DT, + Root.getStart()); + Changed |= NumReplacements > 0; + NumGVNEqProp += NumReplacements; + } + } + if (FalseNum < NextNum) { + Value *FalseCmp = findLeader(Root.getEnd(), TrueNum); + if (FalseCmp && isa(FalseCmp)) { + unsigned NumReplacements = + DominatesByEdge + ? replaceDominatedUsesWith(FalseCmp, + ConstantInt::getFalse( + Cmp->getContext() + ), + *DT, + Root) + : replaceDominatedUsesWith(FalseCmp, + ConstantInt::getFalse( + Cmp->getContext() + ), + *DT, + Root.getStart()); + Changed |= NumReplacements > 0; + NumGVNEqProp += NumReplacements; + } + } + if (RootDominatesEnd) { + addToLeaderTable(TrueNum, ConstantInt::getTrue(Cmp->getContext()), Root.getEnd()); + addToLeaderTable(FalseNum, ConstantInt::getTrue(Cmp->getContext()), Root.getEnd()); + } + } + } continue; }