diff options
Diffstat (limited to 'contrib/llvm/lib/Analysis/InstructionSimplify.cpp')
| -rw-r--r-- | contrib/llvm/lib/Analysis/InstructionSimplify.cpp | 250 | 
1 files changed, 231 insertions, 19 deletions
diff --git a/contrib/llvm/lib/Analysis/InstructionSimplify.cpp b/contrib/llvm/lib/Analysis/InstructionSimplify.cpp index 9d6d3398feb8..9d78f8bf4044 100644 --- a/contrib/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/contrib/llvm/lib/Analysis/InstructionSimplify.cpp @@ -913,8 +913,6 @@ static Value *SimplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,      }    } -  bool isSigned = Opcode == Instruction::SRem; -    // X % undef -> undef    if (match(Op1, m_Undef()))      return Op1; @@ -1378,6 +1376,26 @@ static const Type *GetCompareTy(Value *Op) {    return CmpInst::makeCmpResultType(Op->getType());  } +/// ExtractEquivalentCondition - Rummage around inside V looking for something +/// equivalent to the comparison "LHS Pred RHS".  Return such a value if found, +/// otherwise return null.  Helper function for analyzing max/min idioms. +static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred, +                                         Value *LHS, Value *RHS) { +  SelectInst *SI = dyn_cast<SelectInst>(V); +  if (!SI) +    return 0; +  CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition()); +  if (!Cmp) +    return 0; +  Value *CmpLHS = Cmp->getOperand(0), *CmpRHS = Cmp->getOperand(1); +  if (Pred == Cmp->getPredicate() && LHS == CmpLHS && RHS == CmpRHS) +    return Cmp; +  if (Pred == CmpInst::getSwappedPredicate(Cmp->getPredicate()) && +      LHS == CmpRHS && RHS == CmpLHS) +    return Cmp; +  return 0; +} +  /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can  /// fold the result.  If not, this returns null.  static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, @@ -1460,46 +1478,48 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,      default:        assert(false && "Unknown ICmp predicate!");      case ICmpInst::ICMP_ULT: -      return ConstantInt::getFalse(LHS->getContext()); +      // getNullValue also works for vectors, unlike getFalse. +      return Constant::getNullValue(ITy);      case ICmpInst::ICMP_UGE: -      return ConstantInt::getTrue(LHS->getContext()); +      // getAllOnesValue also works for vectors, unlike getTrue. +      return ConstantInt::getAllOnesValue(ITy);      case ICmpInst::ICMP_EQ:      case ICmpInst::ICMP_ULE:        if (isKnownNonZero(LHS, TD)) -        return ConstantInt::getFalse(LHS->getContext()); +        return Constant::getNullValue(ITy);        break;      case ICmpInst::ICMP_NE:      case ICmpInst::ICMP_UGT:        if (isKnownNonZero(LHS, TD)) -        return ConstantInt::getTrue(LHS->getContext()); +        return ConstantInt::getAllOnesValue(ITy);        break;      case ICmpInst::ICMP_SLT:        ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD);        if (LHSKnownNegative) -        return ConstantInt::getTrue(LHS->getContext()); +        return ConstantInt::getAllOnesValue(ITy);        if (LHSKnownNonNegative) -        return ConstantInt::getFalse(LHS->getContext()); +        return Constant::getNullValue(ITy);        break;      case ICmpInst::ICMP_SLE:        ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD);        if (LHSKnownNegative) -        return ConstantInt::getTrue(LHS->getContext()); +        return ConstantInt::getAllOnesValue(ITy);        if (LHSKnownNonNegative && isKnownNonZero(LHS, TD)) -        return ConstantInt::getFalse(LHS->getContext()); +        return Constant::getNullValue(ITy);        break;      case ICmpInst::ICMP_SGE:        ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD);        if (LHSKnownNegative) -        return ConstantInt::getFalse(LHS->getContext()); +        return Constant::getNullValue(ITy);        if (LHSKnownNonNegative) -        return ConstantInt::getTrue(LHS->getContext()); +        return ConstantInt::getAllOnesValue(ITy);        break;      case ICmpInst::ICMP_SGT:        ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD);        if (LHSKnownNegative) -        return ConstantInt::getFalse(LHS->getContext()); +        return Constant::getNullValue(ITy);        if (LHSKnownNonNegative && isKnownNonZero(LHS, TD)) -        return ConstantInt::getTrue(LHS->getContext()); +        return ConstantInt::getAllOnesValue(ITy);        break;      }    } @@ -1791,7 +1811,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,      case ICmpInst::ICMP_EQ:      case ICmpInst::ICMP_UGT:      case ICmpInst::ICMP_UGE: -      return ConstantInt::getFalse(RHS->getContext()); +      // getNullValue also works for vectors, unlike getFalse. +      return Constant::getNullValue(ITy);      case ICmpInst::ICMP_SLT:      case ICmpInst::ICMP_SLE:        ComputeSignBit(LHS, KnownNonNegative, KnownNegative, TD); @@ -1801,7 +1822,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,      case ICmpInst::ICMP_NE:      case ICmpInst::ICMP_ULT:      case ICmpInst::ICMP_ULE: -      return ConstantInt::getTrue(RHS->getContext()); +      // getAllOnesValue also works for vectors, unlike getTrue. +      return Constant::getAllOnesValue(ITy);      }    }    if (RBO && match(RBO, m_URem(m_Value(), m_Specific(LHS)))) { @@ -1818,7 +1840,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,      case ICmpInst::ICMP_NE:      case ICmpInst::ICMP_UGT:      case ICmpInst::ICMP_UGE: -      return ConstantInt::getTrue(RHS->getContext()); +      // getAllOnesValue also works for vectors, unlike getTrue. +      return Constant::getAllOnesValue(ITy);      case ICmpInst::ICMP_SLT:      case ICmpInst::ICMP_SLE:        ComputeSignBit(RHS, KnownNonNegative, KnownNegative, TD); @@ -1828,7 +1851,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,      case ICmpInst::ICMP_EQ:      case ICmpInst::ICMP_ULT:      case ICmpInst::ICMP_ULE: -      return ConstantInt::getFalse(RHS->getContext()); +      // getNullValue also works for vectors, unlike getFalse. +      return Constant::getNullValue(ITy);      }    } @@ -1843,7 +1867,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,        // fall-through      case Instruction::SDiv:      case Instruction::AShr: -      if (!LBO->isExact() && !RBO->isExact()) +      if (!LBO->isExact() || !RBO->isExact())          break;        if (Value *V = SimplifyICmpInst(Pred, LBO->getOperand(0),                                        RBO->getOperand(0), TD, DT, MaxRecurse-1)) @@ -1864,6 +1888,194 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,      }    } +  // Simplify comparisons involving max/min. +  Value *A, *B; +  CmpInst::Predicate P = CmpInst::BAD_ICMP_PREDICATE; +  CmpInst::Predicate EqP; // Chosen so that "A == max/min(A,B)" iff "A EqP B". + +  // Signed variants on "max(a,b)>=a -> true". +  if (match(LHS, m_SMax(m_Value(A), m_Value(B))) && (A == RHS || B == RHS)) { +    if (A != RHS) std::swap(A, B); // smax(A, B) pred A. +    EqP = CmpInst::ICMP_SGE; // "A == smax(A, B)" iff "A sge B". +    // We analyze this as smax(A, B) pred A. +    P = Pred; +  } else if (match(RHS, m_SMax(m_Value(A), m_Value(B))) && +             (A == LHS || B == LHS)) { +    if (A != LHS) std::swap(A, B); // A pred smax(A, B). +    EqP = CmpInst::ICMP_SGE; // "A == smax(A, B)" iff "A sge B". +    // We analyze this as smax(A, B) swapped-pred A. +    P = CmpInst::getSwappedPredicate(Pred); +  } else if (match(LHS, m_SMin(m_Value(A), m_Value(B))) && +             (A == RHS || B == RHS)) { +    if (A != RHS) std::swap(A, B); // smin(A, B) pred A. +    EqP = CmpInst::ICMP_SLE; // "A == smin(A, B)" iff "A sle B". +    // We analyze this as smax(-A, -B) swapped-pred -A. +    // Note that we do not need to actually form -A or -B thanks to EqP. +    P = CmpInst::getSwappedPredicate(Pred); +  } else if (match(RHS, m_SMin(m_Value(A), m_Value(B))) && +             (A == LHS || B == LHS)) { +    if (A != LHS) std::swap(A, B); // A pred smin(A, B). +    EqP = CmpInst::ICMP_SLE; // "A == smin(A, B)" iff "A sle B". +    // We analyze this as smax(-A, -B) pred -A. +    // Note that we do not need to actually form -A or -B thanks to EqP. +    P = Pred; +  } +  if (P != CmpInst::BAD_ICMP_PREDICATE) { +    // Cases correspond to "max(A, B) p A". +    switch (P) { +    default: +      break; +    case CmpInst::ICMP_EQ: +    case CmpInst::ICMP_SLE: +      // Equivalent to "A EqP B".  This may be the same as the condition tested +      // in the max/min; if so, we can just return that. +      if (Value *V = ExtractEquivalentCondition(LHS, EqP, A, B)) +        return V; +      if (Value *V = ExtractEquivalentCondition(RHS, EqP, A, B)) +        return V; +      // Otherwise, see if "A EqP B" simplifies. +      if (MaxRecurse) +        if (Value *V = SimplifyICmpInst(EqP, A, B, TD, DT, MaxRecurse-1)) +          return V; +      break; +    case CmpInst::ICMP_NE: +    case CmpInst::ICMP_SGT: { +      CmpInst::Predicate InvEqP = CmpInst::getInversePredicate(EqP); +      // Equivalent to "A InvEqP B".  This may be the same as the condition +      // tested in the max/min; if so, we can just return that. +      if (Value *V = ExtractEquivalentCondition(LHS, InvEqP, A, B)) +        return V; +      if (Value *V = ExtractEquivalentCondition(RHS, InvEqP, A, B)) +        return V; +      // Otherwise, see if "A InvEqP B" simplifies. +      if (MaxRecurse) +        if (Value *V = SimplifyICmpInst(InvEqP, A, B, TD, DT, MaxRecurse-1)) +          return V; +      break; +    } +    case CmpInst::ICMP_SGE: +      // Always true. +      return Constant::getAllOnesValue(ITy); +    case CmpInst::ICMP_SLT: +      // Always false. +      return Constant::getNullValue(ITy); +    } +  } + +  // Unsigned variants on "max(a,b)>=a -> true". +  P = CmpInst::BAD_ICMP_PREDICATE; +  if (match(LHS, m_UMax(m_Value(A), m_Value(B))) && (A == RHS || B == RHS)) { +    if (A != RHS) std::swap(A, B); // umax(A, B) pred A. +    EqP = CmpInst::ICMP_UGE; // "A == umax(A, B)" iff "A uge B". +    // We analyze this as umax(A, B) pred A. +    P = Pred; +  } else if (match(RHS, m_UMax(m_Value(A), m_Value(B))) && +             (A == LHS || B == LHS)) { +    if (A != LHS) std::swap(A, B); // A pred umax(A, B). +    EqP = CmpInst::ICMP_UGE; // "A == umax(A, B)" iff "A uge B". +    // We analyze this as umax(A, B) swapped-pred A. +    P = CmpInst::getSwappedPredicate(Pred); +  } else if (match(LHS, m_UMin(m_Value(A), m_Value(B))) && +             (A == RHS || B == RHS)) { +    if (A != RHS) std::swap(A, B); // umin(A, B) pred A. +    EqP = CmpInst::ICMP_ULE; // "A == umin(A, B)" iff "A ule B". +    // We analyze this as umax(-A, -B) swapped-pred -A. +    // Note that we do not need to actually form -A or -B thanks to EqP. +    P = CmpInst::getSwappedPredicate(Pred); +  } else if (match(RHS, m_UMin(m_Value(A), m_Value(B))) && +             (A == LHS || B == LHS)) { +    if (A != LHS) std::swap(A, B); // A pred umin(A, B). +    EqP = CmpInst::ICMP_ULE; // "A == umin(A, B)" iff "A ule B". +    // We analyze this as umax(-A, -B) pred -A. +    // Note that we do not need to actually form -A or -B thanks to EqP. +    P = Pred; +  } +  if (P != CmpInst::BAD_ICMP_PREDICATE) { +    // Cases correspond to "max(A, B) p A". +    switch (P) { +    default: +      break; +    case CmpInst::ICMP_EQ: +    case CmpInst::ICMP_ULE: +      // Equivalent to "A EqP B".  This may be the same as the condition tested +      // in the max/min; if so, we can just return that. +      if (Value *V = ExtractEquivalentCondition(LHS, EqP, A, B)) +        return V; +      if (Value *V = ExtractEquivalentCondition(RHS, EqP, A, B)) +        return V; +      // Otherwise, see if "A EqP B" simplifies. +      if (MaxRecurse) +        if (Value *V = SimplifyICmpInst(EqP, A, B, TD, DT, MaxRecurse-1)) +          return V; +      break; +    case CmpInst::ICMP_NE: +    case CmpInst::ICMP_UGT: { +      CmpInst::Predicate InvEqP = CmpInst::getInversePredicate(EqP); +      // Equivalent to "A InvEqP B".  This may be the same as the condition +      // tested in the max/min; if so, we can just return that. +      if (Value *V = ExtractEquivalentCondition(LHS, InvEqP, A, B)) +        return V; +      if (Value *V = ExtractEquivalentCondition(RHS, InvEqP, A, B)) +        return V; +      // Otherwise, see if "A InvEqP B" simplifies. +      if (MaxRecurse) +        if (Value *V = SimplifyICmpInst(InvEqP, A, B, TD, DT, MaxRecurse-1)) +          return V; +      break; +    } +    case CmpInst::ICMP_UGE: +      // Always true. +      return Constant::getAllOnesValue(ITy); +    case CmpInst::ICMP_ULT: +      // Always false. +      return Constant::getNullValue(ITy); +    } +  } + +  // Variants on "max(x,y) >= min(x,z)". +  Value *C, *D; +  if (match(LHS, m_SMax(m_Value(A), m_Value(B))) && +      match(RHS, m_SMin(m_Value(C), m_Value(D))) && +      (A == C || A == D || B == C || B == D)) { +    // max(x, ?) pred min(x, ?). +    if (Pred == CmpInst::ICMP_SGE) +      // Always true. +      return Constant::getAllOnesValue(ITy); +    if (Pred == CmpInst::ICMP_SLT) +      // Always false. +      return Constant::getNullValue(ITy); +  } else if (match(LHS, m_SMin(m_Value(A), m_Value(B))) && +             match(RHS, m_SMax(m_Value(C), m_Value(D))) && +             (A == C || A == D || B == C || B == D)) { +    // min(x, ?) pred max(x, ?). +    if (Pred == CmpInst::ICMP_SLE) +      // Always true. +      return Constant::getAllOnesValue(ITy); +    if (Pred == CmpInst::ICMP_SGT) +      // Always false. +      return Constant::getNullValue(ITy); +  } else if (match(LHS, m_UMax(m_Value(A), m_Value(B))) && +             match(RHS, m_UMin(m_Value(C), m_Value(D))) && +             (A == C || A == D || B == C || B == D)) { +    // max(x, ?) pred min(x, ?). +    if (Pred == CmpInst::ICMP_UGE) +      // Always true. +      return Constant::getAllOnesValue(ITy); +    if (Pred == CmpInst::ICMP_ULT) +      // Always false. +      return Constant::getNullValue(ITy); +  } else if (match(LHS, m_UMin(m_Value(A), m_Value(B))) && +             match(RHS, m_UMax(m_Value(C), m_Value(D))) && +             (A == C || A == D || B == C || B == D)) { +    // min(x, ?) pred max(x, ?). +    if (Pred == CmpInst::ICMP_ULE) +      // Always true. +      return Constant::getAllOnesValue(ITy); +    if (Pred == CmpInst::ICMP_UGT) +      // Always false. +      return Constant::getNullValue(ITy); +  } +    // If the comparison is with the result of a select instruction, check whether    // comparing with either branch of the select always yields the same value.    if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))  | 
