diff options
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 300 |
1 files changed, 174 insertions, 126 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 6fd205c654a8..6c75085a6678 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -43,15 +43,9 @@ bool Constant::isNegativeZeroValue() const { return CFP->isZero() && CFP->isNegative(); // Equivalent for a vector of -0.0's. - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) - if (CV->getElementType()->isFloatingPointTy() && CV->isSplat()) - if (CV->getElementAsAPFloat(0).isNegZero()) - return true; - - if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue())) - if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative()) - return true; + if (getType()->isVectorTy()) + if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue())) + return SplatCFP->isNegativeZeroValue(); // We've already handled true FP case; any other FP vectors can't represent -0.0. if (getType()->isFPOrFPVectorTy()) @@ -68,16 +62,10 @@ bool Constant::isZeroValue() const { if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) return CFP->isZero(); - // Equivalent for a vector of -0.0's. - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) - if (CV->getElementType()->isFloatingPointTy() && CV->isSplat()) - if (CV->getElementAsAPFloat(0).isZero()) - return true; - - if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue())) - if (SplatCFP && SplatCFP->isZero()) - return true; + // Check for constant splat vectors of 1 values. + if (getType()->isVectorTy()) + if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue())) + return SplatCFP->isZero(); // Otherwise, just use +0.0. return isNullValue(); @@ -90,7 +78,9 @@ bool Constant::isNullValue() const { // +0.0 is null. if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) - return CFP->isZero() && !CFP->isNegative(); + // ppc_fp128 determine isZero using high order double only + // Should check the bitwise value to make sure all bits are zero. + return CFP->isExactlyValue(+0.0); // constant zero is zero for aggregates, cpnull is null for pointers, none for // tokens. @@ -107,19 +97,10 @@ bool Constant::isAllOnesValue() const { if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) return CFP->getValueAPF().bitcastToAPInt().isAllOnesValue(); - // Check for constant vectors which are splats of -1 values. - if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - if (Constant *Splat = CV->getSplatValue()) - return Splat->isAllOnesValue(); - - // Check for constant vectors which are splats of -1 values. - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) { - if (CV->isSplat()) { - if (CV->getElementType()->isFloatingPointTy()) - return CV->getElementAsAPFloat(0).bitcastToAPInt().isAllOnesValue(); - return CV->getElementAsAPInt(0).isAllOnesValue(); - } - } + // Check for constant splat vectors of 1 values. + if (getType()->isVectorTy()) + if (const auto *SplatVal = getSplatValue()) + return SplatVal->isAllOnesValue(); return false; } @@ -133,19 +114,10 @@ bool Constant::isOneValue() const { if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) return CFP->getValueAPF().bitcastToAPInt().isOneValue(); - // Check for constant vectors which are splats of 1 values. - if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - if (Constant *Splat = CV->getSplatValue()) - return Splat->isOneValue(); - - // Check for constant vectors which are splats of 1 values. - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) { - if (CV->isSplat()) { - if (CV->getElementType()->isFloatingPointTy()) - return CV->getElementAsAPFloat(0).bitcastToAPInt().isOneValue(); - return CV->getElementAsAPInt(0).isOneValue(); - } - } + // Check for constant splat vectors of 1 values. + if (getType()->isVectorTy()) + if (const auto *SplatVal = getSplatValue()) + return SplatVal->isOneValue(); return false; } @@ -160,16 +132,20 @@ bool Constant::isNotOneValue() const { return !CFP->getValueAPF().bitcastToAPInt().isOneValue(); // Check that vectors don't contain 1 - if (auto *VTy = dyn_cast<VectorType>(this->getType())) { - unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements(); - for (unsigned i = 0; i != NumElts; ++i) { - Constant *Elt = this->getAggregateElement(i); + if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { + for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) { + Constant *Elt = getAggregateElement(I); if (!Elt || !Elt->isNotOneValue()) return false; } return true; } + // Check for splats that don't contain 1 + if (getType()->isVectorTy()) + if (const auto *SplatVal = getSplatValue()) + return SplatVal->isNotOneValue(); + // It *may* contain 1, we can't tell. return false; } @@ -183,19 +159,10 @@ bool Constant::isMinSignedValue() const { if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) return CFP->getValueAPF().bitcastToAPInt().isMinSignedValue(); - // Check for constant vectors which are splats of INT_MIN values. - if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - if (Constant *Splat = CV->getSplatValue()) - return Splat->isMinSignedValue(); - - // Check for constant vectors which are splats of INT_MIN values. - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) { - if (CV->isSplat()) { - if (CV->getElementType()->isFloatingPointTy()) - return CV->getElementAsAPFloat(0).bitcastToAPInt().isMinSignedValue(); - return CV->getElementAsAPInt(0).isMinSignedValue(); - } - } + // Check for splats of INT_MIN values. + if (getType()->isVectorTy()) + if (const auto *SplatVal = getSplatValue()) + return SplatVal->isMinSignedValue(); return false; } @@ -210,16 +177,20 @@ bool Constant::isNotMinSignedValue() const { return !CFP->getValueAPF().bitcastToAPInt().isMinSignedValue(); // Check that vectors don't contain INT_MIN - if (auto *VTy = dyn_cast<VectorType>(this->getType())) { - unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements(); - for (unsigned i = 0; i != NumElts; ++i) { - Constant *Elt = this->getAggregateElement(i); + if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { + for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) { + Constant *Elt = getAggregateElement(I); if (!Elt || !Elt->isNotMinSignedValue()) return false; } return true; } + // Check for splats that aren't INT_MIN + if (getType()->isVectorTy()) + if (const auto *SplatVal = getSplatValue()) + return SplatVal->isNotMinSignedValue(); + // It *may* contain INT_MIN, we can't tell. return false; } @@ -227,57 +198,85 @@ bool Constant::isNotMinSignedValue() const { bool Constant::isFiniteNonZeroFP() const { if (auto *CFP = dyn_cast<ConstantFP>(this)) return CFP->getValueAPF().isFiniteNonZero(); - auto *VTy = dyn_cast<FixedVectorType>(getType()); - if (!VTy) - return false; - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i)); - if (!CFP || !CFP->getValueAPF().isFiniteNonZero()) - return false; + + if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { + for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) { + auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I)); + if (!CFP || !CFP->getValueAPF().isFiniteNonZero()) + return false; + } + return true; } - return true; + + if (getType()->isVectorTy()) + if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue())) + return SplatCFP->isFiniteNonZeroFP(); + + // It *may* contain finite non-zero, we can't tell. + return false; } bool Constant::isNormalFP() const { if (auto *CFP = dyn_cast<ConstantFP>(this)) return CFP->getValueAPF().isNormal(); - auto *VTy = dyn_cast<FixedVectorType>(getType()); - if (!VTy) - return false; - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i)); - if (!CFP || !CFP->getValueAPF().isNormal()) - return false; + + if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { + for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) { + auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I)); + if (!CFP || !CFP->getValueAPF().isNormal()) + return false; + } + return true; } - return true; + + if (getType()->isVectorTy()) + if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue())) + return SplatCFP->isNormalFP(); + + // It *may* contain a normal fp value, we can't tell. + return false; } bool Constant::hasExactInverseFP() const { if (auto *CFP = dyn_cast<ConstantFP>(this)) return CFP->getValueAPF().getExactInverse(nullptr); - auto *VTy = dyn_cast<FixedVectorType>(getType()); - if (!VTy) - return false; - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i)); - if (!CFP || !CFP->getValueAPF().getExactInverse(nullptr)) - return false; + + if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { + for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) { + auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I)); + if (!CFP || !CFP->getValueAPF().getExactInverse(nullptr)) + return false; + } + return true; } - return true; + + if (getType()->isVectorTy()) + if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue())) + return SplatCFP->hasExactInverseFP(); + + // It *may* have an exact inverse fp value, we can't tell. + return false; } bool Constant::isNaN() const { if (auto *CFP = dyn_cast<ConstantFP>(this)) return CFP->isNaN(); - auto *VTy = dyn_cast<FixedVectorType>(getType()); - if (!VTy) - return false; - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i)); - if (!CFP || !CFP->isNaN()) - return false; + + if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { + for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) { + auto *CFP = dyn_cast_or_null<ConstantFP>(getAggregateElement(I)); + if (!CFP || !CFP->isNaN()) + return false; + } + return true; } - return true; + + if (getType()->isVectorTy()) + if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue())) + return SplatCFP->isNaN(); + + // It *may* be NaN, we can't tell. + return false; } bool Constant::isElementWiseEqual(Value *Y) const { @@ -419,16 +418,21 @@ Constant *Constant::getAllOnesValue(Type *Ty) { } Constant *Constant::getAggregateElement(unsigned Elt) const { + assert((getType()->isAggregateType() || getType()->isVectorTy()) && + "Must be an aggregate/vector constant"); + if (const auto *CC = dyn_cast<ConstantAggregate>(this)) return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr; + if (const auto *CAZ = dyn_cast<ConstantAggregateZero>(this)) + return Elt < CAZ->getElementCount().getKnownMinValue() + ? CAZ->getElementValue(Elt) + : nullptr; + // FIXME: getNumElements() will fail for non-fixed vector types. if (isa<ScalableVectorType>(getType())) return nullptr; - if (const auto *CAZ = dyn_cast<ConstantAggregateZero>(this)) - return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr; - if (const auto *PV = dyn_cast<PoisonValue>(this)) return Elt < PV->getNumElements() ? PV->getElementValue(Elt) : nullptr; @@ -438,6 +442,7 @@ Constant *Constant::getAggregateElement(unsigned Elt) const { if (const auto *CDS = dyn_cast<ConstantDataSequential>(this)) return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : nullptr; + return nullptr; } @@ -652,12 +657,20 @@ bool Constant::isConstantUsed() const { return false; } +bool Constant::needsDynamicRelocation() const { + return getRelocationInfo() == GlobalRelocation; +} + bool Constant::needsRelocation() const { + return getRelocationInfo() != NoRelocation; +} + +Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { if (isa<GlobalValue>(this)) - return true; // Global reference. + return GlobalRelocation; // Global reference. if (const BlockAddress *BA = dyn_cast<BlockAddress>(this)) - return BA->getFunction()->needsRelocation(); + return BA->getFunction()->getRelocationInfo(); if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) { if (CE->getOpcode() == Instruction::Sub) { @@ -675,7 +688,7 @@ bool Constant::needsRelocation() const { if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) && cast<BlockAddress>(LHSOp0)->getFunction() == cast<BlockAddress>(RHSOp0)->getFunction()) - return false; + return NoRelocation; // Relative pointers do not need to be dynamically relocated. if (auto *RHSGV = @@ -683,19 +696,20 @@ bool Constant::needsRelocation() const { auto *LHS = LHSOp0->stripInBoundsConstantOffsets(); if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) { if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal()) - return false; + return LocalRelocation; } else if (isa<DSOLocalEquivalent>(LHS)) { if (RHSGV->isDSOLocal()) - return false; + return LocalRelocation; } } } } } - bool Result = false; + PossibleRelocationsTy Result = NoRelocation; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - Result |= cast<Constant>(getOperand(i))->needsRelocation(); + Result = + std::max(cast<Constant>(getOperand(i))->getRelocationInfo(), Result); return Result; } @@ -712,6 +726,12 @@ static bool removeDeadUsersOfConstant(const Constant *C) { return false; // Constant wasn't dead } + // If C is only used by metadata, it should not be preserved but should have + // its uses replaced. + if (C->isUsedByMetadata()) { + const_cast<Constant *>(C)->replaceAllUsesWith( + UndefValue::get(C->getType())); + } const_cast<Constant*>(C)->destroyConstant(); return true; } @@ -803,6 +823,18 @@ Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) { return C; } +bool Constant::isManifestConstant() const { + if (isa<ConstantData>(this)) + return true; + if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) { + for (const Value *Op : operand_values()) + if (!cast<Constant>(Op)->isManifestConstant()) + return false; + return true; + } + return false; +} + //===----------------------------------------------------------------------===// // ConstantInt //===----------------------------------------------------------------------===// @@ -1070,13 +1102,13 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const { return getStructElement(Idx); } -unsigned ConstantAggregateZero::getNumElements() const { +ElementCount ConstantAggregateZero::getElementCount() const { Type *Ty = getType(); if (auto *AT = dyn_cast<ArrayType>(Ty)) - return AT->getNumElements(); + return ElementCount::getFixed(AT->getNumElements()); if (auto *VT = dyn_cast<VectorType>(Ty)) - return cast<FixedVectorType>(VT)->getNumElements(); - return Ty->getStructNumElements(); + return VT->getElementCount(); + return ElementCount::getFixed(Ty->getStructNumElements()); } //===----------------------------------------------------------------------===// @@ -1247,6 +1279,9 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) { // all undef, return an UndefValue, if "all simple", then return a // ConstantDataArray. Constant *C = V[0]; + if (isa<PoisonValue>(C) && rangeOnlyContains(V.begin(), V.end(), C)) + return PoisonValue::get(Ty); + if (isa<UndefValue>(C) && rangeOnlyContains(V.begin(), V.end(), C)) return UndefValue::get(Ty); @@ -1295,21 +1330,28 @@ Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) { // Create a ConstantAggregateZero value if all elements are zeros. bool isZero = true; bool isUndef = false; + bool isPoison = false; if (!V.empty()) { isUndef = isa<UndefValue>(V[0]); + isPoison = isa<PoisonValue>(V[0]); isZero = V[0]->isNullValue(); + // PoisonValue inherits UndefValue, so its check is not necessary. if (isUndef || isZero) { for (unsigned i = 0, e = V.size(); i != e; ++i) { if (!V[i]->isNullValue()) isZero = false; - if (!isa<UndefValue>(V[i])) + if (!isa<PoisonValue>(V[i])) + isPoison = false; + if (isa<PoisonValue>(V[i]) || !isa<UndefValue>(V[i])) isUndef = false; } } } if (isZero) return ConstantAggregateZero::get(ST); + if (isPoison) + return PoisonValue::get(ST); if (isUndef) return UndefValue::get(ST); @@ -1788,8 +1830,8 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { } BlockAddress::BlockAddress(Function *F, BasicBlock *BB) -: Constant(Type::getInt8PtrTy(F->getContext()), Value::BlockAddressVal, - &Op<0>(), 2) { + : Constant(Type::getInt8PtrTy(F->getContext(), F->getAddressSpace()), + Value::BlockAddressVal, &Op<0>(), 2) { setOperand(0, F); setOperand(1, BB); BB->AdjustBlockAddressRefCount(1); @@ -1899,6 +1941,12 @@ Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) { getContext().pImpl->DSOLocalEquivalents.erase(getGlobalValue()); NewEquiv = this; setOperand(0, Func); + + if (Func->getType() != getType()) { + // It is ok to mutate the type here because this constant should always + // reflect the type of the function it's holding. + mutateType(Func->getType()); + } return nullptr; } @@ -2191,9 +2239,9 @@ Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy, // bitcasting the pointer type and then converting the address space. PointerType *SrcScalarTy = cast<PointerType>(C->getType()->getScalarType()); PointerType *DstScalarTy = cast<PointerType>(DstTy->getScalarType()); - Type *DstElemTy = DstScalarTy->getElementType(); - if (SrcScalarTy->getElementType() != DstElemTy) { - Type *MidTy = PointerType::get(DstElemTy, SrcScalarTy->getAddressSpace()); + if (!SrcScalarTy->hasSameElementTypeAs(DstScalarTy)) { + Type *MidTy = PointerType::getWithSamePointeeType( + DstScalarTy, SrcScalarTy->getAddressSpace()); if (VectorType *VT = dyn_cast<VectorType>(DstTy)) { // Handle vectors of pointers. MidTy = FixedVectorType::get(MidTy, @@ -2378,11 +2426,9 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, ArrayRef<Value *> Idxs, bool InBounds, Optional<unsigned> InRangeIndex, Type *OnlyIfReducedTy) { - if (!Ty) - Ty = cast<PointerType>(C->getType()->getScalarType())->getElementType(); - else - assert(Ty == - cast<PointerType>(C->getType()->getScalarType())->getElementType()); + PointerType *OrigPtrTy = cast<PointerType>(C->getType()->getScalarType()); + assert(Ty && "Must specify element type"); + assert(OrigPtrTy->isOpaqueOrPointeeTypeMatches(Ty)); if (Constant *FC = ConstantFoldGetElementPtr(Ty, C, InBounds, InRangeIndex, Idxs)) @@ -2391,8 +2437,10 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, // Get the result type of the getelementptr! Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs); assert(DestTy && "GEP indices invalid!"); - unsigned AS = C->getType()->getPointerAddressSpace(); - Type *ReqTy = DestTy->getPointerTo(AS); + unsigned AS = OrigPtrTy->getAddressSpace(); + Type *ReqTy = OrigPtrTy->isOpaque() + ? PointerType::get(OrigPtrTy->getContext(), AS) + : DestTy->getPointerTo(AS); auto EltCount = ElementCount::getFixed(0); if (VectorType *VecTy = dyn_cast<VectorType>(C->getType())) |