diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/IR/ConstantFold.cpp | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
| -rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 81 |
1 files changed, 44 insertions, 37 deletions
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<Constant *, 16> 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<UndefValue>(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<Function>(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<GlobalVariable>(GV)) { GVAlign = cast<GlobalVariable>(GV)->getAlign(); } @@ -1513,7 +1514,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, if (const GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0)) if (const GlobalValue *GV2 = dyn_cast<GlobalValue>(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<GlobalValue>(C2); + if (!GV || !C1->isNullValue()) + return nullptr; + + // Don't try to evaluate aliases. External weak GV can be null. + if (!isa<GlobalAlias>(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<GlobalValue>(C2)) - // Don't try to evaluate aliases. External weak GV can be null. - if (!isa<GlobalAlias>(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<GlobalValue>(C1)) { - // Don't try to evaluate aliases. External weak GV can be null. - if (!isa<GlobalAlias>(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<unsigned> IRIndex = GEP->getInRangeIndex(); + std::optional<unsigned> IRIndex = GEP->getInRangeIndex(); if (IRIndex && *IRIndex == GEP->getNumIndices() - 1) - IRIndex = None; + IRIndex = std::nullopt; return ConstantExpr::getGetElementPtr( GEP->getSourceElementType(), cast<Constant>(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<unsigned> InRangeIndex, + std::optional<unsigned> InRangeIndex, ArrayRef<Value *> 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<PoisonValue>(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<Constant>(Idx); return IdxC->isNullValue() || isa<UndefValue>(IdxC); |
