[PATCH] D76508: [VectorUtils] move x86's scaleShuffleMask to generic VectorUtils

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 20 09:11:07 PDT 2020


spatel created this revision.
spatel added reviewers: efriedma, RKSimon, lebedev.ri, nikic.
Herald added subscribers: hiraditya, mcrosier.
Herald added a reviewer: aartbik.

We have some long-standing missing shuffle optimizations that could use this transform via VectorCombine now:
https://bugs.llvm.org/show_bug.cgi?id=35454
(and we still don't get that case in the backend either)

This function is apparently templated because there's existing code in IR that treats mask values as unsigned and backend code that treats masks values as signed?

The mask values are not endian-dependent IIUC.


https://reviews.llvm.org/D76508

Files:
  llvm/include/llvm/Analysis/VectorUtils.h
  llvm/lib/Target/X86/X86ISelLowering.h
  llvm/unittests/Analysis/VectorUtilsTest.cpp


Index: llvm/unittests/Analysis/VectorUtilsTest.cpp
===================================================================
--- llvm/unittests/Analysis/VectorUtilsTest.cpp
+++ llvm/unittests/Analysis/VectorUtilsTest.cpp
@@ -98,6 +98,12 @@
   EXPECT_FALSE(isSplatValue(SplatWithUndefC));
 }
 
+TEST_F(BasicTest, scaleShuffleMask) {
+  SmallVector<int, 16> ScaledMask;
+  scaleShuffleMask<int>(4, {3,2,0,-1}, ScaledMask);
+  EXPECT_EQ(makeArrayRef<int>(ScaledMask), makeArrayRef<int>({12,13,14,15,8,9,10,11,0,1,2,3,-1,-1,-1,-1}));
+}
+
 TEST_F(BasicTest, getSplatIndex) {
   EXPECT_EQ(getSplatIndex({0,0,0}), 0);
   EXPECT_EQ(getSplatIndex({1,0,0}), -1);     // no splat
Index: llvm/lib/Target/X86/X86ISelLowering.h
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.h
+++ llvm/lib/Target/X86/X86ISelLowering.h
@@ -1595,32 +1595,6 @@
     }
   }
 
-  /// Helper function to scale a shuffle or target shuffle mask, replacing each
-  /// mask index with the scaled sequential indices for an equivalent narrowed
-  /// mask. This is the reverse process to canWidenShuffleElements, but can
-  /// always succeed.
-  template <typename T>
-  void scaleShuffleMask(size_t Scale, ArrayRef<T> Mask,
-                        SmallVectorImpl<T> &ScaledMask) {
-    assert(0 < Scale && "Unexpected scaling factor");
-    size_t NumElts = Mask.size();
-    ScaledMask.assign(NumElts * Scale, -1);
-
-    for (size_t i = 0; i != NumElts; ++i) {
-      int M = Mask[i];
-
-      // Repeat sentinel values in every mask element.
-      if (M < 0) {
-        for (size_t s = 0; s != Scale; ++s)
-          ScaledMask[(Scale * i) + s] = M;
-        continue;
-      }
-
-      // Scale mask element and increment across each mask element.
-      for (size_t s = 0; s != Scale; ++s)
-        ScaledMask[(Scale * i) + s] = (Scale * M) + s;
-    }
-  }
 } // end namespace llvm
 
 #endif // LLVM_LIB_TARGET_X86_X86ISELLOWERING_H
Index: llvm/include/llvm/Analysis/VectorUtils.h
===================================================================
--- llvm/include/llvm/Analysis/VectorUtils.h
+++ llvm/include/llvm/Analysis/VectorUtils.h
@@ -328,6 +328,40 @@
 /// not limited by finding a scalar source value to a splatted vector.
 bool isSplatValue(const Value *V, int Index = -1, unsigned Depth = 0);
 
+/// Scale a shuffle or target shuffle mask, replacing each mask index with the
+/// scaled sequential indices for an equivalent mask of narrowed elements.
+/// Mask elements that are less than 0 (sentinel values) are repeated in the
+/// output mask.
+///
+/// Example with Scale = 4:
+///   <4 x i32> <3, 2, 0, -1> -->
+///   <16 x i8> <12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, -1, -1, -1, -1>
+///
+/// This is the reverse process of "canWidenShuffleElements", but can always
+/// succeed.
+template <typename T>
+void scaleShuffleMask(size_t Scale, ArrayRef<T> Mask,
+                      SmallVectorImpl<T> &ScaledMask) {
+  assert(Scale > 0 && "Unexpected scaling factor");
+  size_t NumElts = Mask.size();
+  ScaledMask.assign(NumElts * Scale, -1);
+
+  for (size_t i = 0; i != NumElts; ++i) {
+    int M = Mask[i];
+
+    // Repeat sentinel values in every mask element.
+    if (M < 0) {
+      for (size_t s = 0; s != Scale; ++s)
+        ScaledMask[(Scale * i) + s] = M;
+      continue;
+    }
+
+    // Scale mask element and increment across each mask element.
+    for (size_t s = 0; s != Scale; ++s)
+      ScaledMask[(Scale * i) + s] = (Scale * M) + s;
+  }
+}
+
 /// Compute a map of integer instructions to their minimum legal type
 /// size.
 ///


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76508.251659.patch
Type: text/x-patch
Size: 3601 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200320/46d5efba/attachment.bin>


More information about the llvm-commits mailing list