Skip to content

Commit 9efcce9

Browse files
frasercrmcktstellar
authored andcommitted
[RISCV] Fix lowering of BUILD_VECTORs as VID sequences
This patch fixes a bug when lowering BUILD_VECTOR via VID sequences. After adding support for fractional steps in D106533, elements with zero steps may be skipped if no step has yet been computed. This allowed certain sequences to slip through the cracks, being identified as VID sequences when in fact they are not. The fix for this is to perform a second loop over the BUILD_VECTOR to validate the entire sequence once the step has been computed. This isn't the most efficient, but on balance the code is more readable and maintainable than doing back-validation during the first loop. Fixes the tests introduced in D123785. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D123786 (cherry picked from commit c5cac48)
1 parent 21ce6cf commit 9efcce9

File tree

2 files changed

+44
-35
lines changed

2 files changed

+44
-35
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,49 +1908,57 @@ static Optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
19081908
// A zero-value value difference means that we're somewhere in the middle
19091909
// of a fractional step, e.g. <0,0,0*,0,1,1,1,1>. Wait until we notice a
19101910
// step change before evaluating the sequence.
1911-
if (ValDiff != 0) {
1912-
int64_t Remainder = ValDiff % IdxDiff;
1913-
// Normalize the step if it's greater than 1.
1914-
if (Remainder != ValDiff) {
1915-
// The difference must cleanly divide the element span.
1916-
if (Remainder != 0)
1917-
return None;
1918-
ValDiff /= IdxDiff;
1919-
IdxDiff = 1;
1920-
}
1921-
1922-
if (!SeqStepNum)
1923-
SeqStepNum = ValDiff;
1924-
else if (ValDiff != SeqStepNum)
1925-
return None;
1911+
if (ValDiff == 0)
1912+
continue;
19261913

1927-
if (!SeqStepDenom)
1928-
SeqStepDenom = IdxDiff;
1929-
else if (IdxDiff != *SeqStepDenom)
1914+
int64_t Remainder = ValDiff % IdxDiff;
1915+
// Normalize the step if it's greater than 1.
1916+
if (Remainder != ValDiff) {
1917+
// The difference must cleanly divide the element span.
1918+
if (Remainder != 0)
19301919
return None;
1920+
ValDiff /= IdxDiff;
1921+
IdxDiff = 1;
19311922
}
1932-
}
19331923

1934-
// Record and/or check any addend.
1935-
if (SeqStepNum && SeqStepDenom) {
1936-
uint64_t ExpectedVal =
1937-
(int64_t)(Idx * (uint64_t)*SeqStepNum) / *SeqStepDenom;
1938-
int64_t Addend = SignExtend64(Val - ExpectedVal, EltSizeInBits);
1939-
if (!SeqAddend)
1940-
SeqAddend = Addend;
1941-
else if (SeqAddend != Addend)
1924+
if (!SeqStepNum)
1925+
SeqStepNum = ValDiff;
1926+
else if (ValDiff != SeqStepNum)
1927+
return None;
1928+
1929+
if (!SeqStepDenom)
1930+
SeqStepDenom = IdxDiff;
1931+
else if (IdxDiff != *SeqStepDenom)
19421932
return None;
19431933
}
19441934

19451935
// Record this non-undef element for later.
19461936
if (!PrevElt || PrevElt->first != Val)
19471937
PrevElt = std::make_pair(Val, Idx);
19481938
}
1949-
// We need to have logged both a step and an addend for this to count as
1950-
// a legal index sequence.
1951-
if (!SeqStepNum || !SeqStepDenom || !SeqAddend)
1939+
1940+
// We need to have logged a step for this to count as a legal index sequence.
1941+
if (!SeqStepNum || !SeqStepDenom)
19521942
return None;
19531943

1944+
// Loop back through the sequence and validate elements we might have skipped
1945+
// while waiting for a valid step. While doing this, log any sequence addend.
1946+
for (unsigned Idx = 0; Idx < NumElts; Idx++) {
1947+
if (Op.getOperand(Idx).isUndef())
1948+
continue;
1949+
uint64_t Val = Op.getConstantOperandVal(Idx) &
1950+
maskTrailingOnes<uint64_t>(EltSizeInBits);
1951+
uint64_t ExpectedVal =
1952+
(int64_t)(Idx * (uint64_t)*SeqStepNum) / *SeqStepDenom;
1953+
int64_t Addend = SignExtend64(Val - ExpectedVal, EltSizeInBits);
1954+
if (!SeqAddend)
1955+
SeqAddend = Addend;
1956+
else if (Addend != SeqAddend)
1957+
return None;
1958+
}
1959+
1960+
assert(SeqAddend && "Must have an addend if we have a step");
1961+
19541962
return VIDSequence{*SeqStepNum, *SeqStepDenom, *SeqAddend};
19551963
}
19561964

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-buildvec.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -705,23 +705,24 @@ define <8 x i16> @splat_idx_v8i16(<8 x i16> %v, i64 %idx) {
705705
ret <8 x i16> %splat
706706
}
707707

708-
; FIXME: This is not a vid sequence!
709708
define <4 x i8> @buildvec_not_vid_v4i8_1() {
710709
; CHECK-LABEL: buildvec_not_vid_v4i8_1:
711710
; CHECK: # %bb.0:
711+
; CHECK-NEXT: lui a0, %hi(.LCPI37_0)
712+
; CHECK-NEXT: addi a0, a0, %lo(.LCPI37_0)
712713
; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, mu
713-
; CHECK-NEXT: vid.v v8
714+
; CHECK-NEXT: vle8.v v8, (a0)
714715
; CHECK-NEXT: ret
715716
ret <4 x i8> <i8 0, i8 0, i8 2, i8 3>
716717
}
717718

718-
; FIXME: This is not a vid sequence!
719719
define <4 x i8> @buildvec_not_vid_v4i8_2() {
720720
; CHECK-LABEL: buildvec_not_vid_v4i8_2:
721721
; CHECK: # %bb.0:
722+
; CHECK-NEXT: lui a0, %hi(.LCPI38_0)
723+
; CHECK-NEXT: addi a0, a0, %lo(.LCPI38_0)
722724
; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, mu
723-
; CHECK-NEXT: vid.v v8
724-
; CHECK-NEXT: vrsub.vi v8, v8, 3
725+
; CHECK-NEXT: vle8.v v8, (a0)
725726
; CHECK-NEXT: ret
726727
ret <4 x i8> <i8 3, i8 3, i8 1, i8 0>
727728
}

0 commit comments

Comments
 (0)