From d3000982c588933c523e1fb25bc2275f99d7f644 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Sun, 2 Oct 2016 02:40:27 +0000 Subject: [PATCH] Revert r283057 and r283058 They've broken the sanitizer-bootstrap bots. Reverting while I investigate. Original commit messages: r283057: "[ConstantRange] Make getEquivalentICmp smarter" r283058: "[SCEV] Rely on ConstantRange instead of custom logic; NFCI" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283062 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolution.cpp | 176 ++++++++++++++++++++--------- lib/IR/ConstantRange.cpp | 8 -- unittests/IR/ConstantRangeTest.cpp | 31 ----- 3 files changed, 124 insertions(+), 91 deletions(-) diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 70e0c297a8d..c7381d63922 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -7337,77 +7337,149 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred, // cases, and canonicalize *-or-equal comparisons to regular comparisons. if (const SCEVConstant *RC = dyn_cast(RHS)) { const APInt &RA = RC->getAPInt(); - - bool SimplifiedByConstantRange = false; - - if (!ICmpInst::isEquality(Pred)) { - ConstantRange ExactCR = ConstantRange::makeExactICmpRegion(Pred, RA); - if (ExactCR.isFullSet()) - goto trivially_true; - else if (ExactCR.isEmptySet()) - goto trivially_false; - - APInt NewRHS; - CmpInst::Predicate NewPred; - if (ExactCR.getEquivalentICmp(NewPred, NewRHS) && - ICmpInst::isEquality(NewPred)) { - // We were able to convert an inequality to an equality. - Pred = NewPred; - RHS = getConstant(NewRHS); - Changed = SimplifiedByConstantRange = true; + switch (Pred) { + default: llvm_unreachable("Unexpected ICmpInst::Predicate value!"); + case ICmpInst::ICMP_EQ: + case ICmpInst::ICMP_NE: + // Fold ((-1) * %a) + %b == 0 (equivalent to %b-%a == 0) into %a == %b. + if (!RA) + if (const SCEVAddExpr *AE = dyn_cast(LHS)) + if (const SCEVMulExpr *ME = dyn_cast(AE->getOperand(0))) + if (AE->getNumOperands() == 2 && ME->getNumOperands() == 2 && + ME->getOperand(0)->isAllOnesValue()) { + RHS = AE->getOperand(1); + LHS = ME->getOperand(1); + Changed = true; + } + break; + case ICmpInst::ICMP_UGE: + if ((RA - 1).isMinValue()) { + Pred = ICmpInst::ICMP_NE; + RHS = getConstant(RA - 1); + Changed = true; + break; } - } + if (RA.isMaxValue()) { + Pred = ICmpInst::ICMP_EQ; + Changed = true; + break; + } + if (RA.isMinValue()) goto trivially_true; - if (!SimplifiedByConstantRange) { - switch (Pred) { - default: + Pred = ICmpInst::ICMP_UGT; + RHS = getConstant(RA - 1); + Changed = true; + break; + case ICmpInst::ICMP_ULE: + if ((RA + 1).isMaxValue()) { + Pred = ICmpInst::ICMP_NE; + RHS = getConstant(RA + 1); + Changed = true; break; - case ICmpInst::ICMP_EQ: - case ICmpInst::ICMP_NE: - // Fold ((-1) * %a) + %b == 0 (equivalent to %b-%a == 0) into %a == %b. - if (!RA) - if (const SCEVAddExpr *AE = dyn_cast(LHS)) - if (const SCEVMulExpr *ME = - dyn_cast(AE->getOperand(0))) - if (AE->getNumOperands() == 2 && ME->getNumOperands() == 2 && - ME->getOperand(0)->isAllOnesValue()) { - RHS = AE->getOperand(1); - LHS = ME->getOperand(1); - Changed = true; - } + } + if (RA.isMinValue()) { + Pred = ICmpInst::ICMP_EQ; + Changed = true; break; + } + if (RA.isMaxValue()) goto trivially_true; + Pred = ICmpInst::ICMP_ULT; + RHS = getConstant(RA + 1); + Changed = true; + break; + case ICmpInst::ICMP_SGE: + if ((RA - 1).isMinSignedValue()) { + Pred = ICmpInst::ICMP_NE; + RHS = getConstant(RA - 1); + Changed = true; + break; + } + if (RA.isMaxSignedValue()) { + Pred = ICmpInst::ICMP_EQ; + Changed = true; + break; + } + if (RA.isMinSignedValue()) goto trivially_true; - // The "Should have been caught earlier!" messages refer to the fact - // that the ExactCR.isFullSet() or ExactCR.isEmptySet() check above - // should have fired on the corresponding cases, and canonicalized the - // check to trivially_true or trivially_false. + Pred = ICmpInst::ICMP_SGT; + RHS = getConstant(RA - 1); + Changed = true; + break; + case ICmpInst::ICMP_SLE: + if ((RA + 1).isMaxSignedValue()) { + Pred = ICmpInst::ICMP_NE; + RHS = getConstant(RA + 1); + Changed = true; + break; + } + if (RA.isMinSignedValue()) { + Pred = ICmpInst::ICMP_EQ; + Changed = true; + break; + } + if (RA.isMaxSignedValue()) goto trivially_true; - case ICmpInst::ICMP_UGE: - assert(!RA.isMinValue() && "Should have been caught earlier!"); - Pred = ICmpInst::ICMP_UGT; - RHS = getConstant(RA - 1); + Pred = ICmpInst::ICMP_SLT; + RHS = getConstant(RA + 1); + Changed = true; + break; + case ICmpInst::ICMP_UGT: + if (RA.isMinValue()) { + Pred = ICmpInst::ICMP_NE; Changed = true; break; - case ICmpInst::ICMP_ULE: - assert(!RA.isMaxValue() && "Should have been caught earlier!"); - Pred = ICmpInst::ICMP_ULT; + } + if ((RA + 1).isMaxValue()) { + Pred = ICmpInst::ICMP_EQ; RHS = getConstant(RA + 1); Changed = true; break; - case ICmpInst::ICMP_SGE: - assert(!RA.isMinSignedValue() && "Should have been caught earlier!"); - Pred = ICmpInst::ICMP_SGT; + } + if (RA.isMaxValue()) goto trivially_false; + break; + case ICmpInst::ICMP_ULT: + if (RA.isMaxValue()) { + Pred = ICmpInst::ICMP_NE; + Changed = true; + break; + } + if ((RA - 1).isMinValue()) { + Pred = ICmpInst::ICMP_EQ; RHS = getConstant(RA - 1); Changed = true; break; - case ICmpInst::ICMP_SLE: - assert(!RA.isMaxSignedValue() && "Should have been caught earlier!"); - Pred = ICmpInst::ICMP_SLT; + } + if (RA.isMinValue()) goto trivially_false; + break; + case ICmpInst::ICMP_SGT: + if (RA.isMinSignedValue()) { + Pred = ICmpInst::ICMP_NE; + Changed = true; + break; + } + if ((RA + 1).isMaxSignedValue()) { + Pred = ICmpInst::ICMP_EQ; RHS = getConstant(RA + 1); Changed = true; break; } + if (RA.isMaxSignedValue()) goto trivially_false; + break; + case ICmpInst::ICMP_SLT: + if (RA.isMaxSignedValue()) { + Pred = ICmpInst::ICMP_NE; + Changed = true; + break; + } + if ((RA - 1).isMinSignedValue()) { + Pred = ICmpInst::ICMP_EQ; + RHS = getConstant(RA - 1); + Changed = true; + break; + } + if (RA.isMinSignedValue()) goto trivially_false; + break; } } diff --git a/lib/IR/ConstantRange.cpp b/lib/IR/ConstantRange.cpp index 0dbefc7b0c2..0f5c7128f3d 100644 --- a/lib/IR/ConstantRange.cpp +++ b/lib/IR/ConstantRange.cpp @@ -147,14 +147,6 @@ bool ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred, Pred = isEmptySet() ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE; RHS = APInt(getBitWidth(), 0); Success = true; - } else if (auto *OnlyElt = getSingleElement()) { - Pred = CmpInst::ICMP_EQ; - RHS = *OnlyElt; - Success = true; - } else if (auto *OnlyMissingElt = inverse().getSingleElement()) { - Pred = CmpInst::ICMP_NE; - RHS = *OnlyMissingElt; - Success = true; } else if (getLower().isMinSignedValue() || getLower().isMinValue()) { Pred = getLower().isMinSignedValue() ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT; diff --git a/unittests/IR/ConstantRangeTest.cpp b/unittests/IR/ConstantRangeTest.cpp index 423f0627917..f7a8a82043b 100644 --- a/unittests/IR/ConstantRangeTest.cpp +++ b/unittests/IR/ConstantRangeTest.cpp @@ -760,37 +760,6 @@ TEST(ConstantRange, GetEquivalentICmp) { EXPECT_FALSE(ConstantRange(APInt::getMinValue(32) - APInt(32, 100), APInt::getMinValue(32) + APInt(32, 100)) .getEquivalentICmp(Pred, RHS)); - - EXPECT_TRUE(ConstantRange(APInt(32, 100)).getEquivalentICmp(Pred, RHS)); - EXPECT_EQ(Pred, CmpInst::ICMP_EQ); - EXPECT_EQ(RHS, APInt(32, 100)); - - EXPECT_TRUE( - ConstantRange(APInt(32, 100)).inverse().getEquivalentICmp(Pred, RHS)); - EXPECT_EQ(Pred, CmpInst::ICMP_NE); - EXPECT_EQ(RHS, APInt(32, 100)); - - // NB! It would be correct for the following four calls to getEquivalentICmp - // to return ordered predicates like CmpInst::ICMP_ULT or CmpInst::ICMP_UGT. - // However, that's not the case today. - - EXPECT_TRUE(ConstantRange(APInt(32, 0)).getEquivalentICmp(Pred, RHS)); - EXPECT_EQ(Pred, CmpInst::ICMP_EQ); - EXPECT_EQ(RHS, APInt(32, 0)); - - EXPECT_TRUE( - ConstantRange(APInt(32, 0)).inverse().getEquivalentICmp(Pred, RHS)); - EXPECT_EQ(Pred, CmpInst::ICMP_NE); - EXPECT_EQ(RHS, APInt(32, 0)); - - EXPECT_TRUE(ConstantRange(APInt(32, -1)).getEquivalentICmp(Pred, RHS)); - EXPECT_EQ(Pred, CmpInst::ICMP_EQ); - EXPECT_EQ(RHS, APInt(32, -1)); - - EXPECT_TRUE( - ConstantRange(APInt(32, -1)).inverse().getEquivalentICmp(Pred, RHS)); - EXPECT_EQ(Pred, CmpInst::ICMP_NE); - EXPECT_EQ(RHS, APInt(32, -1)); } } // anonymous namespace -- 2.50.1