[llvm-branch-commits] [llvm] 57443bf - [Hexagon] Fix segment start to adjust for gaps between segments

Krzysztof Parzyszek via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jan 19 10:59:01 PST 2021


Author: Brendon Cahoon
Date: 2021-01-19T12:49:39-06:00
New Revision: 57443bfb4ab06f7dc45f802119efc1068289cdd9

URL: https://github.com/llvm/llvm-project/commit/57443bfb4ab06f7dc45f802119efc1068289cdd9
DIFF: https://github.com/llvm/llvm-project/commit/57443bfb4ab06f7dc45f802119efc1068289cdd9.diff

LOG: [Hexagon] Fix segment start to adjust for gaps between segments

The Hexagon Vector Combine pass genertes stores for a complete
aligned vector. The start of each section is a multiple of the
vector size, so that value is passed to normalize to compute
the offset of the stores in the section.  The first store may
not occur at offset 0 when there is a gap between sections.

Added: 
    llvm/test/CodeGen/Hexagon/autohvx/vector-align-store-mask.ll

Modified: 
    llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp
index 01fd8a9ef9ce..a605fdfcf100 100644
--- a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp
@@ -198,7 +198,7 @@ class AlignVectors {
 
     int extent() const;
     ByteSpan section(int Start, int Length) const;
-    ByteSpan &normalize();
+    ByteSpan &shift(int Offset);
 
     int size() const { return Blocks.size(); }
     Block &operator[](int i) { return Blocks[i]; }
@@ -348,16 +348,9 @@ auto AlignVectors::ByteSpan::section(int Start, int Length) const -> ByteSpan {
   return Section;
 }
 
-auto AlignVectors::ByteSpan::normalize() -> ByteSpan & {
-  if (size() == 0)
-    return *this;
-  int Min = Blocks[0].Pos;
-  for (int i = 1, e = size(); i != e; ++i)
-    Min = std::min(Min, Blocks[i].Pos);
-  if (Min != 0) {
-    for (Block &B : Blocks)
-      B.Pos -= Min;
-  }
+auto AlignVectors::ByteSpan::shift(int Offset) -> ByteSpan & {
+  for (Block &B : Blocks)
+    B.Pos += Offset;
   return *this;
 }
 
@@ -794,7 +787,7 @@ auto AlignVectors::realignGroup(const MoveGroup &Move) const -> bool {
     }
 
     for (ByteSpan::Block &B : VSpan) {
-      ByteSpan Section = ASpan.section(B.Pos, B.Seg.Size).normalize();
+      ByteSpan Section = ASpan.section(B.Pos, B.Seg.Size).shift(-B.Pos);
       Value *Accum = UndefValue::get(HVC.getByteTy(B.Seg.Size));
       for (ByteSpan::Block &S : Section) {
         Value *Pay = HVC.vbytes(Builder, getPayload(S.Seg.Val));
@@ -830,7 +823,9 @@ auto AlignVectors::realignGroup(const MoveGroup &Move) const -> bool {
     // Create an extra "undef" sector at the beginning and at the end.
     // They will be used as the left/right filler in the vlalign step.
     for (int i = -1; i != NumSectors + 1; ++i) {
-      ByteSpan Section = VSpan.section(i * ScLen, ScLen).normalize();
+      // For stores, the size of each section is an aligned vector length.
+      // Adjust the store offsets relative to the section start offset.
+      ByteSpan Section = VSpan.section(i * ScLen, ScLen).shift(-i * ScLen);
       Value *AccumV = UndefValue::get(SecTy);
       Value *AccumM = HVC.getNullValue(SecTy);
       for (ByteSpan::Block &S : Section) {

diff  --git a/llvm/test/CodeGen/Hexagon/autohvx/vector-align-store-mask.ll b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-store-mask.ll
new file mode 100644
index 000000000000..d63366fc1ca9
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-store-mask.ll
@@ -0,0 +1,36 @@
+; RUN: llc -march=hexagon -hexagon-hvx-widen=32 < %s | FileCheck %s
+
+target triple = "hexagon"
+
+; Test the the store mask is adjusted for gaps between sections. The
+; Vector Combine pass generates masked stores for chunks of 128 bytes.
+; The masked store must be shifted if the first store in a section
+; is not a multiple of 128 bytes. This test checks that two masks
+; are created, and the second mask is used in a masked store.
+
+; CHECK: [[REG:r[0-9]+]] = ##.LCPI0_1
+; CHECK: [[VREG1:v[0-9]+]] = vmem([[REG]]+#0)
+; CHECK: [[VREG2:v[0-9]+]] = vlalign([[VREG1]],v{{[0-9]+}},r{{[0-9]+}})
+; CHECK: [[QREG:q[0-3]+]] = vand([[VREG2]],r{{[0-9]+}})
+; CHECK: if ([[QREG]]) vmem({{.*}}) = v{{[0-9]+}}
+
+define dllexport void @f0(i32* %a0) local_unnamed_addr #0 {
+b0:
+  br label %b1
+
+b1:                                               ; preds = %b1, %b0
+  %v0 = or i32 -1, 40
+  %v1 = getelementptr inbounds i32, i32* %a0, i32 %v0
+  %v2 = bitcast i32* %v1 to <8 x i32>*
+  store <8 x i32> undef, <8 x i32>* %v2, align 32
+  %v3 = or i32 0, 48
+  %v4 = getelementptr inbounds i32, i32* %a0, i32 %v3
+  %v5 = bitcast i32* %v4 to <8 x i32>*
+  store <8 x i32> undef, <8 x i32>* %v5, align 64
+  br i1 undef, label %b2, label %b1
+
+b2:                                               ; preds = %b1
+  ret void
+}
+
+attributes #0 = { "target-features"="+hvxv66,+hvx-length128b" }


        


More information about the llvm-branch-commits mailing list