[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:54:18 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/4] [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/4] 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/4] 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.

>From 4a11f831dd427f169c66f7874d25f401f72bfcd1 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 7 Jul 2025 22:54:03 +0000
Subject: [PATCH 4/4] Remove duplicate comment

---
 llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 978d7f6d74354..8a3112b7b2f07 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3397,8 +3397,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
   /// <8 x i8>.
   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.
     FixedVectorType *ShadowType = cast<FixedVectorType>(getShadowTy(&I));
 
     // TODO: generalize beyond 2x?



More information about the llvm-commits mailing list