summaryrefslogtreecommitdiff
path: root/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/ConstantFold.cpp')
-rw-r--r--lib/IR/ConstantFold.cpp79
1 files changed, 52 insertions, 27 deletions
diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp
index 59818a1425f1..90a8366d1696 100644
--- a/lib/IR/ConstantFold.cpp
+++ b/lib/IR/ConstantFold.cpp
@@ -71,7 +71,7 @@ static Constant *BitCastConstantVector(Constant *CV, VectorType *DstTy) {
/// This function determines which opcode to use to fold two constant cast
/// expressions together. It uses CastInst::isEliminableCastPair to determine
/// the opcode. Consequently its just a wrapper around that function.
-/// @brief Determine if it is valid to fold a cast of a cast
+/// Determine if it is valid to fold a cast of a cast
static unsigned
foldConstantCastPair(
unsigned opc, ///< opcode of the second cast constant expression
@@ -321,7 +321,7 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart,
if (ByteStart == 0 && ByteSize*8 == SrcBitSize)
return CE->getOperand(0);
- // If extracting something completely in the input, if if the input is a
+ // If extracting something completely in the input, if the input is a
// multiple of 8 bits, recurse.
if ((SrcBitSize&7) == 0 && (ByteStart+ByteSize)*8 <= SrcBitSize)
return ExtractConstantBytes(CE->getOperand(0), ByteStart, ByteSize);
@@ -545,7 +545,11 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
opc != Instruction::AddrSpaceCast &&
// Do not fold bitcast (gep) with inrange index, as this loses
// information.
- !cast<GEPOperator>(CE)->getInRangeIndex().hasValue()) {
+ !cast<GEPOperator>(CE)->getInRangeIndex().hasValue() &&
+ // Do not fold if the gep type is a vector, as bitcasting
+ // operand 0 of a vector gep will result in a bitcast between
+ // different sizes.
+ !CE->getType()->isVectorTy()) {
// If all of the indexes in the GEP are null values, there is no pointer
// adjustment going on. We might as well cast the source pointer.
bool isAllNull = true;
@@ -678,13 +682,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
const APInt &api = CI->getValue();
APFloat apf(DestTy->getFltSemantics(),
APInt::getNullValue(DestTy->getPrimitiveSizeInBits()));
- if (APFloat::opOverflow &
- apf.convertFromAPInt(api, opc==Instruction::SIToFP,
- APFloat::rmNearestTiesToEven)) {
- // Undefined behavior invoked - the destination type can't represent
- // the input constant.
- return UndefValue::get(DestTy);
- }
+ apf.convertFromAPInt(api, opc==Instruction::SIToFP,
+ APFloat::rmNearestTiesToEven);
return ConstantFP::get(V->getContext(), apf);
}
return nullptr;
@@ -1009,8 +1008,17 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
case Instruction::FMul:
case Instruction::FDiv:
case Instruction::FRem:
- // TODO: UNDEF handling for binary float instructions.
- return nullptr;
+ // [any flop] undef, undef -> undef
+ if (isa<UndefValue>(C1) && isa<UndefValue>(C2))
+ return C1;
+ // [any flop] C, undef -> NaN
+ // [any flop] undef, C -> NaN
+ // We could potentially specialize NaN/Inf constants vs. 'normal'
+ // constants (possibly differently depending on opcode and operand). This
+ // would allow returning undef sometimes. But it is always safe to fold to
+ // NaN because we can choose the undef operand as NaN, and any FP opcode
+ // with a NaN operand will propagate NaN.
+ return ConstantFP::getNaN(C1->getType());
case Instruction::BinaryOpsEnd:
llvm_unreachable("Invalid BinaryOp");
}
@@ -1219,9 +1227,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
Constant *RHS = ConstantExpr::getExtractElement(C2, ExtractIdx);
// If any element of a divisor vector is zero, the whole op is undef.
- if ((Opcode == Instruction::SDiv || Opcode == Instruction::UDiv ||
- Opcode == Instruction::SRem || Opcode == Instruction::URem) &&
- RHS->isNullValue())
+ if (Instruction::isIntDivRem(Opcode) && RHS->isNullValue())
return UndefValue::get(VTy);
Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
@@ -1494,7 +1500,12 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
assert(isa<ConstantPointerNull>(V2) && "Canonicalization guarantee!");
// GlobalVals can never be null unless they have external weak linkage.
// We don't try to evaluate aliases here.
- if (!GV->hasExternalWeakLinkage() && !isa<GlobalAlias>(GV))
+ // NOTE: We should not be doing this constant folding if null pointer
+ // is considered valid for the function. But currently there is no way to
+ // query it from the Constant type.
+ if (!GV->hasExternalWeakLinkage() && !isa<GlobalAlias>(GV) &&
+ !NullPointerIsDefined(nullptr /* F */,
+ GV->getType()->getAddressSpace()))
return ICmpInst::ICMP_NE;
}
} else if (const BlockAddress *BA = dyn_cast<BlockAddress>(V1)) {
@@ -1546,8 +1557,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
// If the cast is not actually changing bits, and the second operand is a
// null pointer, do the comparison with the pre-casted value.
- if (V2->isNullValue() &&
- (CE1->getType()->isPointerTy() || CE1->getType()->isIntegerTy())) {
+ if (V2->isNullValue() && CE1->getType()->isIntOrPtrTy()) {
if (CE1->getOpcode() == Instruction::ZExt) isSigned = false;
if (CE1->getOpcode() == Instruction::SExt) isSigned = true;
return evaluateICmpRelation(CE1Op0,
@@ -1724,7 +1734,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
if (C1->isNullValue()) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C2))
// Don't try to evaluate aliases. External weak GV can be null.
- if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) {
+ if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage() &&
+ !NullPointerIsDefined(nullptr /* F */,
+ GV->getType()->getAddressSpace())) {
if (pred == ICmpInst::ICMP_EQ)
return ConstantInt::getFalse(C1->getContext());
else if (pred == ICmpInst::ICMP_NE)
@@ -1734,7 +1746,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
} else if (C2->isNullValue()) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C1))
// Don't try to evaluate aliases. External weak GV can be null.
- if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) {
+ if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage() &&
+ !NullPointerIsDefined(nullptr /* F */,
+ GV->getType()->getAddressSpace())) {
if (pred == ICmpInst::ICMP_EQ)
return ConstantInt::getFalse(C1->getContext());
else if (pred == ICmpInst::ICMP_NE)
@@ -2018,8 +2032,16 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) {
// If the first index is one and all the rest are zero, it's in bounds,
// by the one-past-the-end rule.
- if (!cast<ConstantInt>(Idxs[0])->isOne())
- return false;
+ if (auto *CI = dyn_cast<ConstantInt>(Idxs[0])) {
+ if (!CI->isOne())
+ return false;
+ } else {
+ auto *CV = cast<ConstantDataVector>(Idxs[0]);
+ CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue());
+ if (!CI || !CI->isOne())
+ return false;
+ }
+
for (unsigned i = 1, e = Idxs.size(); i != e; ++i)
if (!cast<Constant>(Idxs[i])->isNullValue())
return false;
@@ -2049,15 +2071,18 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
ArrayRef<Value *> Idxs) {
if (Idxs.empty()) return C;
- if (isa<UndefValue>(C)) {
- Type *GEPTy = GetElementPtrInst::getGEPReturnType(
- C, makeArrayRef((Value * const *)Idxs.data(), Idxs.size()));
+ Type *GEPTy = GetElementPtrInst::getGEPReturnType(
+ C, makeArrayRef((Value *const *)Idxs.data(), Idxs.size()));
+
+ if (isa<UndefValue>(C))
return UndefValue::get(GEPTy);
- }
Constant *Idx0 = cast<Constant>(Idxs[0]);
if (Idxs.size() == 1 && (Idx0->isNullValue() || isa<UndefValue>(Idx0)))
- return C;
+ return GEPTy->isVectorTy() && !C->getType()->isVectorTy()
+ ? ConstantVector::getSplat(
+ cast<VectorType>(GEPTy)->getNumElements(), C)
+ : C;
if (C->isNullValue()) {
bool isNull = true;