https://github.com/gandhi56 created https://github.com/llvm/llvm-project/pull/224997
Stacked on #224996, which is the base of this PR. reinterpretConstant() reinterprets the bits of a constant as another type of the same size, which is needed for any value once mixed-type load chains are unpacked, not just for constants. Split the cast logic out into reinterpretValue(), which works on any Value, and keep reinterpretConstant() as a wrapper for the constant callers. While here, handle vectors of pointers by going through `<N x iM>`, so that the helper covers every type a lane can have. Casts of constants fold, so the constant path emits no instructions, as before, and no test output changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) >From 5ec64a3f2b9296b1ae43d52af573d37f6e5d59a3 Mon Sep 17 00:00:00 2001 From: Anshil Gandhi <[email protected]> Date: Mon, 21 Sep 2026 00:49:43 -0400 Subject: [PATCH] [SandboxVec][LoadStoreVec][NFC] Generalize reinterpretConstant to values reinterpretConstant() reinterprets the bits of a constant as another type of the same size, which is needed for any value once mixed-type load chains are unpacked, not just for constants. Split the cast logic out into reinterpretValue(), which works on any Value, and keep reinterpretConstant() as a wrapper for the constant callers. While here, handle vectors of pointers by going through <N x iM>, so that the helper covers every type a lane can have. Casts of constants fold, so the constant path emits no instructions, as before. Assisted by Claude Opus 5 --- .../SandboxVectorizer/Passes/LoadStoreVec.cpp | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp index 86d93b4cfdd73..f86cee65057ad 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp @@ -82,42 +82,56 @@ LoadInst *LoadStoreVec::createVectorLoad(BndlRef<Instruction *> Loads) { return LoadInst::create(Ty, LdPtr, LdAlign, LdWhereIt, *Ctx, "VecIinitL"); } -/// Reinterprets the bits of \p C as \p DestTy, which must have the same size -/// in \p DL. Goes through an integer of that size using ptrtoint / inttoptr / -/// bitcast. \Returns nullptr if the result does not fold to a constant or if a -/// non-integral pointer is involved. -static Constant *reinterpretConstant(Constant *C, Type *DestTy, - BBIterator WhereIt, Context &Ctx, - const DataLayout &DL) { - Type *SrcTy = C->getType(); +/// \returns an integer type with the same layout as \p Ty: iN for scalars, +/// <N x iM> for vectors. +static Type *getIntTypeFor(Type *Ty, Context &Ctx, const DataLayout &DL) { + if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) { + auto *ElmIntTy = + IntegerType::get(Ctx, Utils::getNumBits(VecTy->getElementType(), DL)); + return FixedVectorType::get(ElmIntTy, VecTy->getNumElements()); + } + return IntegerType::get(Ctx, Utils::getNumBits(Ty, DL)); +} + +/// Reinterprets the bits of \p V as \p DestTy, which must have the same size +/// in \p DL. Pointers only convert with ptrtoint / inttoptr, so those go +/// through an integer of matching layout, everything else through a bitcast. +/// Casts of constants fold, so nothing is inserted at \p WhereIt for those. +/// \returns nullptr if a non-integral pointer is involved. +static Value *reinterpretValue(Value *V, Type *DestTy, BBIterator WhereIt, + Context &Ctx, const DataLayout &DL) { + Type *SrcTy = V->getType(); if (SrcTy == DestTy) - return C; + return V; auto IsNonIntegralPtr = [&DL](Type *Ty) { - return Ty->isPointerTy() && - DL.isNonIntegralAddressSpace(Ty->getPointerAddressSpace()); + Type *ScalarTy = Ty->getScalarType(); + return ScalarTy->isPointerTy() && + DL.isNonIntegralAddressSpace(ScalarTy->getPointerAddressSpace()); }; if (IsNonIntegralPtr(SrcTy) || IsNonIntegralPtr(DestTy)) return nullptr; - auto Cast = [&](Constant *V, Type *To, - Instruction::Opcode Opc) -> Constant * { - if (V == nullptr) - return nullptr; - // Casts of constants fold, so nothing is inserted at WhereIt. - return dyn_cast<Constant>( - CastInst::create(To, Opc, V, WhereIt, Ctx, "VCast")); + auto Cast = [&](Value *Op, Type *To, Instruction::Opcode Opc) -> Value * { + if (Op == nullptr || Op->getType() == To) + return Op; + return CastInst::create(To, Opc, Op, WhereIt, Ctx, "VCast"); }; - Constant *AsInt = C; - if (!SrcTy->isIntegerTy()) { - Type *IntTy = IntegerType::get(Ctx, Utils::getNumBits(SrcTy, DL)); - AsInt = Cast(C, IntTy, - SrcTy->isPointerTy() ? Instruction::Opcode::PtrToInt - : Instruction::Opcode::BitCast); - } - if (DestTy->isIntegerTy()) - return AsInt; - return Cast(AsInt, DestTy, - DestTy->isPointerTy() ? Instruction::Opcode::IntToPtr - : Instruction::Opcode::BitCast); + Value *AsInt = V; + if (SrcTy->getScalarType()->isPointerTy()) + AsInt = + Cast(V, getIntTypeFor(SrcTy, Ctx, DL), Instruction::Opcode::PtrToInt); + if (!DestTy->getScalarType()->isPointerTy()) + return Cast(AsInt, DestTy, Instruction::Opcode::BitCast); + AsInt = + Cast(AsInt, getIntTypeFor(DestTy, Ctx, DL), Instruction::Opcode::BitCast); + return Cast(AsInt, DestTy, Instruction::Opcode::IntToPtr); +} + +/// reinterpretValue() for constants, which fold to a constant or not at all. +static Constant *reinterpretConstant(Constant *C, Type *DestTy, + BBIterator WhereIt, Context &Ctx, + const DataLayout &DL) { + return dyn_cast_or_null<Constant>( + reinterpretValue(C, DestTy, WhereIt, Ctx, DL)); } Value *LoadStoreVec::createConstantVector(ArrayRef<Value *> Operands, _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
