aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/IR/ConstantFold.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp81
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);