[PATCH] D95139: [SVE][LoopVectorize] Add support for extracting the last lane of a scalable vector

Sander de Smalen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 28 07:30:48 PST 2021


sdesmalen added inline comments.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2467
 
-  assert(Instance.Lane > 0
+  assert((Instance.Lane > 0 || Instance.isNonConstLane())
              ? !Cost->isUniformAfterVectorization(cast<Instruction>(V), VF)
----------------
should this be implied by Instance.Lane > 0? (implemented with operator overload, `Instance > 0`)


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2488-2494
+  if (Instance.isNonConstLane()) {
+    assert(Instance.Kind == VPIteration::LK_ScalableLast &&
+           "Cannot handle other non-constant lane types");
+    Lane = Builder.CreateSub(getRuntimeVF(Builder, Builder.getInt32Ty(), VF),
+                             Builder.getInt32(1 + Instance.Lane));
+  } else
+    Lane = Builder.getInt32(Instance.Lane);
----------------
nit:

  switch (Instance.Kind) {
  case VPIteration::LK_First:
    Lane = Builder.getInt32(Instance.Lane);
    break;
  case VPIteration::LK_ScalableLast:
    Lane = Builder.CreateSub(...);
    break;
  }

(without default). That will give a compile-time warning when a new kind is added.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:4428
+      else
+        Lane = VF.getKnownMinValue() - 1;
+    }
----------------
Should Lane not be set to VF.getKnownMinValue() - 1 for VF.isScalable() as well?


================
Comment at: llvm/lib/Transforms/Vectorize/VPlan.h:101-108
+  /// There are cases where we wish to extract a particular lane of a vector,
+  /// but don't know the exact value at compile time. For example, we may wish
+  /// to extract the last lane of a scalable vector and this requires using a
+  /// runtime calculation. The enum below describes how the 'Lane' is
+  /// interpreted. The default is LK_First, which means the lane offset from
+  /// the start of the vector. If you want to extract a lane at an offset from
+  /// the end, i.e. LastLane - Lane, you can set the lane 'Kind' to
----------------
How about:

  /// LaneKind describes how to interpret Lane.
  /// For LK_First, Lane is the index into the first N elements of a fixed-vector <N x <etltty>> or a scalable vector <vscale x N x <eltty>>.
  /// For LK_ScalableLast, Lane is the index into the last N elements of a scalable vector <vscale x N x  <eltty>>


================
Comment at: llvm/lib/Transforms/Vectorize/VPlan.h:180
+  /// Returns the number of lanes that we are able to cache.
+  unsigned getNumCachedLanes() const { return 2 * VF.getKnownMinValue(); }
+
----------------
This only needs to be `2 * VF.getKnownMinValue()` if VF is scalable.


================
Comment at: llvm/lib/Transforms/Vectorize/VPlan.h:187
+      return VF.getKnownMinValue() + Instance.Lane;
+    default:
+      assert(Instance.Kind == VPIteration::LK_First);
----------------
use LK_First and drop the default, so that you get a compile-time warning if a new kind is added to the enum.


================
Comment at: llvm/lib/Transforms/Vectorize/VPlan.h:205
            "ScalarParts has wrong dimensions.");
-    return Entry[Instance.Part][Instance.Lane] != nullptr;
+    unsigned CacheIdx = mapInstanceLaneToIndex(Instance);
+    return Entry[Instance.Part][CacheIdx] != nullptr;
----------------
Can you make this a method to VPIteration, e.g. `getIndex()`


================
Comment at: llvm/lib/Transforms/Vectorize/VPlan.h:102
+  enum NonConstantLanes {
+    LAST_LANE = 0xFFFFFFFF,
+    FIRST_NON_CONST_LANE = LAST_LANE,
----------------
david-arm wrote:
> sdesmalen wrote:
> > For scalable vectors, it probably only ever makes sense to capture any of the following lanes:
> > * The first N lanes from <vscale x N x <eltty>>
> > * The last N lanes from <vscale x N x <eltty>>
> > 
> > I'm not sure if the loop-vectorizer would currently ever need more than just the first/last lane, but I could imagine for interleaving it may want to extract the second/third/fourth-last value from the vector.
> > 
> > Perhaps you can represent this with:
> >   unsigned LaneIdx;
> >   enum {
> >     LK_Fixed,
> >     LK_ScalableFirst,
> >     LK_ScalableLast,
> >   } LaneKind;
> > ?
> I'm happy with the idea of adding an extra member to VPInstance that contains an enum and is probably nicer than what I have now! I'm not sure if we need a LK_ScalableFirst though as this is always known at compile time to be 0 I think - perhaps we just need a LK_First and a LK_ScalableLast? Also, are suggesting that the enum describes how to use Lane, i.e.
> 
> if (StartFromFirst)
>   Index = Lane
> else if (StartFromLast)
>   Index = NumElts - 1 - Lane?
> 
> or with LK_ScalableLast do you literally mean the last lane of the vector?
I indeed meant that LaneKind indexes the first or last 'chunk' in the vector, e.g. `v0, v1` for the first, and `vN-2, vN-1` for the last in:

  <vscale x 2 x i32> <=> <elt0, elt1 |  elt2, elt3 | ... | eltN-2, eltN-1>



CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95139/new/

https://reviews.llvm.org/D95139



More information about the llvm-commits mailing list