From e3b557809604d036af6e00c60f012c2025b59a5e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 11 Feb 2023 13:38:04 +0100 Subject: Vendor import of llvm-project main llvmorg-16-init-18548-gb0daacf58f41, the last commit before the upstream release/17.x branch was created. --- llvm/lib/IR/ConstantFold.cpp | 81 ++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 37 deletions(-) (limited to 'llvm/lib/IR/ConstantFold.cpp') diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 98adff107cec..f84fe79b21be 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -848,18 +848,19 @@ Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) { Type *Ty = IntegerType::get(VTy->getContext(), 32); // Fast path for splatted constants. - if (Constant *Splat = C->getSplatValue()) { - Constant *Elt = ConstantExpr::get(Opcode, Splat); - return ConstantVector::getSplat(VTy->getElementCount(), Elt); - } + if (Constant *Splat = C->getSplatValue()) + if (Constant *Elt = ConstantFoldUnaryInstruction(Opcode, Splat)) + return ConstantVector::getSplat(VTy->getElementCount(), Elt); // Fold each element and create a vector constant from those constants. SmallVector Result; for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { Constant *ExtractIdx = ConstantInt::get(Ty, i); Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx); - - Result.push_back(ConstantExpr::get(Opcode, Elt)); + Constant *Res = ConstantFoldUnaryInstruction(Opcode, Elt); + if (!Res) + return nullptr; + Result.push_back(Res); } return ConstantVector::get(Result); @@ -903,7 +904,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, // Handle undef ^ undef -> 0 special case. This is a common // idiom (misuse). return Constant::getNullValue(C1->getType()); - LLVM_FALLTHROUGH; + [[fallthrough]]; case Instruction::Add: case Instruction::Sub: return UndefValue::get(C1->getType()); @@ -979,7 +980,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, // -0.0 - undef --> undef (consistent with "fneg undef") if (match(C1, m_NegZeroFP()) && isa(C2)) return C2; - LLVM_FALLTHROUGH; + [[fallthrough]]; case Instruction::FAdd: case Instruction::FMul: case Instruction::FDiv: @@ -1072,7 +1073,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, } else if (isa(GV)) { // Without a datalayout we have to assume the worst case: that the // function pointer isn't aligned at all. - GVAlign = llvm::None; + GVAlign = std::nullopt; } else if (isa(GV)) { GVAlign = cast(GV)->getAlign(); } @@ -1513,7 +1514,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, if (const GlobalValue *GV = dyn_cast(CE1Op0)) if (const GlobalValue *GV2 = dyn_cast(V2)) return areGlobalsPotentiallyEqual(GV, GV2); - LLVM_FALLTHROUGH; + [[fallthrough]]; case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::ZExt: @@ -1578,6 +1579,25 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, return ICmpInst::BAD_ICMP_PREDICATE; } +static Constant *constantFoldCompareGlobalToNull(CmpInst::Predicate Predicate, + Constant *C1, Constant *C2) { + const GlobalValue *GV = dyn_cast(C2); + if (!GV || !C1->isNullValue()) + return nullptr; + + // Don't try to evaluate aliases. External weak GV can be null. + if (!isa(GV) && !GV->hasExternalWeakLinkage() && + !NullPointerIsDefined(nullptr /* F */, + GV->getType()->getAddressSpace())) { + if (Predicate == ICmpInst::ICMP_EQ) + return ConstantInt::getFalse(C1->getContext()); + else if (Predicate == ICmpInst::ICMP_NE) + return ConstantInt::getTrue(C1->getContext()); + } + + return nullptr; +} + Constant *llvm::ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, Constant *C1, Constant *C2) { Type *ResultTy; @@ -1617,31 +1637,14 @@ Constant *llvm::ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, } // icmp eq/ne(null,GV) -> false/true - if (C1->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(C2)) - // Don't try to evaluate aliases. External weak GV can be null. - if (!isa(GV) && !GV->hasExternalWeakLinkage() && - !NullPointerIsDefined(nullptr /* F */, - GV->getType()->getAddressSpace())) { - if (Predicate == ICmpInst::ICMP_EQ) - return ConstantInt::getFalse(C1->getContext()); - else if (Predicate == ICmpInst::ICMP_NE) - return ConstantInt::getTrue(C1->getContext()); - } + if (Constant *Folded = constantFoldCompareGlobalToNull(Predicate, C1, C2)) + return Folded; + // icmp eq/ne(GV,null) -> false/true - } else if (C2->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(C1)) { - // Don't try to evaluate aliases. External weak GV can be null. - if (!isa(GV) && !GV->hasExternalWeakLinkage() && - !NullPointerIsDefined(nullptr /* F */, - GV->getType()->getAddressSpace())) { - if (Predicate == ICmpInst::ICMP_EQ) - return ConstantInt::getFalse(C1->getContext()); - else if (Predicate == ICmpInst::ICMP_NE) - return ConstantInt::getTrue(C1->getContext()); - } - } + if (Constant *Folded = constantFoldCompareGlobalToNull(Predicate, C2, C1)) + return Folded; + if (C2->isNullValue()) { // The caller is expected to commute the operands if the constant expression // is C2. // C1 >= 0 --> true @@ -2019,9 +2022,9 @@ static Constant *foldGEPOfGEP(GEPOperator *GEP, Type *PointeeTy, bool InBounds, // The combined GEP normally inherits its index inrange attribute from // the inner GEP, but if the inner GEP's last index was adjusted by the // outer GEP, any inbounds attribute on that index is invalidated. - Optional IRIndex = GEP->getInRangeIndex(); + std::optional IRIndex = GEP->getInRangeIndex(); if (IRIndex && *IRIndex == GEP->getNumIndices() - 1) - IRIndex = None; + IRIndex = std::nullopt; return ConstantExpr::getGetElementPtr( GEP->getSourceElementType(), cast(GEP->getPointerOperand()), @@ -2030,12 +2033,12 @@ static Constant *foldGEPOfGEP(GEPOperator *GEP, Type *PointeeTy, bool InBounds, Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, bool InBounds, - Optional InRangeIndex, + std::optional InRangeIndex, ArrayRef Idxs) { if (Idxs.empty()) return C; Type *GEPTy = GetElementPtrInst::getGEPReturnType( - PointeeTy, C, makeArrayRef((Value *const *)Idxs.data(), Idxs.size())); + PointeeTy, C, ArrayRef((Value *const *)Idxs.data(), Idxs.size())); if (isa(C)) return PoisonValue::get(GEPTy); @@ -2050,6 +2053,10 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, if (!C->getType()->getScalarType()->isOpaquePointerTy() && Idxs.size() != 1) return false; + // Avoid losing inrange information. + if (InRangeIndex) + return false; + return all_of(Idxs, [](Value *Idx) { Constant *IdxC = cast(Idx); return IdxC->isNullValue() || isa(IdxC); -- cgit v1.2.3