aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-11-01 16:24:33 +0100
committerNikita Popov <npopov@redhat.com>2023-11-01 16:50:52 +0100
commit57384aeb3743dc2b5540cedd965977b6a67ae01f (patch)
tree0aa1510067516f02bc2c2e3e3b58b58efde2b3de /llvm/lib/IR/ConstantFold.cpp
parentc605431a4045f78929e8f6f0aeb20ee26ce6792c (diff)
downloadllvm-57384aeb3743dc2b5540cedd965977b6a67ae01f.zip
llvm-57384aeb3743dc2b5540cedd965977b6a67ae01f.tar.gz
llvm-57384aeb3743dc2b5540cedd965977b6a67ae01f.tar.bz2
[ConstantFold] Avoid creating undesirable cast expressions
Similar to what we do for binops, for undesirable casts we should call the constant folding API instead of the constant expr API, to avoid indirect creation of undesirable cast ops.
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp23
1 files changed, 17 insertions, 6 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index d35106a..15a7485 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -295,6 +295,13 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart,
}
}
+static Constant *foldMaybeUndesirableCast(unsigned opc, Constant *V,
+ Type *DestTy) {
+ return ConstantExpr::isDesirableCastOp(opc)
+ ? ConstantExpr::getCast(opc, V, DestTy)
+ : ConstantFoldCastInstruction(opc, V, DestTy);
+}
+
Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
Type *DestTy) {
if (isa<PoisonValue>(V))
@@ -320,7 +327,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
if (CE->isCast()) {
// Try hard to fold cast of cast because they are often eliminable.
if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy))
- return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy);
+ return foldMaybeUndesirableCast(newOpc, CE->getOperand(0), DestTy);
} else if (CE->getOpcode() == Instruction::GetElementPtr &&
// Do not fold addrspacecast (gep 0, .., 0). It might make the
// addrspacecast uncanonicalized.
@@ -357,18 +364,22 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
Type *DstEltTy = DestVecTy->getElementType();
// Fast path for splatted constants.
if (Constant *Splat = V->getSplatValue()) {
+ Constant *Res = foldMaybeUndesirableCast(opc, Splat, DstEltTy);
+ if (!Res)
+ return nullptr;
return ConstantVector::getSplat(
- cast<VectorType>(DestTy)->getElementCount(),
- ConstantExpr::getCast(opc, Splat, DstEltTy));
+ cast<VectorType>(DestTy)->getElementCount(), Res);
}
SmallVector<Constant *, 16> res;
Type *Ty = IntegerType::get(V->getContext(), 32);
for (unsigned i = 0,
e = cast<FixedVectorType>(V->getType())->getNumElements();
i != e; ++i) {
- Constant *C =
- ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
- res.push_back(ConstantExpr::getCast(opc, C, DstEltTy));
+ Constant *C = ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
+ Constant *Casted = foldMaybeUndesirableCast(opc, C, DstEltTy);
+ if (!Casted)
+ return nullptr;
+ res.push_back(Casted);
}
return ConstantVector::get(res);
}