[llvm] [SLP]Analyze widened reduction leaves in the narrow type (PR #216062)
Ryan Buchner via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 12:59:39 PDT 2026
================
@@ -31342,6 +31416,39 @@ class HorizontalReduction {
SameValuesCounter, RootTrackedToOrig);
}
+ // Widen and shift per lane. Map back from extractelements to the
+ // original reduced values for the shift amounts. The absorbed narrow
+ // and-masks and the bits truncated by the absorbed narrow shls are
+ // masked off after the shift.
+ if (!NarrowedLeafShifts.empty()) {
+ Type *WideTy = ReductionRoot->getType();
+ unsigned VF = getNumElements(VectorizedRoot->getType());
+ VectorizedRoot =
+ Builder.CreateZExt(VectorizedRoot, getWidenedType(WideTy, VF));
+ SmallVector<Constant *> ShiftConsts(VF, ConstantInt::get(WideTy, 0));
+ SmallVector<Constant *> MaskConsts(VF,
+ Constant::getAllOnesValue(WideTy));
+ bool AnyShift = false;
+ bool AnyMask = false;
+ for (auto [Idx, Val] : enumerate(VL)) {
+ const NarrowedLeafInfo &L =
+ NarrowedLeafShifts.at(TrackedToOrig[Pos + Idx]);
+ unsigned Lane = V.findRootLaneForValue(Val);
+ ShiftConsts[Lane] = ConstantInt::get(WideTy, L.Shift);
+ AnyShift |= L.Shift != 0;
+ if (!L.Mask.isAllOnes()) {
+ MaskConsts[Lane] = ConstantInt::get(WideTy, L.Mask);
+ AnyMask = true;
+ }
+ }
+ if (AnyShift)
+ VectorizedRoot = Builder.CreateShl(
+ VectorizedRoot, ConstantVector::get(ShiftConsts));
+ if (AnyMask)
+ VectorizedRoot = Builder.CreateAnd(VectorizedRoot,
+ ConstantVector::get(MaskConsts));
----------------
bababuck wrote:
I think we should emit the `and` before the `shl` and the `zext`. In cases such as the motivating example, it will cause the `and` mask to become constant across all lanes. In other cases where that doesn't occur, moving it prior to the `zext` will allow the mask to be in a smaller `8 bit` type which will allow for cheaper materialization on different backends. For RISCV, if the vector width is small enough, we can synthesize <8 x i8> as an i64 in the scalar side and then move it to the vector side using an int->vec move instruction before bitcasting it to <8 x i8>.
https://github.com/llvm/llvm-project/pull/216062
More information about the llvm-commits
mailing list