[llvm-branch-commits] [llvm] [SandboxVec][LoadStoreVec][NFC] Generalize reinterpretConstant to values (PR #224997)
Anshil Gandhi via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Sep 20 22:36:14 PDT 2026
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 <gandhi21299 at gmail.com>
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,
More information about the llvm-branch-commits
mailing list