[llvm] [AArch64] SVE Shuffleopt: merge reduction reverse into tbl (PR #206047)
Gaƫtan Bossu via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 07:29:26 PDT 2026
================
@@ -638,5 +638,454 @@ exit:
ret void
}
+define void @uitofp_nxv8i16_to_nxv8f64_deinterleave_fma_with_reverse_double(ptr %src, ptr %src2, ptr %dst, <vscale x 8 x i1> %mask) #0 {
+; CHECK-LABEL: uitofp_nxv8i16_to_nxv8f64_deinterleave_fma_with_reverse_double:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: index z7.d, #0, #-4
+; CHECK-NEXT: mov x9, #-4 // =0xfffffffffffffffc
+; CHECK-NEXT: mov x10, #-3 // =0xfffffffffffffffd
+; CHECK-NEXT: movk x9, #65534, lsl #16
+; CHECK-NEXT: movk x10, #65534, lsl #16
+; CHECK-NEXT: mov z24.d, #0xfffffffffffeffff
+; CHECK-NEXT: mov z4.d, x9
+; CHECK-NEXT: mov x9, #-2 // =0xfffffffffffffffe
+; CHECK-NEXT: mov z5.d, x10
+; CHECK-NEXT: movk x9, #65534, lsl #16
+; CHECK-NEXT: movi v0.2d, #0000000000000000
+; CHECK-NEXT: movi v3.2d, #0000000000000000
+; CHECK-NEXT: incd z7.d
+; CHECK-NEXT: mov z6.d, x9
+; CHECK-NEXT: movi v2.2d, #0000000000000000
+; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: ptrue p1.d
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: add x9, x1, #8
+; CHECK-NEXT: cntw x10
+; CHECK-NEXT: rdvl x11, #2
+; CHECK-NEXT: add z4.d, z7.d, z4.d
+; CHECK-NEXT: add z5.d, z7.d, z5.d
+; CHECK-NEXT: add z6.d, z7.d, z6.d
+; CHECK-NEXT: add z7.d, z7.d, z24.d
+; CHECK-NEXT: .LBB8_1: // %loop
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ld1h { z24.h }, p0/z, [x0]
+; CHECK-NEXT: ld1d { z28.d }, p1/z, [x9, x8, lsl #3]
+; CHECK-NEXT: sub x8, x8, x10
+; CHECK-NEXT: cmn x8, #2048
+; CHECK-NEXT: add x0, x0, x11
+; CHECK-NEXT: tbl z25.h, { z24.h }, z4.h
+; CHECK-NEXT: tbl z26.h, { z24.h }, z5.h
+; CHECK-NEXT: tbl z27.h, { z24.h }, z6.h
+; CHECK-NEXT: tbl z24.h, { z24.h }, z7.h
+; CHECK-NEXT: ucvtf z25.d, p1/m, z25.d
+; CHECK-NEXT: ucvtf z26.d, p1/m, z26.d
+; CHECK-NEXT: ucvtf z27.d, p1/m, z27.d
+; CHECK-NEXT: ucvtf z24.d, p1/m, z24.d
+; CHECK-NEXT: fmul z25.d, z25.d, z28.d
+; CHECK-NEXT: fmul z26.d, z26.d, z28.d
+; CHECK-NEXT: fmul z27.d, z27.d, z28.d
+; CHECK-NEXT: fmul z24.d, z24.d, z28.d
+; CHECK-NEXT: fadd z0.d, z0.d, z25.d
+; CHECK-NEXT: fadd z3.d, z3.d, z26.d
+; CHECK-NEXT: fadd z2.d, z2.d, z27.d
+; CHECK-NEXT: fadd z1.d, z1.d, z24.d
+; CHECK-NEXT: b.ne .LBB8_1
+; CHECK-NEXT: // %bb.2: // %exit
+; CHECK-NEXT: faddv d0, p1, z0.d
+; CHECK-NEXT: faddv d3, p1, z3.d
+; CHECK-NEXT: faddv d2, p1, z2.d
+; CHECK-NEXT: faddv d1, p1, z1.d
+; CHECK-NEXT: mov v0.d[1], v3.d[0]
+; CHECK-NEXT: mov v2.d[1], v1.d[0]
+; CHECK-NEXT: stp q0, q2, [x2]
+; CHECK-NEXT: ret
+entry:
+ %vscale = tail call i64 @llvm.vscale.i64()
+ %stride = shl nuw nsw i64 %vscale, 2
+ %common.base = getelementptr double, ptr %src2, i64 1
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %acc.b.f64 = phi <vscale x 2 x double> [ splat(double 0.000000e+00), %entry ], [ %fadd.b.f64, %loop ]
+ %acc.g.f64 = phi <vscale x 2 x double> [ splat(double 0.000000e+00), %entry ], [ %fadd.g.f64, %loop ]
+ %acc.r.f64 = phi <vscale x 2 x double> [ splat(double 0.000000e+00), %entry ], [ %fadd.r.f64, %loop ]
+ %acc.a.f64 = phi <vscale x 2 x double> [ splat(double 0.000000e+00), %entry ], [ %fadd.a.f64, %loop ]
+ %negated = mul i64 %iv, -1
+ %common.term.ptr = getelementptr inbounds nuw double, ptr %common.base, i64 %negated
+ %common.term = load <vscale x 2 x double>, ptr %common.term.ptr, align 8
+ %reversed = call <vscale x 2 x double> @llvm.vector.reverse.nxv2f64(<vscale x 2 x double> %common.term)
+ %src.gep = getelementptr inbounds nuw [4 x i16], ptr %src, i64 %iv
+ %bgra = call <vscale x 8 x i16> @llvm.masked.load(ptr %src.gep, <vscale x 8 x i1> %mask, <vscale x 8 x i16> zeroinitializer)
+ %deinterleave = tail call { <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16> } @llvm.vector.deinterleave4(<vscale x 8 x i16> %bgra)
+ %b.i16 = extractvalue { <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16> } %deinterleave, 0
+ %g.i16 = extractvalue { <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16> } %deinterleave, 1
+ %r.i16 = extractvalue { <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16> } %deinterleave, 2
+ %a.i16 = extractvalue { <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16>, <vscale x 2 x i16> } %deinterleave, 3
+ %b.f64 = uitofp <vscale x 2 x i16> %b.i16 to <vscale x 2 x double>
+ %g.f64 = uitofp <vscale x 2 x i16> %g.i16 to <vscale x 2 x double>
+ %r.f64 = uitofp <vscale x 2 x i16> %r.i16 to <vscale x 2 x double>
+ %a.f64 = uitofp <vscale x 2 x i16> %a.i16 to <vscale x 2 x double>
+ %b.mul.f64 = fmul <vscale x 2 x double> %b.f64, %reversed
+ %g.mul.f64 = fmul <vscale x 2 x double> %g.f64, %reversed
+ %r.mul.f64 = fmul <vscale x 2 x double> %r.f64, %reversed
+ %a.mul.f64 = fmul <vscale x 2 x double> %a.f64, %reversed
+ %fadd.b.f64 = fadd <vscale x 2 x double> %acc.b.f64, %b.mul.f64
+ %fadd.g.f64 = fadd <vscale x 2 x double> %acc.g.f64, %g.mul.f64
+ %fadd.r.f64 = fadd <vscale x 2 x double> %acc.r.f64, %r.mul.f64
+ %fadd.a.f64 = fadd <vscale x 2 x double> %acc.a.f64, %a.mul.f64
+ %iv.next = add nuw i64 %iv, %stride
+ %ec = icmp eq i64 %iv.next, 2048
+ br i1 %ec, label %exit, label %loop
----------------
gbossu wrote:
Ah I didn't realise that we used the deinterleave + extend as a source of tbl. In theory we could use a shufflevector as well to avoid using deinterleaving? Or maybe use 2-way deinterleaving to make the tests easier to read?
https://github.com/llvm/llvm-project/pull/206047
More information about the llvm-commits
mailing list