diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2007-04-07 04:49:12 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2007-04-07 04:49:12 +0000 |
commit | a995d920d5547fb2d3c11e1bf912106a178e2bea (patch) | |
tree | 1c5f46be0b2e4ace39475fa1bb3910a11a813dc1 | |
parent | 46b58f78697fafa1500228337c84dc969a8bfcc3 (diff) | |
download | external_llvm-a995d920d5547fb2d3c11e1bf912106a178e2bea.zip external_llvm-a995d920d5547fb2d3c11e1bf912106a178e2bea.tar.gz external_llvm-a995d920d5547fb2d3c11e1bf912106a178e2bea.tar.bz2 |
Support NE inequality in ValueRanges.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/PredicateSimplifier.cpp | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp index 8805dee..2febab9 100644 --- a/lib/Transforms/Scalar/PredicateSimplifier.cpp +++ b/lib/Transforms/Scalar/PredicateSimplifier.cpp @@ -949,6 +949,60 @@ namespace { update(V, CR, Subtree); } + void addNotEquals(Value *V1, Value *V2, ETNode *Subtree, VRPSolver *VRP) { + uint32_t W = typeToWidth(V1->getType()); + if (!W) return; + + ConstantRange CR1 = rangeFromValue(V1, Subtree, W); + ConstantRange CR2 = rangeFromValue(V2, Subtree, W); + + if (const APInt *I = CR1.getSingleElement()) { + if (CR2.isFullSet()) { + ConstantRange NewCR2(CR1.getUpper(), CR1.getLower()); + applyRange(V2, NewCR2, Subtree, VRP); + } else if (*I == CR2.getLower()) { + APInt NewLower = CR2.getLower() + 1, + NewUpper = CR2.getUpper(); + if (NewLower == NewUpper) + NewLower = NewUpper = APInt::getMinValue(W); + + ConstantRange NewCR2(NewLower, NewUpper); + applyRange(V2, NewCR2, Subtree, VRP); + } else if (*I == CR2.getUpper() - 1) { + APInt NewLower = CR2.getLower(), + NewUpper = CR2.getUpper() - 1; + if (NewLower == NewUpper) + NewLower = NewUpper = APInt::getMinValue(W); + + ConstantRange NewCR2(NewLower, NewUpper); + applyRange(V2, NewCR2, Subtree, VRP); + } + } + + if (const APInt *I = CR2.getSingleElement()) { + if (CR1.isFullSet()) { + ConstantRange NewCR1(CR2.getUpper(), CR2.getLower()); + applyRange(V1, NewCR1, Subtree, VRP); + } else if (*I == CR1.getLower()) { + APInt NewLower = CR1.getLower() + 1, + NewUpper = CR1.getUpper(); + if (NewLower == NewUpper) + NewLower = NewUpper = APInt::getMinValue(W); + + ConstantRange NewCR1(NewLower, NewUpper); + applyRange(V1, NewCR1, Subtree, VRP); + } else if (*I == CR1.getUpper() - 1) { + APInt NewLower = CR1.getLower(), + NewUpper = CR1.getUpper() - 1; + if (NewLower == NewUpper) + NewLower = NewUpper = APInt::getMinValue(W); + + ConstantRange NewCR1(NewLower, NewUpper); + applyRange(V1, NewCR1, Subtree, VRP); + } + } + } + void addInequality(Value *V1, Value *V2, ETNode *Subtree, LatticeVal LV, VRPSolver *VRP) { assert(!isRelatedBy(V1, V2, Subtree, LV) && "Asked to do useless work."); @@ -956,9 +1010,10 @@ namespace { assert(isCanonical(V1, Subtree, VRP) && "Value not canonical."); assert(isCanonical(V2, Subtree, VRP) && "Value not canonical."); - if (LV == NE) return; // we can't represent those. - // XXX: except in the case where isSingleElement and equal to either - // Lower or Upper. That's probably not profitable. (Type::Int1Ty?) + if (LV == NE) { + addNotEquals(V1, V2, Subtree, VRP); + return; + } uint32_t W = typeToWidth(V1->getType()); if (!W) return; |