diff options
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
| -rw-r--r-- | llvm/lib/IR/Constants.cpp | 132 |
1 files changed, 53 insertions, 79 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index b862a159127f..0bf5e09d6647 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -11,12 +11,12 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/Constants.h" -#include "ConstantFold.h" #include "LLVMContextImpl.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/ConstantFold.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GetElementPtrTypeIterator.h" @@ -27,7 +27,6 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Operator.h" #include "llvm/IR/PatternMatch.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -353,26 +352,14 @@ Constant *Constant::getNullValue(Type *Ty) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); case Type::HalfTyID: - return ConstantFP::get(Ty->getContext(), - APFloat::getZero(APFloat::IEEEhalf())); case Type::BFloatTyID: - return ConstantFP::get(Ty->getContext(), - APFloat::getZero(APFloat::BFloat())); case Type::FloatTyID: - return ConstantFP::get(Ty->getContext(), - APFloat::getZero(APFloat::IEEEsingle())); case Type::DoubleTyID: - return ConstantFP::get(Ty->getContext(), - APFloat::getZero(APFloat::IEEEdouble())); case Type::X86_FP80TyID: - return ConstantFP::get(Ty->getContext(), - APFloat::getZero(APFloat::x87DoubleExtended())); case Type::FP128TyID: - return ConstantFP::get(Ty->getContext(), - APFloat::getZero(APFloat::IEEEquad())); case Type::PPC_FP128TyID: - return ConstantFP::get(Ty->getContext(), APFloat(APFloat::PPCDoubleDouble(), - APInt::getZero(128))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(Ty->getFltSemantics())); case Type::PointerTyID: return ConstantPointerNull::get(cast<PointerType>(Ty)); case Type::StructTyID: @@ -560,8 +547,6 @@ void llvm::deleteConstant(Constant *C) { delete static_cast<InsertElementConstantExpr *>(C); else if (isa<ShuffleVectorConstantExpr>(C)) delete static_cast<ShuffleVectorConstantExpr *>(C); - else if (isa<ExtractValueConstantExpr>(C)) - delete static_cast<ExtractValueConstantExpr *>(C); else if (isa<InsertValueConstantExpr>(C)) delete static_cast<InsertValueConstantExpr *>(C); else if (isa<GetElementPtrConstantExpr>(C)) @@ -577,38 +562,47 @@ void llvm::deleteConstant(Constant *C) { } static bool canTrapImpl(const Constant *C, - SmallPtrSetImpl<const ConstantExpr *> &NonTrappingOps) { - assert(C->getType()->isFirstClassType() && "Cannot evaluate aggregate vals!"); - // The only thing that could possibly trap are constant exprs. + SmallPtrSetImpl<const Constant *> &NonTrappingOps) { + assert(C->getType()->isFirstClassType() && + "Cannot evaluate non-first-class types!"); + // ConstantExpr or ConstantAggregate trap if any operands can trap. + if (isa<ConstantExpr>(C) || isa<ConstantAggregate>(C)) { + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + const Constant *Op = cast<Constant>(C->getOperand(i)); + if (isa<ConstantExpr>(Op) || isa<ConstantAggregate>(Op)) { + if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps)) + return true; + } + } + } + + // The only leafs that can trap are constant expressions. const ConstantExpr *CE = dyn_cast<ConstantExpr>(C); if (!CE) return false; - // ConstantExpr traps if any operands can trap. - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - if (ConstantExpr *Op = dyn_cast<ConstantExpr>(CE->getOperand(i))) { - if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps)) - return true; - } - } - // Otherwise, only specific operations can trap. switch (CE->getOpcode()) { default: return false; - case Instruction::UDiv: case Instruction::SDiv: - case Instruction::URem: case Instruction::SRem: - // Div and rem can trap if the RHS is not known to be non-zero. - if (!isa<ConstantInt>(CE->getOperand(1)) ||CE->getOperand(1)->isNullValue()) + // Signed div/rem can trap for SignedMin / -1. + if (!CE->getOperand(0)->isNotMinSignedValue() && + (!isa<ConstantInt>(CE->getOperand(1)) || + CE->getOperand(1)->isAllOnesValue())) return true; - return false; + LLVM_FALLTHROUGH; + case Instruction::UDiv: + case Instruction::URem: + // Div and rem can trap if the RHS is not known to be non-zero. + return !isa<ConstantInt>(CE->getOperand(1)) || + CE->getOperand(1)->isNullValue(); } } bool Constant::canTrap() const { - SmallPtrSet<const ConstantExpr *, 4> NonTrappingOps; + SmallPtrSet<const Constant *, 4> NonTrappingOps; return canTrapImpl(this, NonTrappingOps); } @@ -742,9 +736,13 @@ static bool constantIsDead(const Constant *C, bool RemoveDeadUsers) { ++I; } - if (RemoveDeadUsers) + if (RemoveDeadUsers) { + // If C is only used by metadata, it should not be preserved but should + // have its uses replaced. + ReplaceableMetadataImpl::SalvageDebugInfo(*C); const_cast<Constant *>(C)->destroyConstant(); - + } + return true; } @@ -1046,9 +1044,9 @@ Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) { return C; } -Constant *ConstantFP::getNegativeZero(Type *Ty) { +Constant *ConstantFP::getZero(Type *Ty, bool Negative) { const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics(); - APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true); + APFloat NegZero = APFloat::getZero(Semantics, Negative); Constant *C = get(Ty->getContext(), NegZero); if (VectorType *VTy = dyn_cast<VectorType>(Ty)) @@ -1057,7 +1055,6 @@ Constant *ConstantFP::getNegativeZero(Type *Ty) { return C; } - Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { if (Ty->isFPOrFPVectorTy()) return getNegativeZero(Ty); @@ -1492,15 +1489,10 @@ bool ConstantExpr::isCompare() const { } bool ConstantExpr::hasIndices() const { - return getOpcode() == Instruction::ExtractValue || - getOpcode() == Instruction::InsertValue; + return getOpcode() == Instruction::InsertValue; } ArrayRef<unsigned> ConstantExpr::getIndices() const { - if (const ExtractValueConstantExpr *EVCE = - dyn_cast<ExtractValueConstantExpr>(this)) - return EVCE->Indices; - return cast<InsertValueConstantExpr>(this)->Indices; } @@ -1550,8 +1542,6 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty, case Instruction::InsertValue: return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices(), OnlyIfReducedTy); - case Instruction::ExtractValue: - return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy); case Instruction::FNeg: return ConstantExpr::getFNeg(Ops[0]); case Instruction::ShuffleVector: @@ -2065,6 +2055,17 @@ Constant *ConstantExpr::getTruncOrBitCast(Constant *C, Type *Ty) { return getTrunc(C, Ty); } +Constant *ConstantExpr::getSExtOrTrunc(Constant *C, Type *Ty) { + assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && + "Can only sign extend/truncate integers!"); + Type *CTy = C->getType(); + if (CTy->getScalarSizeInBits() < Ty->getScalarSizeInBits()) + return getSExt(C, Ty); + if (CTy->getScalarSizeInBits() > Ty->getScalarSizeInBits()) + return getTrunc(C, Ty); + return C; +} + Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) { assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && @@ -2233,8 +2234,8 @@ Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy, "PtrToInt destination must be integer or integer vector"); assert(isa<VectorType>(C->getType()) == isa<VectorType>(DstTy)); if (isa<VectorType>(C->getType())) - assert(cast<FixedVectorType>(C->getType())->getNumElements() == - cast<FixedVectorType>(DstTy)->getNumElements() && + assert(cast<VectorType>(C->getType())->getElementCount() == + cast<VectorType>(DstTy)->getElementCount() && "Invalid cast between a different number of vector elements"); return getFoldedCast(Instruction::PtrToInt, C, DstTy, OnlyIfReduced); } @@ -2667,30 +2668,6 @@ Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs, - Type *OnlyIfReducedTy) { - assert(Agg->getType()->isFirstClassType() && - "Tried to create extractelement operation on non-first-class type!"); - - Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs); - (void)ReqTy; - assert(ReqTy && "extractvalue indices invalid!"); - - assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant extractvalue expression"); - if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs)) - return FC; - - if (OnlyIfReducedTy == ReqTy) - return nullptr; - - Constant *ArgVec[] = { Agg }; - const ConstantExprKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs); - - LLVMContextImpl *pImpl = Agg->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { assert(C->getType()->isIntOrIntVectorTy() && "Cannot NEG a nonintegral value!"); @@ -2833,7 +2810,7 @@ Constant *ConstantExpr::getExactLogBase2(Constant *C) { } Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty, - bool AllowRHSConstant) { + bool AllowRHSConstant, bool NSZ) { assert(Instruction::isBinaryOp(Opcode) && "Only binops allowed"); // Commutative opcodes: it does not matter if AllowRHSConstant is set. @@ -2848,8 +2825,7 @@ Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty, case Instruction::And: // X & -1 = X return Constant::getAllOnesValue(Ty); case Instruction::FAdd: // X + -0.0 = X - // TODO: If the fadd has 'nsz', should we return +0.0? - return ConstantFP::getNegativeZero(Ty); + return ConstantFP::getZero(Ty, !NSZ); case Instruction::FMul: // X * 1.0 = X return ConstantFP::get(Ty, 1.0); default: @@ -3544,8 +3520,6 @@ Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { case Instruction::InsertValue: return InsertValueInst::Create(Ops[0], Ops[1], getIndices(), "", InsertBefore); - case Instruction::ExtractValue: - return ExtractValueInst::Create(Ops[0], getIndices(), "", InsertBefore); case Instruction::ShuffleVector: return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "", InsertBefore); |
