[llvm] [NFCI][msan] Extract 'shrinkVectorShadow' and 'extendVectorShadowWithZeros' into helper functions (PR #147415)
Thurston Dang via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 7 15:53:30 PDT 2025
https://github.com/thurstond updated https://github.com/llvm/llvm-project/pull/147415
>From d985b19c231bd083ae64503e33e31e298a4570b5 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 7 Jul 2025 22:10:54 +0000
Subject: [PATCH 1/3] [NFCI][msan] Extract 'shrinkVectorShadow' and
'extendVectorShadowWithZeros' into helper functions
These functions will be useful in other intrinsic handlers.
---
.../Instrumentation/MemorySanitizer.cpp | 74 ++++++++++++++-----
1 file changed, 54 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index ec94dcaa2c051..a098ca388738b 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3389,6 +3389,58 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOriginForNaryOp(I);
}
+ /// Some instructions have additional zero-elements in the return type
+ /// e.g., <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512(<8 x i64>, ...)
+ ///
+ /// This function will return a vector type with the same number of elements
+ /// as the input, but same width as the return value e.g., <8 x i8>.
+ FixedVectorType *shrinkVectorShadow(Value *Src, IntrinsicInst &I) {
+ assert(isa<FixedVectorType>(getShadowTy(&I)));
+ // The return type might have more elements than the input.
+ // Temporarily shrink the return type's number of elements.
+ FixedVectorType *ShadowType = cast<FixedVectorType>(getShadowTy(&I));
+
+ // TODO: generalize beyond 2x?
+ if (ShadowType->getElementCount() ==
+ cast<VectorType>(Src->getType())->getElementCount() * 2)
+ ShadowType = FixedVectorType::getHalfElementsVectorType(ShadowType);
+
+ assert(ShadowType->getElementCount() ==
+ cast<VectorType>(Src->getType())->getElementCount());
+
+ return ShadowType;
+ }
+
+ /// Doubles the length of a vector shadow (filled with zeros) if necessary to
+ /// match the length of the shadow for the instruction.
+ /// This is more type-safe than CreateShadowCast().
+ Value *extendVectorShadowWithZeros(Value *Shadow, IntrinsicInst &I) {
+ IRBuilder<> IRB(&I);
+ assert(isa<FixedVectorType>(Shadow->getType()));
+ assert(isa<FixedVectorType>(I.getType()));
+
+ Value *FullShadow = getCleanShadow(&I);
+ assert(cast<FixedVectorType>(Shadow->getType())->getNumElements() <=
+ cast<FixedVectorType>(FullShadow->getType())->getNumElements());
+ assert(cast<FixedVectorType>(Shadow->getType())->getScalarType() ==
+ cast<FixedVectorType>(FullShadow->getType())->getScalarType());
+
+ if (Shadow->getType() == FullShadow->getType()) {
+ FullShadow = Shadow;
+ } else {
+ // TODO: generalize beyond 2x?
+ SmallVector<int, 32> ShadowMask(
+ cast<FixedVectorType>(FullShadow->getType())->getNumElements());
+ std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
+
+ // Append zeros
+ FullShadow =
+ IRB.CreateShuffleVector(Shadow, getCleanShadow(Shadow), ShadowMask);
+ }
+
+ return FullShadow;
+ }
+
/// Handle x86 SSE vector conversion.
///
/// e.g., single-precision to half-precision conversion:
@@ -3419,13 +3471,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// The return type might have more elements than the input.
// Temporarily shrink the return type's number of elements.
- VectorType *ShadowType = cast<VectorType>(getShadowTy(&I));
- if (ShadowType->getElementCount() ==
- cast<VectorType>(Src->getType())->getElementCount() * 2)
- ShadowType = VectorType::getHalfElementsVectorType(ShadowType);
-
- assert(ShadowType->getElementCount() ==
- cast<VectorType>(Src->getType())->getElementCount());
+ VectorType *ShadowType = shrinkVectorShadow(Src, I);
IRBuilder<> IRB(&I);
Value *S0 = getShadow(&I, 0);
@@ -3440,19 +3486,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// The return type might have more elements than the input.
// Extend the return type back to its original width if necessary.
- Value *FullShadow = getCleanShadow(&I);
-
- if (Shadow->getType() == FullShadow->getType()) {
- FullShadow = Shadow;
- } else {
- SmallVector<int, 8> ShadowMask(
- cast<FixedVectorType>(FullShadow->getType())->getNumElements());
- std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
-
- // Append zeros
- FullShadow =
- IRB.CreateShuffleVector(Shadow, getCleanShadow(Shadow), ShadowMask);
- }
+ Value *FullShadow = extendVectorShadowWithZeros(Shadow, I);
setShadow(&I, FullShadow);
setOriginForNaryOp(I);
>From 715ccab41849ec8ba7f05216901c4ffafc9a306c Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 7 Jul 2025 22:19:38 +0000
Subject: [PATCH 2/3] Rename to shrinkVectorShadowType
---
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index a098ca388738b..566264f23c831 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3394,7 +3394,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
///
/// This function will return a vector type with the same number of elements
/// as the input, but same width as the return value e.g., <8 x i8>.
- FixedVectorType *shrinkVectorShadow(Value *Src, IntrinsicInst &I) {
+ FixedVectorType *shrinkVectorShadowType(Value *Src, IntrinsicInst &I) {
assert(isa<FixedVectorType>(getShadowTy(&I)));
// The return type might have more elements than the input.
// Temporarily shrink the return type's number of elements.
@@ -3471,7 +3471,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// The return type might have more elements than the input.
// Temporarily shrink the return type's number of elements.
- VectorType *ShadowType = shrinkVectorShadow(Src, I);
+ VectorType *ShadowType = shrinkVectorShadowType(Src, I);
IRBuilder<> IRB(&I);
Value *S0 = getShadow(&I, 0);
>From 86ba37e4f2e05b95a8cb6ea9103e0974fa725bc4 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 7 Jul 2025 22:53:12 +0000
Subject: [PATCH 3/3] Clarify per-element width
---
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 566264f23c831..978d7f6d74354 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3393,7 +3393,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// e.g., <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512(<8 x i64>, ...)
///
/// This function will return a vector type with the same number of elements
- /// as the input, but same width as the return value e.g., <8 x i8>.
+ /// as the input, but same per-element width as the return value e.g.,
+ /// <8 x i8>.
FixedVectorType *shrinkVectorShadowType(Value *Src, IntrinsicInst &I) {
assert(isa<FixedVectorType>(getShadowTy(&I)));
// The return type might have more elements than the input.
More information about the llvm-commits
mailing list