[llvm] [SandboxVec][LoadStoreVec] Support constant vectors of mixed types (PR #224890)
Vasileios Porpodas via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 14:51:31 PDT 2026
================
@@ -82,42 +83,108 @@ LoadInst *LoadStoreVec::createVectorLoad(BndlRef<Instruction *> Loads) {
return LoadInst::create(Ty, LdPtr, LdAlign, LdWhereIt, *Ctx, "VecIinitL");
}
-Value *LoadStoreVec::createConstantVector(BndlRef<Value *> Operands) {
- SmallVector<Constant *, 8> Constants;
- Constants.reserve(Operands.size());
+Constant *LoadStoreVec::createEquivalentConstantWithType(Constant *C,
+ Type *DestTy) {
+ Type *SrcTy = C->getType();
+ if (SrcTy == DestTy)
+ return C;
+ auto IsNonIntegralPtr = [this](Type *Ty) {
+ return Ty->isPointerTy() &&
+ DL->isNonIntegralAddressSpace(Ty->getPointerAddressSpace());
+ };
+ if (IsNonIntegralPtr(SrcTy) || IsNonIntegralPtr(DestTy))
+ return nullptr;
+
+ Constant *AsInt = C;
+ if (!SrcTy->isIntegerTy()) {
+ Type *IntTy = IntegerType::get(*Ctx, Utils::getNumBits(SrcTy, *DL));
+ AsInt = SrcTy->isPointerTy() ? ConstantExpr::getPtrToInt(C, IntTy)
+ : ConstantExpr::getBitCast(C, IntTy);
+ }
+ if (DestTy->isIntegerTy())
+ return AsInt;
+ return DestTy->isPointerTy() ? ConstantExpr::getIntToPtr(AsInt, DestTy)
+ : ConstantExpr::getBitCast(AsInt, DestTy);
+}
+
+Value *LoadStoreVec::createConstantVector(ArrayRef<Value *> Operands,
+ Type *LaneTy) {
+ SmallVector<Constant *, 8> ConstantElements;
+ ConstantElements.reserve(Operands.size());
for (Value *Op : Operands) {
auto *COp = cast<Constant>(Op);
if (auto *AggrCOp = dyn_cast<ConstantAggregate>(COp)) {
// If the operand is a constant aggregate, then append all its elements.
for (Value *Elm : AggrCOp->operands())
- Constants.push_back(cast<Constant>(Elm));
+ ConstantElements.push_back(cast<Constant>(Elm));
} else if (auto *SeqCOp = dyn_cast<ConstantDataSequential>(COp)) {
for (auto ElmIdx : seq<unsigned>(SeqCOp->getNumElements()))
- Constants.push_back(SeqCOp->getElementAsConstant(ElmIdx));
+ ConstantElements.push_back(SeqCOp->getElementAsConstant(ElmIdx));
} else if (auto *Zero = dyn_cast<ConstantAggregateZero>(COp)) {
auto *ZeroElm = Zero->getSequentialElement();
for ([[maybe_unused]] auto Cnt :
seq<unsigned>(Zero->getElementCount().getFixedValue()))
- Constants.push_back(ZeroElm);
+ ConstantElements.push_back(ZeroElm);
} else if (isa<ConstantInt>(COp) && isa<VectorType>(COp->getType())) {
auto *Elm = ConstantInt::get(*Ctx, cast<ConstantInt>(COp)->getValue());
for ([[maybe_unused]] auto Cnt :
seq<unsigned>(cast<VectorType>(COp->getType())
->getElementCount()
.getFixedValue()))
- Constants.push_back(Elm);
+ ConstantElements.push_back(Elm);
} else if (isa<ConstantFP>(COp) && isa<VectorType>(COp->getType())) {
auto *Elm = ConstantFP::get(cast<ConstantFP>(COp)->getValue(), *Ctx);
for ([[maybe_unused]] auto Cnt :
seq<unsigned>(cast<VectorType>(COp->getType())
->getElementCount()
.getFixedValue()))
- Constants.push_back(Elm);
+ ConstantElements.push_back(Elm);
+ } else if (isa<VectorType>(COp->getType())) {
+ // TODO: Flatten the remaining vector constants, e.g. undef or poison.
+ return nullptr;
} else {
- Constants.push_back(COp);
+ ConstantElements.push_back(COp);
}
}
- return ConstantVector::get(Constants);
+
+ // Stores may mix types, e.g. i32 and float. Convert each constant to LaneTy.
+ // A wider constant is split into multiple LaneTy-sized pieces, in memory
+ // order.
+ unsigned LaneBits = Utils::getNumBits(LaneTy, *DL);
+ SmallVector<Constant *, 8> ConstantLanes;
+ ConstantLanes.reserve(ConstantElements.size());
+ for (Constant *C : ConstantElements) {
+ unsigned Bits = Utils::getNumBits(C->getType(), *DL);
+ if (Bits == LaneBits) {
+ Constant *Lane = createEquivalentConstantWithType(C, LaneTy);
+ if (Lane == nullptr)
+ return nullptr;
+ ConstantLanes.push_back(Lane);
+ } else if (Bits > LaneBits && Bits % LaneBits == 0) {
+ // Only integer bit patterns can be split, so this bails out on constants
+ // like the address of a global.
+ auto *CI = dyn_cast_or_null<ConstantInt>(
+ createEquivalentConstantWithType(C, IntegerType::get(*Ctx, Bits)));
+ if (CI == nullptr)
+ return nullptr;
+ const APInt &Val = CI->getValue();
+ unsigned NumLanes = Bits / LaneBits;
+ for (unsigned Idx : seq<unsigned>(NumLanes)) {
+ unsigned Part = DL->isLittleEndian() ? Idx : NumLanes - 1 - Idx;
----------------
vporpo wrote:
EnidanAwareSlice instead of Part ?
https://github.com/llvm/llvm-project/pull/224890
More information about the llvm-commits
mailing list