aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/Constants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Constants.cpp')
-rw-r--r--lib/IR/Constants.cpp79
1 files changed, 43 insertions, 36 deletions
diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp
index 027946efd1..2d67c0c943 100644
--- a/lib/IR/Constants.cpp
+++ b/lib/IR/Constants.cpp
@@ -47,6 +47,16 @@ bool Constant::isNegativeZeroValue() const {
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero() && CFP->isNegative();
+ // Equivalent for a vector of -0.0's.
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
+ return true;
+
+ // We've already handled true FP case; any other FP vectors can't represent -0.0.
+ if (getType()->isFPOrFPVectorTy())
+ return false;
+
// Otherwise, just use +0.0.
return isNullValue();
}
@@ -227,18 +237,21 @@ void Constant::destroyConstantImpl() {
delete this;
}
-/// canTrap - Return true if evaluation of this constant could trap. This is
-/// true for things like constant expressions that could divide by zero.
-bool Constant::canTrap() const {
- assert(getType()->isFirstClassType() && "Cannot evaluate aggregate vals!");
+static bool canTrapImpl(const Constant *C,
+ SmallPtrSet<const ConstantExpr *, 4> &NonTrappingOps) {
+ assert(C->getType()->isFirstClassType() && "Cannot evaluate aggregate vals!");
// The only thing that could possibly trap are constant exprs.
- const ConstantExpr *CE = dyn_cast<ConstantExpr>(this);
- if (!CE) return false;
+ const ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
+ if (!CE)
+ return false;
// ConstantExpr traps if any operands can trap.
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (CE->getOperand(i)->canTrap())
- return true;
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+ if (ConstantExpr *Op = dyn_cast<ConstantExpr>(CE->getOperand(i))) {
+ if (NonTrappingOps.insert(Op) && canTrapImpl(Op, NonTrappingOps))
+ return true;
+ }
+ }
// Otherwise, only specific operations can trap.
switch (CE->getOpcode()) {
@@ -257,6 +270,13 @@ bool Constant::canTrap() const {
}
}
+/// canTrap - Return true if evaluation of this constant could trap. This is
+/// true for things like constant expressions that could divide by zero.
+bool Constant::canTrap() const {
+ SmallPtrSet<const ConstantExpr *, 4> NonTrappingOps;
+ return canTrapImpl(this, NonTrappingOps);
+}
+
/// isThreadDependent - Return true if the value can vary between threads.
bool Constant::isThreadDependent() const {
SmallPtrSet<const Constant*, 64> Visited;
@@ -1416,9 +1436,8 @@ static inline Constant *getFoldedCast(
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
- // Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> argVec(1, C);
- ExprMapKeyType Key(opc, argVec);
+ // Look up the constant in the table first to ensure uniqueness.
+ ExprMapKeyType Key(opc, C);
return pImpl->ExprConstants.getOrCreate(Ty, Key);
}
@@ -1715,9 +1734,8 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
return FC; // Fold a few common cases.
- std::vector<Constant*> argVec(1, C1);
- argVec.push_back(C2);
- ExprMapKeyType Key(Opcode, argVec, 0, Flags);
+ Constant *ArgVec[] = { C1, C2 };
+ ExprMapKeyType Key(Opcode, ArgVec, 0, Flags);
LLVMContextImpl *pImpl = C1->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
@@ -1793,10 +1811,8 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) {
if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
return SC; // Fold common cases
- std::vector<Constant*> argVec(3, C);
- argVec[1] = V1;
- argVec[2] = V2;
- ExprMapKeyType Key(Instruction::Select, argVec);
+ Constant *ArgVec[] = { C, V1, V2 };
+ ExprMapKeyType Key(Instruction::Select, ArgVec);
LLVMContextImpl *pImpl = C->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
@@ -1848,9 +1864,7 @@ ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) {
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> ArgVec;
- ArgVec.push_back(LHS);
- ArgVec.push_back(RHS);
+ Constant *ArgVec[] = { LHS, RHS };
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
@@ -1871,9 +1885,7 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) {
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> ArgVec;
- ArgVec.push_back(LHS);
- ArgVec.push_back(RHS);
+ Constant *ArgVec[] = { LHS, RHS };
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
@@ -1895,9 +1907,8 @@ Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
return FC; // Fold a few common cases.
// Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> ArgVec(1, Val);
- ArgVec.push_back(Idx);
- const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
+ Constant *ArgVec[] = { Val, Idx };
+ const ExprMapKeyType Key(Instruction::ExtractElement, ArgVec);
LLVMContextImpl *pImpl = Val->getContext().pImpl;
Type *ReqTy = Val->getType()->getVectorElementType();
@@ -1916,10 +1927,8 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
return FC; // Fold a few common cases.
// Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> ArgVec(1, Val);
- ArgVec.push_back(Elt);
- ArgVec.push_back(Idx);
- const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
+ Constant *ArgVec[] = { Val, Elt, Idx };
+ const ExprMapKeyType Key(Instruction::InsertElement, ArgVec);
LLVMContextImpl *pImpl = Val->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(Val->getType(), Key);
@@ -1938,10 +1947,8 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
Type *ShufTy = VectorType::get(EltTy, NElts);
// Look up the constant in the table first to ensure uniqueness
- std::vector<Constant*> ArgVec(1, V1);
- ArgVec.push_back(V2);
- ArgVec.push_back(Mask);
- const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
+ Constant *ArgVec[] = { V1, V2, Mask };
+ const ExprMapKeyType Key(Instruction::ShuffleVector, ArgVec);
LLVMContextImpl *pImpl = ShufTy->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ShufTy, Key);