diff options
author | Nikita Popov <npopov@redhat.com> | 2023-11-01 16:24:33 +0100 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2023-11-01 16:50:52 +0100 |
commit | 57384aeb3743dc2b5540cedd965977b6a67ae01f (patch) | |
tree | 0aa1510067516f02bc2c2e3e3b58b58efde2b3de /llvm/lib/IR/ConstantFold.cpp | |
parent | c605431a4045f78929e8f6f0aeb20ee26ce6792c (diff) | |
download | llvm-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.cpp | 23 |
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); } |