diff options
Diffstat (limited to 'contrib/llvm/lib/IR/ConstantFold.cpp')
| -rw-r--r-- | contrib/llvm/lib/IR/ConstantFold.cpp | 177 | 
1 files changed, 117 insertions, 60 deletions
| diff --git a/contrib/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm/lib/IR/ConstantFold.cpp index 39d9a1d0a282..3f64c43e902d 100644 --- a/contrib/llvm/lib/IR/ConstantFold.cpp +++ b/contrib/llvm/lib/IR/ConstantFold.cpp @@ -132,7 +132,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {          if (ElTy == DPTy->getElementType())            // This GEP is inbounds because all indices are zero. -          return ConstantExpr::getInBoundsGetElementPtr(V, IdxList); +          return ConstantExpr::getInBoundsGetElementPtr(PTy->getElementType(), +                                                        V, IdxList);        }    // Handle casts from one vector constant to another.  We know that the src  @@ -169,7 +170,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {        // be the same. Consequently, we just fold to V.        return V; -    if (DestTy->isFloatingPointTy()) +    // See note below regarding the PPC_FP128 restriction. +    if (DestTy->isFloatingPointTy() && !DestTy->isPPC_FP128Ty())        return ConstantFP::get(DestTy->getContext(),                               APFloat(DestTy->getFltSemantics(),                                       CI->getValue())); @@ -179,9 +181,19 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {    }    // Handle ConstantFP input: FP -> Integral. -  if (ConstantFP *FP = dyn_cast<ConstantFP>(V)) +  if (ConstantFP *FP = dyn_cast<ConstantFP>(V)) { +    // PPC_FP128 is really the sum of two consecutive doubles, where the first +    // double is always stored first in memory, regardless of the target +    // endianness. The memory layout of i128, however, depends on the target +    // endianness, and so we can't fold this without target endianness +    // information. This should instead be handled by +    // Analysis/ConstantFolding.cpp +    if (FP->getType()->isPPC_FP128Ty()) +      return nullptr; +      return ConstantInt::get(FP->getContext(),                              FP->getValueAPF().bitcastToAPInt()); +  }    return nullptr;  } @@ -620,8 +632,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))        if (CE->getOpcode() == Instruction::GetElementPtr &&            CE->getOperand(0)->isNullValue()) { -        Type *Ty = -          cast<PointerType>(CE->getOperand(0)->getType())->getElementType(); +        GEPOperator *GEPO = cast<GEPOperator>(CE); +        Type *Ty = GEPO->getSourceElementType();          if (CE->getNumOperands() == 2) {            // Handle a sizeof-like expression.            Constant *Idx = CE->getOperand(1); @@ -777,11 +789,10 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,      return UndefValue::get(Val->getType()->getVectorElementType());    if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) { -    uint64_t Index = CIdx->getZExtValue();      // ee({w,x,y,z}, wrong_value) -> undef -    if (Index >= Val->getType()->getVectorNumElements()) +    if (CIdx->uge(Val->getType()->getVectorNumElements()))        return UndefValue::get(Val->getType()->getVectorElementType()); -    return Val->getAggregateElement(Index); +    return Val->getAggregateElement(CIdx->getZExtValue());    }    return nullptr;  } @@ -789,23 +800,30 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,  Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,                                                       Constant *Elt,                                                       Constant *Idx) { +  if (isa<UndefValue>(Idx)) +    return UndefValue::get(Val->getType()); +    ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);    if (!CIdx) return nullptr; -  const APInt &IdxVal = CIdx->getValue(); -   + +  unsigned NumElts = Val->getType()->getVectorNumElements(); +  if (CIdx->uge(NumElts)) +    return UndefValue::get(Val->getType()); +    SmallVector<Constant*, 16> Result; -  Type *Ty = IntegerType::get(Val->getContext(), 32); -  for (unsigned i = 0, e = Val->getType()->getVectorNumElements(); i != e; ++i){ +  Result.reserve(NumElts); +  auto *Ty = Type::getInt32Ty(Val->getContext()); +  uint64_t IdxVal = CIdx->getZExtValue(); +  for (unsigned i = 0; i != NumElts; ++i) {          if (i == IdxVal) {        Result.push_back(Elt);        continue;      } -    Constant *C = -      ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i)); +    Constant *C = ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));      Result.push_back(C);    } -   +    return ConstantVector::get(Result);  } @@ -1273,15 +1291,17 @@ static int IdxCompare(Constant *C1, Constant *C2, Type *ElTy) {    if (!isa<ConstantInt>(C1) || !isa<ConstantInt>(C2))      return -2; // don't know! -  // Ok, we have two differing integer indices.  Sign extend them to be the same -  // type.  Long is always big enough, so we use it. -  if (!C1->getType()->isIntegerTy(64)) -    C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(C1->getContext())); +  // We cannot compare the indices if they don't fit in an int64_t. +  if (cast<ConstantInt>(C1)->getValue().getActiveBits() > 64 || +      cast<ConstantInt>(C2)->getValue().getActiveBits() > 64) +    return -2; // don't know! -  if (!C2->getType()->isIntegerTy(64)) -    C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(C1->getContext())); +  // Ok, we have two differing integer indices.  Sign extend them to be the same +  // type. +  int64_t C1Val = cast<ConstantInt>(C1)->getSExtValue(); +  int64_t C2Val = cast<ConstantInt>(C2)->getSExtValue(); -  if (C1 == C2) return 0;  // They are equal +  if (C1Val == C2Val) return 0;  // They are equal    // If the type being indexed over is really just a zero sized type, there is    // no pointer difference being made here. @@ -1290,8 +1310,7 @@ static int IdxCompare(Constant *C1, Constant *C2, Type *ElTy) {    // If they are really different, now that they are the same type, then we    // found a difference! -  if (cast<ConstantInt>(C1)->getSExtValue() <  -      cast<ConstantInt>(C2)->getSExtValue()) +  if (C1Val < C2Val)      return -1;    else      return 1; @@ -1317,7 +1336,7 @@ static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) {    if (!isa<ConstantExpr>(V1)) {      if (!isa<ConstantExpr>(V2)) { -      // We distilled thisUse the standard constant folder for a few cases +      // Simple case, use the standard constant folder.        ConstantInt *R = nullptr;        R = dyn_cast<ConstantInt>(                        ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, V1, V2)); @@ -1366,7 +1385,7 @@ static ICmpInst::Predicate areGlobalsPotentiallyEqual(const GlobalValue *GV1,      if (GV->hasExternalWeakLinkage() || GV->hasWeakAnyLinkage())        return true;      if (const auto *GVar = dyn_cast<GlobalVariable>(GV)) { -      Type *Ty = GVar->getType()->getPointerElementType(); +      Type *Ty = GVar->getValueType();        // A global with opaque type might end up being zero sized.        if (!Ty->isSized())          return true; @@ -1655,15 +1674,22 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,    // Handle some degenerate cases first    if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) { +    CmpInst::Predicate Predicate = CmpInst::Predicate(pred); +    bool isIntegerPredicate = ICmpInst::isIntPredicate(Predicate);      // For EQ and NE, we can always pick a value for the undef to make the      // predicate pass or fail, so we can return undef. -    // Also, if both operands are undef, we can return undef. -    if (ICmpInst::isEquality(ICmpInst::Predicate(pred)) || -        (isa<UndefValue>(C1) && isa<UndefValue>(C2))) +    // Also, if both operands are undef, we can return undef for int comparison. +    if (ICmpInst::isEquality(Predicate) || (isIntegerPredicate && C1 == C2))        return UndefValue::get(ResultTy); -    // Otherwise, pick the same value as the non-undef operand, and fold -    // it to true or false. -    return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(pred)); + +    // Otherwise, for integer compare, pick the same value as the non-undef +    // operand, and fold it to true or false. +    if (isIntegerPredicate) +      return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(pred)); + +    // Choosing NaN for the undef will always make unordered comparison succeed +    // and ordered comparison fails. +    return ConstantInt::get(ResultTy, CmpInst::isUnordered(Predicate));    }    // icmp eq/ne(null,GV) -> false/true @@ -1779,7 +1805,10 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,      return ConstantVector::get(ResElts);    } -  if (C1->getType()->isFloatingPointTy()) { +  if (C1->getType()->isFloatingPointTy() && +      // Only call evaluateFCmpRelation if we have a constant expr to avoid +      // infinite recursive loop +      (isa<ConstantExpr>(C1) || isa<ConstantExpr>(C2))) {      int Result = -1;  // -1 = unknown, 0 = known false, 1 = known true.      switch (evaluateFCmpRelation(C1, C2)) {      default: llvm_unreachable("Unknown relation!"); @@ -1999,7 +2028,7 @@ static bool isIndexInRangeOfSequentialType(const SequentialType *STy,  }  template<typename IndexTy> -static Constant *ConstantFoldGetElementPtrImpl(Constant *C, +static Constant *ConstantFoldGetElementPtrImpl(Type *PointeeTy, Constant *C,                                                 bool inBounds,                                                 ArrayRef<IndexTy> Idxs) {    if (Idxs.empty()) return C; @@ -2009,7 +2038,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,    if (isa<UndefValue>(C)) {      PointerType *Ptr = cast<PointerType>(C->getType()); -    Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs); +    Type *Ty = GetElementPtrInst::getIndexedType( +        cast<PointerType>(Ptr->getScalarType())->getElementType(), Idxs);      assert(Ty && "Invalid indices for GEP!");      return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace()));    } @@ -2023,7 +2053,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,        }      if (isNull) {        PointerType *Ptr = cast<PointerType>(C->getType()); -      Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs); +      Type *Ty = GetElementPtrInst::getIndexedType( +          cast<PointerType>(Ptr->getScalarType())->getElementType(), Idxs);        assert(Ty && "Invalid indices for GEP!");        return ConstantPointerNull::get(PointerType::get(Ty,                                                         Ptr->getAddressSpace())); @@ -2069,8 +2100,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,        if (PerformFold) {          SmallVector<Value*, 16> NewIndices;          NewIndices.reserve(Idxs.size() + CE->getNumOperands()); -        for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) -          NewIndices.push_back(CE->getOperand(i)); +        NewIndices.append(CE->op_begin() + 1, CE->op_end() - 1);          // Add the last index of the source with the first index of the new GEP.          // Make sure to handle the case when they are actually different types. @@ -2079,9 +2109,15 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,          if (!Idx0->isNullValue()) {            Type *IdxTy = Combined->getType();            if (IdxTy != Idx0->getType()) { -            Type *Int64Ty = Type::getInt64Ty(IdxTy->getContext()); -            Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Int64Ty); -            Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, Int64Ty); +            unsigned CommonExtendedWidth = +                std::max(IdxTy->getIntegerBitWidth(), +                         Idx0->getType()->getIntegerBitWidth()); +            CommonExtendedWidth = std::max(CommonExtendedWidth, 64U); + +            Type *CommonTy = +                Type::getIntNTy(IdxTy->getContext(), CommonExtendedWidth); +            Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, CommonTy); +            Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, CommonTy);              Combined = ConstantExpr::get(Instruction::Add, C1, C2);            } else {              Combined = @@ -2091,10 +2127,9 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,          NewIndices.push_back(Combined);          NewIndices.append(Idxs.begin() + 1, Idxs.end()); -        return -          ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices, -                                         inBounds && -                                           cast<GEPOperator>(CE)->isInBounds()); +        return ConstantExpr::getGetElementPtr( +            cast<GEPOperator>(CE)->getSourceElementType(), CE->getOperand(0), +            NewIndices, inBounds && cast<GEPOperator>(CE)->isInBounds());        }      } @@ -2119,8 +2154,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,          if (SrcArrayTy && DstArrayTy              && SrcArrayTy->getElementType() == DstArrayTy->getElementType()              && SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) -          return ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0), -                                                Idxs, inBounds); +          return ConstantExpr::getGetElementPtr( +              SrcArrayTy, (Constant *)CE->getOperand(0), Idxs, inBounds);        }      }    } @@ -2130,9 +2165,9 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,    // factored out into preceding dimensions.    bool Unknown = false;    SmallVector<Constant *, 8> NewIdxs; -  Type *Ty = C->getType(); -  Type *Prev = nullptr; -  for (unsigned i = 0, e = Idxs.size(); i != e; +  Type *Ty = PointeeTy; +  Type *Prev = C->getType(); +  for (unsigned i = 1, e = Idxs.size(); i != e;         Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {      if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {        if (isa<ArrayType>(Ty) || isa<VectorType>(Ty)) @@ -2154,14 +2189,20 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,              Constant *PrevIdx = cast<Constant>(Idxs[i-1]);              Constant *Div = ConstantExpr::getSDiv(CI, Factor); +            unsigned CommonExtendedWidth = +                std::max(PrevIdx->getType()->getIntegerBitWidth(), +                         Div->getType()->getIntegerBitWidth()); +            CommonExtendedWidth = std::max(CommonExtendedWidth, 64U); +              // Before adding, extend both operands to i64 to avoid              // overflow trouble. -            if (!PrevIdx->getType()->isIntegerTy(64)) -              PrevIdx = ConstantExpr::getSExt(PrevIdx, -                                           Type::getInt64Ty(Div->getContext())); -            if (!Div->getType()->isIntegerTy(64)) -              Div = ConstantExpr::getSExt(Div, -                                          Type::getInt64Ty(Div->getContext())); +            if (!PrevIdx->getType()->isIntegerTy(CommonExtendedWidth)) +              PrevIdx = ConstantExpr::getSExt( +                  PrevIdx, +                  Type::getIntNTy(Div->getContext(), CommonExtendedWidth)); +            if (!Div->getType()->isIntegerTy(CommonExtendedWidth)) +              Div = ConstantExpr::getSExt( +                  Div, Type::getIntNTy(Div->getContext(), CommonExtendedWidth));              NewIdxs[i-1] = ConstantExpr::getAdd(PrevIdx, Div);            } else { @@ -2180,7 +2221,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,    if (!NewIdxs.empty()) {      for (unsigned i = 0, e = Idxs.size(); i != e; ++i)        if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]); -    return ConstantExpr::getGetElementPtr(C, NewIdxs, inBounds); +    return ConstantExpr::getGetElementPtr(PointeeTy, C, NewIdxs, inBounds);    }    // If all indices are known integers and normalized, we can do a simple @@ -2188,7 +2229,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,    if (!Unknown && !inBounds)      if (auto *GV = dyn_cast<GlobalVariable>(C))        if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs)) -        return ConstantExpr::getInBoundsGetElementPtr(C, Idxs); +        return ConstantExpr::getInBoundsGetElementPtr(PointeeTy, C, Idxs);    return nullptr;  } @@ -2196,11 +2237,27 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,  Constant *llvm::ConstantFoldGetElementPtr(Constant *C,                                            bool inBounds,                                            ArrayRef<Constant *> Idxs) { -  return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs); +  return ConstantFoldGetElementPtrImpl( +      cast<PointerType>(C->getType()->getScalarType())->getElementType(), C, +      inBounds, Idxs);  }  Constant *llvm::ConstantFoldGetElementPtr(Constant *C,                                            bool inBounds,                                            ArrayRef<Value *> Idxs) { -  return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs); +  return ConstantFoldGetElementPtrImpl( +      cast<PointerType>(C->getType()->getScalarType())->getElementType(), C, +      inBounds, Idxs); +} + +Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C, +                                          bool inBounds, +                                          ArrayRef<Constant *> Idxs) { +  return ConstantFoldGetElementPtrImpl(Ty, C, inBounds, Idxs); +} + +Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C, +                                          bool inBounds, +                                          ArrayRef<Value *> Idxs) { +  return ConstantFoldGetElementPtrImpl(Ty, C, inBounds, Idxs);  } | 
