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" } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits