diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/IR/ConstantFold.cpp | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) |
Notes
Diffstat (limited to 'lib/IR/ConstantFold.cpp')
-rw-r--r-- | lib/IR/ConstantFold.cpp | 79 |
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; |