blob: e6ca6875e141263dd8f765979a335991994f22de [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,NODOT
; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,NODOT
; RUN: llc -mtriple=riscv32 -mattr=+v,+experimental-zvqdotq -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,DOT,DOT32
; RUN: llc -mtriple=riscv64 -mattr=+v,+experimental-zvqdotq -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,DOT,DOT64
define i32 @vqdot_vv(<16 x i8> %a, <16 x i8> %b) {
; NODOT-LABEL: vqdot_vv:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vsext.vf2 v14, v9
; NODOT-NEXT: vwmul.vv v8, v12, v14
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v12, zero
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vqdot_vx_constant(<16 x i8> %a) {
; CHECK-LABEL: vqdot_vx_constant:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vsext.vf2 v12, v8
; CHECK-NEXT: li a0, 23
; CHECK-NEXT: vwmul.vx v8, v12, a0
; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; CHECK-NEXT: vmv.s.x v12, zero
; CHECK-NEXT: vredsum.vs v8, v8, v12
; CHECK-NEXT: vmv.x.s a0, v8
; CHECK-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %a.sext, splat (i32 23)
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vqdot_vx_constant_swapped(<16 x i8> %a) {
; CHECK-LABEL: vqdot_vx_constant_swapped:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vsext.vf2 v12, v8
; CHECK-NEXT: li a0, 23
; CHECK-NEXT: vwmul.vx v8, v12, a0
; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; CHECK-NEXT: vmv.s.x v12, zero
; CHECK-NEXT: vredsum.vs v8, v8, v12
; CHECK-NEXT: vmv.x.s a0, v8
; CHECK-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> splat (i32 23), %a.sext
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vqdotu_vv(<16 x i8> %a, <16 x i8> %b) {
; NODOT-LABEL: vqdotu_vv:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; NODOT-NEXT: vwmulu.vv v10, v8, v9
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vsetvli zero, zero, e16, m2, ta, ma
; NODOT-NEXT: vwredsumu.vs v8, v10, v8
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotu_vv:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdotu.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.zext = zext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.zext, %b.zext
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vqdotu_vx_constant(<16 x i8> %a) {
; CHECK-LABEL: vqdotu_vx_constant:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vzext.vf2 v12, v8
; CHECK-NEXT: li a0, 123
; CHECK-NEXT: vwmulu.vx v8, v12, a0
; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; CHECK-NEXT: vmv.s.x v12, zero
; CHECK-NEXT: vredsum.vs v8, v8, v12
; CHECK-NEXT: vmv.x.s a0, v8
; CHECK-NEXT: ret
entry:
%a.zext = zext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %a.zext, splat (i32 123)
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vqdotsu_vv(<16 x i8> %a, <16 x i8> %b) {
; NODOT-LABEL: vqdotsu_vv:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vzext.vf2 v14, v9
; NODOT-NEXT: vwmulsu.vv v8, v12, v14
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v12, zero
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdotsu.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.zext
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vqdotsu_vv_swapped(<16 x i8> %a, <16 x i8> %b) {
; NODOT-LABEL: vqdotsu_vv_swapped:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vzext.vf2 v14, v9
; NODOT-NEXT: vwmulsu.vv v8, v12, v14
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v12, zero
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_swapped:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdotsu.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %b.zext, %a.sext
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vdotqsu_vx_constant(<16 x i8> %a) {
; CHECK-LABEL: vdotqsu_vx_constant:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vsext.vf2 v12, v8
; CHECK-NEXT: li a0, 123
; CHECK-NEXT: vwmul.vx v8, v12, a0
; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; CHECK-NEXT: vmv.s.x v12, zero
; CHECK-NEXT: vredsum.vs v8, v8, v12
; CHECK-NEXT: vmv.x.s a0, v8
; CHECK-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %a.sext, splat (i32 123)
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @vdotqus_vx_constant(<16 x i8> %a) {
; CHECK-LABEL: vdotqus_vx_constant:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vzext.vf2 v12, v8
; CHECK-NEXT: li a0, -23
; CHECK-NEXT: vmv.v.x v14, a0
; CHECK-NEXT: vwmulsu.vv v8, v14, v12
; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; CHECK-NEXT: vmv.s.x v12, zero
; CHECK-NEXT: vredsum.vs v8, v8, v12
; CHECK-NEXT: vmv.x.s a0, v8
; CHECK-NEXT: ret
entry:
%a.zext = zext <16 x i8> %a to <16 x i32>
%mul = mul <16 x i32> %a.zext, splat (i32 -23)
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
ret i32 %res
}
define i32 @reduce_of_sext(<16 x i8> %a) {
; NODOT-LABEL: reduce_of_sext:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vsext.vf4 v12, v8
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vredsum.vs v8, v12, v8
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: reduce_of_sext:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; DOT-NEXT: vmv.v.i v9, 1
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.ext = sext <16 x i8> %a to <16 x i32>
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %a.ext)
ret i32 %res
}
define i32 @reduce_of_zext(<16 x i8> %a) {
; NODOT-LABEL: reduce_of_zext:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vzext.vf4 v12, v8
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vredsum.vs v8, v12, v8
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: reduce_of_zext:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; DOT-NEXT: vmv.v.i v9, 1
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdotu.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.ext = zext <16 x i8> %a to <16 x i32>
%res = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %a.ext)
ret i32 %res
}
define i32 @vqdot_vv_accum(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; NODOT-LABEL: vqdot_vv_accum:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v10, v8
; NODOT-NEXT: vsext.vf2 v16, v9
; NODOT-NEXT: vwmacc.vv v12, v10, v16
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vredsum.vs v8, v12, v8
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_accum:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv1r.v v16, v12
; DOT-NEXT: vqdot.vv v16, v8, v9
; DOT-NEXT: vsetivli zero, 4, e32, m4, tu, ma
; DOT-NEXT: vmv.v.v v12, v16
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%add = add <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define i32 @vqdotu_vv_accum(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; NODOT-LABEL: vqdotu_vv_accum:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; NODOT-NEXT: vwmulu.vv v10, v8, v9
; NODOT-NEXT: vsetvli zero, zero, e16, m2, ta, ma
; NODOT-NEXT: vwaddu.wv v12, v12, v10
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vredsum.vs v8, v12, v8
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotu_vv_accum:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv1r.v v16, v12
; DOT-NEXT: vqdotu.vv v16, v8, v9
; DOT-NEXT: vsetivli zero, 4, e32, m4, tu, ma
; DOT-NEXT: vmv.v.v v12, v16
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.zext = zext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.zext, %b.zext
%add = add <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define i32 @vqdotsu_vv_accum(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; NODOT-LABEL: vqdotsu_vv_accum:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v10, v8
; NODOT-NEXT: vzext.vf2 v16, v9
; NODOT-NEXT: vwmaccsu.vv v12, v10, v16
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vredsum.vs v8, v12, v8
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_accum:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv1r.v v16, v12
; DOT-NEXT: vqdotsu.vv v16, v8, v9
; DOT-NEXT: vsetivli zero, 4, e32, m4, tu, ma
; DOT-NEXT: vmv.v.v v12, v16
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.zext
%add = add <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define i32 @vqdot_vv_scalar_add(<16 x i8> %a, <16 x i8> %b, i32 %x) {
; NODOT-LABEL: vqdot_vv_scalar_add:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vsext.vf2 v14, v9
; NODOT-NEXT: vwmul.vv v8, v12, v14
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v12, a0
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_scalar_add:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, a0
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
%add = add i32 %sum, %x
ret i32 %add
}
define i32 @vqdotu_vv_scalar_add(<16 x i8> %a, <16 x i8> %b, i32 %x) {
; NODOT-LABEL: vqdotu_vv_scalar_add:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; NODOT-NEXT: vwmulu.vv v10, v8, v9
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v8, a0
; NODOT-NEXT: vsetvli zero, zero, e16, m2, ta, ma
; NODOT-NEXT: vwredsumu.vs v8, v10, v8
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotu_vv_scalar_add:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdotu.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, a0
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.zext = zext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.zext, %b.zext
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
%add = add i32 %sum, %x
ret i32 %add
}
define i32 @vqdotsu_vv_scalar_add(<16 x i8> %a, <16 x i8> %b, i32 %x) {
; NODOT-LABEL: vqdotsu_vv_scalar_add:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vzext.vf2 v14, v9
; NODOT-NEXT: vwmulsu.vv v8, v12, v14
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v12, a0
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_scalar_add:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdotsu.vv v10, v8, v9
; DOT-NEXT: vmv.s.x v8, a0
; DOT-NEXT: vredsum.vs v8, v10, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.zext
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %mul)
%add = add i32 %sum, %x
ret i32 %add
}
define i32 @vqdot_vv_split(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c, <16 x i8> %d) {
; NODOT-LABEL: vqdot_vv_split:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vsext.vf2 v14, v9
; NODOT-NEXT: vsext.vf2 v16, v10
; NODOT-NEXT: vsext.vf2 v18, v11
; NODOT-NEXT: vwmul.vv v8, v12, v14
; NODOT-NEXT: vwmacc.vv v8, v16, v18
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v12, zero
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_split:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v12, 0
; DOT-NEXT: vqdot.vv v12, v8, v9
; DOT-NEXT: vqdot.vv v12, v10, v11
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%c.sext = sext <16 x i8> %c to <16 x i32>
%d.sext = sext <16 x i8> %d to <16 x i32>
%mul2 = mul <16 x i32> %c.sext, %d.sext
%add = add <16 x i32> %mul, %mul2
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define <1 x i32> @vqdot_vv_partial_reduce_v1i32_v4i8(<4 x i8> %a, <4 x i8> %b) {
; NODOT-LABEL: vqdot_vv_partial_reduce_v1i32_v4i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; NODOT-NEXT: vsext.vf2 v10, v8
; NODOT-NEXT: vsext.vf2 v8, v9
; NODOT-NEXT: vwmul.vv v9, v10, v8
; NODOT-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v9, 3
; NODOT-NEXT: vslidedown.vi v10, v9, 2
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v9
; NODOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v9, v9, 1
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v9, v9, v10
; NODOT-NEXT: vadd.vv v8, v9, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_partial_reduce_v1i32_v4i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; DOT-NEXT: vmv.s.x v10, zero
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv1r.v v8, v10
; DOT-NEXT: ret
entry:
%a.sext = sext <4 x i8> %a to <4 x i32>
%b.sext = sext <4 x i8> %b to <4 x i32>
%mul = mul <4 x i32> %a.sext, %b.sext
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <1 x i32> @vqdotu_vv_partial_reduce_v1i32_v4i8(<4 x i8> %a, <4 x i8> %b) {
; NODOT-LABEL: vqdotu_vv_partial_reduce_v1i32_v4i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
; NODOT-NEXT: vwmulu.vv v10, v8, v9
; NODOT-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; NODOT-NEXT: vzext.vf2 v8, v10
; NODOT-NEXT: vslidedown.vi v9, v8, 3
; NODOT-NEXT: vslidedown.vi v10, v8, 2
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v9, v9, v8
; NODOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v8, 1
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v10
; NODOT-NEXT: vadd.vv v8, v8, v9
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotu_vv_partial_reduce_v1i32_v4i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; DOT-NEXT: vmv.s.x v10, zero
; DOT-NEXT: vqdotu.vv v10, v8, v9
; DOT-NEXT: vmv1r.v v8, v10
; DOT-NEXT: ret
entry:
%a.sext = zext <4 x i8> %a to <4 x i32>
%b.sext = zext <4 x i8> %b to <4 x i32>
%mul = mul <4 x i32> %a.sext, %b.sext
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <1 x i32> @vqdotu_vx_partial_reduce(<4 x i8> %a, <4 x i8> %b) {
; NODOT-LABEL: vqdotu_vx_partial_reduce:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vzext.vf4 v9, v8
; NODOT-NEXT: vsll.vi v8, v9, 7
; NODOT-NEXT: vslidedown.vi v9, v8, 3
; NODOT-NEXT: vslidedown.vi v10, v8, 2
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v9, v9, v8
; NODOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v8, 1
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v10
; NODOT-NEXT: vadd.vv v8, v8, v9
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotu_vx_partial_reduce:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; DOT-NEXT: vmv.s.x v9, zero
; DOT-NEXT: li a0, 128
; DOT-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
; DOT-NEXT: vmv.v.x v10, a0
; DOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; DOT-NEXT: vqdotu.vv v9, v8, v10
; DOT-NEXT: vmv1r.v v8, v9
; DOT-NEXT: ret
entry:
%a.ext = zext <4 x i8> %a to <4 x i32>
%mul = mul <4 x i32> %a.ext, splat (i32 128)
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <1 x i32> @vqdot_vx_partial_reduce(<4 x i8> %a, <4 x i8> %b) {
; NODOT-LABEL: vqdot_vx_partial_reduce:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vsext.vf4 v9, v8
; NODOT-NEXT: vsll.vi v8, v9, 7
; NODOT-NEXT: vrsub.vi v8, v8, 0
; NODOT-NEXT: vslidedown.vi v9, v8, 3
; NODOT-NEXT: vslidedown.vi v10, v8, 2
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v9, v9, v8
; NODOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v8, 1
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v10
; NODOT-NEXT: vadd.vv v8, v8, v9
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vx_partial_reduce:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; DOT-NEXT: vmv.s.x v9, zero
; DOT-NEXT: li a0, 128
; DOT-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
; DOT-NEXT: vmv.v.x v10, a0
; DOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; DOT-NEXT: vqdot.vv v9, v8, v10
; DOT-NEXT: vmv1r.v v8, v9
; DOT-NEXT: ret
entry:
%a.ext = sext <4 x i8> %a to <4 x i32>
%mul = mul <4 x i32> %a.ext, splat (i32 -128)
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <1 x i32> @vqdotsu_vv_partial_reduce_v1i32_v4i8(<4 x i8> %a, <4 x i8> %b) {
; NODOT-LABEL: vqdotsu_vv_partial_reduce_v1i32_v4i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; NODOT-NEXT: vsext.vf2 v10, v8
; NODOT-NEXT: vzext.vf2 v8, v9
; NODOT-NEXT: vwmulsu.vv v9, v10, v8
; NODOT-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v9, 3
; NODOT-NEXT: vslidedown.vi v10, v9, 2
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v9
; NODOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v9, v9, 1
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v9, v9, v10
; NODOT-NEXT: vadd.vv v8, v9, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_partial_reduce_v1i32_v4i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; DOT-NEXT: vmv.s.x v10, zero
; DOT-NEXT: vqdotsu.vv v10, v8, v9
; DOT-NEXT: vmv1r.v v8, v10
; DOT-NEXT: ret
entry:
%a.sext = sext <4 x i8> %a to <4 x i32>
%b.sext = zext <4 x i8> %b to <4 x i32>
%mul = mul <4 x i32> %a.sext, %b.sext
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <1 x i32> @vqdotsu_vv_partial_reduce_swapped(<4 x i8> %a, <4 x i8> %b) {
; NODOT-LABEL: vqdotsu_vv_partial_reduce_swapped:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; NODOT-NEXT: vsext.vf2 v10, v8
; NODOT-NEXT: vzext.vf2 v8, v9
; NODOT-NEXT: vwmulsu.vv v9, v10, v8
; NODOT-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v9, 3
; NODOT-NEXT: vslidedown.vi v10, v9, 2
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v9
; NODOT-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v9, v9, 1
; NODOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v9, v9, v10
; NODOT-NEXT: vadd.vv v8, v9, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_partial_reduce_swapped:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; DOT-NEXT: vmv.s.x v10, zero
; DOT-NEXT: vqdotsu.vv v10, v8, v9
; DOT-NEXT: vmv1r.v v8, v10
; DOT-NEXT: ret
entry:
%a.ext = sext <4 x i8> %a to <4 x i32>
%b.ext = zext <4 x i8> %b to <4 x i32>
%mul = mul <4 x i32> %b.ext, %a.ext
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <1 x i32> @vqdotsu_vx_partial_reduce(<4 x i8> %a, <4 x i8> %b) {
; CHECK-LABEL: vqdotsu_vx_partial_reduce:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; CHECK-NEXT: vsext.vf4 v9, v8
; CHECK-NEXT: vsll.vi v8, v9, 7
; CHECK-NEXT: vslidedown.vi v9, v8, 3
; CHECK-NEXT: vslidedown.vi v10, v8, 2
; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v9, v9, v8
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; CHECK-NEXT: vslidedown.vi v8, v8, 1
; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v8, v8, v10
; CHECK-NEXT: vadd.vv v8, v8, v9
; CHECK-NEXT: ret
entry:
%a.ext = sext <4 x i8> %a to <4 x i32>
%mul = mul <4 x i32> %a.ext, splat (i32 128)
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <4 x i32> %mul)
ret <1 x i32> %res
}
define <2 x i32> @vqdot_vv_partial_reduce_v2i32_v8i8(<8 x i8> %a, <8 x i8> %b) {
; NODOT-LABEL: vqdot_vv_partial_reduce_v2i32_v8i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 8, e16, m1, ta, ma
; NODOT-NEXT: vsext.vf2 v10, v8
; NODOT-NEXT: vsext.vf2 v11, v9
; NODOT-NEXT: vwmul.vv v8, v10, v11
; NODOT-NEXT: vsetivli zero, 2, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v10, v8, 6
; NODOT-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v12, v10, v8
; NODOT-NEXT: vsetivli zero, 2, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v10, v8, 4
; NODOT-NEXT: vsetivli zero, 2, e32, m1, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v8, 2
; NODOT-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v10
; NODOT-NEXT: vadd.vv v8, v8, v12
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_partial_reduce_v2i32_v8i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv1r.v v8, v10
; DOT-NEXT: ret
entry:
%a.sext = sext <8 x i8> %a to <8 x i32>
%b.sext = sext <8 x i8> %b to <8 x i32>
%mul = mul <8 x i32> %a.sext, %b.sext
%res = call <2 x i32> @llvm.vector.partial.reduce.add(<2 x i32> zeroinitializer, <8 x i32> %mul)
ret <2 x i32> %res
}
define <2 x i32> @vqdot_vv_partial_reduce_v2i32_v64i8(<64 x i8> %a, <64 x i8> %b) {
; CHECK-LABEL: vqdot_vv_partial_reduce_v2i32_v64i8:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -16
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a1, a0, 2
; CHECK-NEXT: add a0, a1, a0
; CHECK-NEXT: sub sp, sp, a0
; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x05, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 5 * vlenb
; CHECK-NEXT: li a0, 32
; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; CHECK-NEXT: vsext.vf2 v24, v8
; CHECK-NEXT: vsext.vf2 v28, v12
; CHECK-NEXT: vwmul.vv v16, v24, v28
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v16, 28
; CHECK-NEXT: vslidedown.vi v0, v16, 26
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v24, v0, v24
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 2
; CHECK-NEXT: add a1, sp, a1
; CHECK-NEXT: addi a1, a1, 16
; CHECK-NEXT: vs1r.v v24, (a1) # vscale x 8-byte Folded Spill
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v0, v16, 24
; CHECK-NEXT: vslidedown.vi v24, v16, 22
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v24, v24, v0
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a2, a1, 1
; CHECK-NEXT: add a1, a2, a1
; CHECK-NEXT: add a1, sp, a1
; CHECK-NEXT: addi a1, a1, 16
; CHECK-NEXT: vs1r.v v24, (a1) # vscale x 8-byte Folded Spill
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v0, v16, 20
; CHECK-NEXT: vslidedown.vi v24, v16, 18
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v24, v24, v0
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: add a1, sp, a1
; CHECK-NEXT: addi a1, a1, 16
; CHECK-NEXT: vs1r.v v24, (a1) # vscale x 8-byte Folded Spill
; CHECK-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; CHECK-NEXT: vslidedown.vx v8, v8, a0
; CHECK-NEXT: vslidedown.vx v12, v12, a0
; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; CHECK-NEXT: vsext.vf2 v24, v8
; CHECK-NEXT: vsext.vf2 v28, v12
; CHECK-NEXT: vwmul.vv v8, v24, v28
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v0, v8, 28
; CHECK-NEXT: vslidedown.vi v24, v8, 26
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v24, v24, v0
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: add a0, sp, a0
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: vs1r.v v24, (a0) # vscale x 8-byte Folded Spill
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v8, 24
; CHECK-NEXT: vslidedown.vi v0, v8, 22
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v24, v0, v24
; CHECK-NEXT: addi a0, sp, 16
; CHECK-NEXT: vs1r.v v24, (a0) # vscale x 8-byte Folded Spill
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v8, 20
; CHECK-NEXT: vslidedown.vi v0, v8, 18
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v7, v0, v24
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v16, 16
; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma
; CHECK-NEXT: vslidedown.vi v28, v16, 14
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v6, v28, v24
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v8, 16
; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma
; CHECK-NEXT: vslidedown.vi v28, v8, 14
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v5, v28, v24
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v16, 30
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v4, v24, v16
; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma
; CHECK-NEXT: vslidedown.vi v20, v16, 12
; CHECK-NEXT: vslidedown.vi v24, v16, 10
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v3, v24, v20
; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
; CHECK-NEXT: vslidedown.vi v24, v8, 30
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v24, v24, v8
; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma
; CHECK-NEXT: vslidedown.vi v12, v8, 12
; CHECK-NEXT: vslidedown.vi v20, v8, 10
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v25, v20, v12
; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
; CHECK-NEXT: vslidedown.vi v20, v16, 6
; CHECK-NEXT: vslidedown.vi v22, v16, 4
; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma
; CHECK-NEXT: vslidedown.vi v21, v16, 2
; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma
; CHECK-NEXT: vslidedown.vi v12, v16, 8
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v16, v20, v12
; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
; CHECK-NEXT: vslidedown.vi v12, v8, 6
; CHECK-NEXT: vslidedown.vi v14, v8, 4
; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma
; CHECK-NEXT: vslidedown.vi v13, v8, 2
; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma
; CHECK-NEXT: vslidedown.vi v8, v8, 8
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v8, v12, v8
; CHECK-NEXT: vadd.vv v9, v21, v22
; CHECK-NEXT: vadd.vv v10, v13, v14
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 2
; CHECK-NEXT: add a0, sp, a0
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: vl1r.v v11, (a0) # vscale x 8-byte Folded Reload
; CHECK-NEXT: vadd.vv v11, v11, v4
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a1, a0, 1
; CHECK-NEXT: add a0, a1, a0
; CHECK-NEXT: add a0, sp, a0
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: vl1r.v v12, (a0) # vscale x 8-byte Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: add a0, sp, a0
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: vl1r.v v13, (a0) # vscale x 8-byte Folded Reload
; CHECK-NEXT: vadd.vv v12, v13, v12
; CHECK-NEXT: vadd.vv v13, v3, v6
; CHECK-NEXT: vadd.vv v9, v9, v16
; CHECK-NEXT: vadd.vv v11, v12, v11
; CHECK-NEXT: vadd.vv v9, v9, v13
; CHECK-NEXT: addi a0, sp, 16
; CHECK-NEXT: vl1r.v v12, (a0) # vscale x 8-byte Folded Reload
; CHECK-NEXT: vadd.vv v12, v7, v12
; CHECK-NEXT: vadd.vv v13, v25, v5
; CHECK-NEXT: vadd.vv v8, v10, v8
; CHECK-NEXT: vadd.vv v9, v9, v11
; CHECK-NEXT: vadd.vv v9, v24, v9
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: add a0, sp, a0
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: vl1r.v v10, (a0) # vscale x 8-byte Folded Reload
; CHECK-NEXT: vadd.vv v9, v10, v9
; CHECK-NEXT: vadd.vv v9, v12, v9
; CHECK-NEXT: vadd.vv v8, v8, v13
; CHECK-NEXT: vadd.vv v8, v8, v9
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a1, a0, 2
; CHECK-NEXT: add a0, a1, a0
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: .cfi_def_cfa sp, 16
; CHECK-NEXT: addi sp, sp, 16
; CHECK-NEXT: .cfi_def_cfa_offset 0
; CHECK-NEXT: ret
entry:
%a.sext = sext <64 x i8> %a to <64 x i32>
%b.sext = sext <64 x i8> %b to <64 x i32>
%mul = mul <64 x i32> %a.sext, %b.sext
%res = call <2 x i32> @llvm.vector.partial.reduce.add(<2 x i32> zeroinitializer, <64 x i32> %mul)
ret <2 x i32> %res
}
define <4 x i32> @vqdot_vv_partial_reduce_v4i32_v16i8(<16 x i8> %a, <16 x i8> %b) {
; NODOT-LABEL: vqdot_vv_partial_reduce_v4i32_v16i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v8
; NODOT-NEXT: vsext.vf2 v14, v9
; NODOT-NEXT: vwmul.vv v8, v12, v14
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v12, v8, 12
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v16, v12, v8
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v12, v8, 8
; NODOT-NEXT: vsetivli zero, 4, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v8, 4
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v12
; NODOT-NEXT: vadd.vv v8, v8, v16
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_partial_reduce_v4i32_v16i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 0
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv.v.v v8, v10
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%res = call <4 x i32> @llvm.vector.partial.reduce.add(<4 x i32> zeroinitializer, <16 x i32> %mul)
ret <4 x i32> %res
}
define <16 x i32> @vqdot_vv_partial_reduce_v16i32_v64i8(<64 x i8> %a, <64 x i8> %b) {
; NODOT-LABEL: vqdot_vv_partial_reduce_v16i32_v64i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: li a0, 32
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v16, v8
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v8, v8, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v20, v12
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v12, v12, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v24, v8
; NODOT-NEXT: vsext.vf2 v28, v12
; NODOT-NEXT: vwmul.vv v8, v16, v20
; NODOT-NEXT: vwmul.vv v16, v24, v28
; NODOT-NEXT: vsetivli zero, 16, e32, m8, ta, ma
; NODOT-NEXT: vslidedown.vi v24, v8, 16
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vadd.vv v8, v24, v8
; NODOT-NEXT: vadd.vv v24, v8, v16
; NODOT-NEXT: vsetivli zero, 16, e32, m8, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v16, 16
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v24
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_partial_reduce_v16i32_v64i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vmv.v.i v16, 0
; DOT-NEXT: vqdot.vv v16, v8, v12
; DOT-NEXT: vmv.v.v v8, v16
; DOT-NEXT: ret
entry:
%a.sext = sext <64 x i8> %a to <64 x i32>
%b.sext = sext <64 x i8> %b to <64 x i32>
%mul = mul <64 x i32> %a.sext, %b.sext
%res = call <16 x i32> @llvm.vector.partial.reduce.add(<16 x i32> zeroinitializer, <64 x i32> %mul)
ret <16 x i32> %res
}
define <4 x i32> @vqdot_vv_partial_reduce_m1_accum(<16 x i8> %a, <16 x i8> %b, <4 x i32> %accum) {
; NODOT-LABEL: vqdot_vv_partial_reduce_m1_accum:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v16, v8
; NODOT-NEXT: vsext.vf2 v18, v9
; NODOT-NEXT: vwmul.vv v12, v16, v18
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v16, v10, v12
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v12, 12
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v16, v8, v16
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v12, 8
; NODOT-NEXT: vsetivli zero, 4, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v10, v12, 4
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v8, v10, v8
; NODOT-NEXT: vadd.vv v8, v8, v16
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_partial_reduce_m1_accum:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vqdot.vv v10, v8, v9
; DOT-NEXT: vmv.v.v v8, v10
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%res = call <4 x i32> @llvm.vector.partial.reduce.add(<4 x i32> %accum, <16 x i32> %mul)
ret <4 x i32> %res
}
define <16 x i32> @vqdot_vv_partial_reduce3(<16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: vqdot_vv_partial_reduce3:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vsext.vf2 v12, v8
; CHECK-NEXT: vsext.vf2 v14, v9
; CHECK-NEXT: vwmul.vv v8, v12, v14
; CHECK-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%res = call <16 x i32> @llvm.vector.partial.reduce.add.nvx8i32.nvx16i32.nvx16i32(<16 x i32> %mul, <16 x i32> zeroinitializer)
ret <16 x i32> %res
}
; Test legalization - type split
define <64 x i32> @vqdotsu_vv_partial_v64i32_v256i8(<256 x i8> %a, <256 x i8> %b) {
; NODOT-LABEL: vqdotsu_vv_partial_v64i32_v256i8:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: addi sp, sp, -16
; NODOT-NEXT: .cfi_def_cfa_offset 16
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 3
; NODOT-NEXT: mv a2, a1
; NODOT-NEXT: slli a1, a1, 2
; NODOT-NEXT: add a1, a1, a2
; NODOT-NEXT: sub sp, sp, a1
; NODOT-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x28, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 40 * vlenb
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 4
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vs8r.v v16, (a1) # vscale x 64-byte Folded Spill
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 5
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vs8r.v v8, (a1) # vscale x 64-byte Folded Spill
; NODOT-NEXT: addi a1, a0, 128
; NODOT-NEXT: li a2, 128
; NODOT-NEXT: vsetvli zero, a2, e8, m8, ta, ma
; NODOT-NEXT: vle8.v v0, (a0)
; NODOT-NEXT: csrr a0, vlenb
; NODOT-NEXT: slli a0, a0, 3
; NODOT-NEXT: mv a3, a0
; NODOT-NEXT: slli a0, a0, 1
; NODOT-NEXT: add a0, a0, a3
; NODOT-NEXT: add a0, sp, a0
; NODOT-NEXT: addi a0, a0, 16
; NODOT-NEXT: vs8r.v v0, (a0) # vscale x 64-byte Folded Spill
; NODOT-NEXT: li a0, 32
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v24, v8, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v8, v24
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v12, v0, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vzext.vf2 v4, v12
; NODOT-NEXT: vwmulsu.vv v24, v8, v4
; NODOT-NEXT: csrr a3, vlenb
; NODOT-NEXT: slli a3, a3, 5
; NODOT-NEXT: add a3, sp, a3
; NODOT-NEXT: addi a3, a3, 16
; NODOT-NEXT: vl8r.v v8, (a3) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vsext.vf2 v4, v8
; NODOT-NEXT: csrr a3, vlenb
; NODOT-NEXT: slli a3, a3, 3
; NODOT-NEXT: mv a4, a3
; NODOT-NEXT: slli a3, a3, 1
; NODOT-NEXT: add a3, a3, a4
; NODOT-NEXT: add a3, sp, a3
; NODOT-NEXT: addi a3, a3, 16
; NODOT-NEXT: vl8r.v v8, (a3) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vzext.vf2 v0, v8
; NODOT-NEXT: vsetvli zero, a2, e8, m8, ta, ma
; NODOT-NEXT: vle8.v v8, (a1)
; NODOT-NEXT: addi a1, sp, 16
; NODOT-NEXT: vs8r.v v8, (a1) # vscale x 64-byte Folded Spill
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vwmaccsu.vv v24, v4, v0
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v4, v16, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v4
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v4, v8, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vzext.vf2 v16, v4
; NODOT-NEXT: vwmulsu.vv v0, v12, v16
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 4
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl8r.v v16, (a1) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vsext.vf2 v12, v16
; NODOT-NEXT: vzext.vf2 v20, v8
; NODOT-NEXT: vwmaccsu.vv v0, v12, v20
; NODOT-NEXT: li a1, 64
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 5
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vl8r.v v16, (a2) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vsetvli zero, a1, e8, m8, ta, ma
; NODOT-NEXT: vslidedown.vx v8, v16, a1
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 5
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vs8r.v v8, (a2) # vscale x 64-byte Folded Spill
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 3
; NODOT-NEXT: mv a3, a2
; NODOT-NEXT: slli a2, a2, 1
; NODOT-NEXT: add a2, a2, a3
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vl8r.v v16, (a2) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vslidedown.vx v8, v16, a1
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 3
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vs8r.v v8, (a2) # vscale x 64-byte Folded Spill
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 5
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vl8r.v v8, (a2) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v16, v8
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 3
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vl8r.v v8, (a2) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vzext.vf2 v20, v8
; NODOT-NEXT: vwmaccsu.vv v24, v16, v20
; NODOT-NEXT: csrr a2, vlenb
; NODOT-NEXT: slli a2, a2, 4
; NODOT-NEXT: add a2, sp, a2
; NODOT-NEXT: addi a2, a2, 16
; NODOT-NEXT: vl8r.v v16, (a2) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vsetvli zero, a1, e8, m8, ta, ma
; NODOT-NEXT: vslidedown.vx v16, v16, a1
; NODOT-NEXT: addi a2, sp, 16
; NODOT-NEXT: vl8r.v v8, (a2) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vslidedown.vx v8, v8, a1
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 3
; NODOT-NEXT: mv a2, a1
; NODOT-NEXT: slli a1, a1, 1
; NODOT-NEXT: add a1, a1, a2
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vs8r.v v8, (a1) # vscale x 64-byte Folded Spill
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v8, v16
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 4
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vs4r.v v8, (a1) # vscale x 32-byte Folded Spill
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 3
; NODOT-NEXT: mv a2, a1
; NODOT-NEXT: slli a1, a1, 1
; NODOT-NEXT: add a1, a1, a2
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl8r.v v8, (a1) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vzext.vf2 v20, v8
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 4
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl4r.v v8, (a1) # vscale x 32-byte Folded Reload
; NODOT-NEXT: vwmaccsu.vv v0, v8, v20
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 5
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl8r.v v8, (a1) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v20, v8, a0
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 3
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl8r.v v8, (a1) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vslidedown.vx v8, v8, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v12, v20
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 5
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vs4r.v v12, (a1) # vscale x 32-byte Folded Spill
; NODOT-NEXT: vzext.vf2 v12, v8
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 5
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl4r.v v8, (a1) # vscale x 32-byte Folded Reload
; NODOT-NEXT: vwmaccsu.vv v24, v8, v12
; NODOT-NEXT: vsetvli zero, a0, e8, m4, ta, ma
; NODOT-NEXT: vslidedown.vx v12, v16, a0
; NODOT-NEXT: csrr a1, vlenb
; NODOT-NEXT: slli a1, a1, 3
; NODOT-NEXT: mv a2, a1
; NODOT-NEXT: slli a1, a1, 1
; NODOT-NEXT: add a1, a1, a2
; NODOT-NEXT: add a1, sp, a1
; NODOT-NEXT: addi a1, a1, 16
; NODOT-NEXT: vl8r.v v16, (a1) # vscale x 64-byte Folded Reload
; NODOT-NEXT: vslidedown.vx v8, v16, a0
; NODOT-NEXT: vsetvli zero, a0, e16, m4, ta, ma
; NODOT-NEXT: vsext.vf2 v16, v12
; NODOT-NEXT: vzext.vf2 v12, v8
; NODOT-NEXT: vwmaccsu.vv v0, v16, v12
; NODOT-NEXT: vmv8r.v v8, v24
; NODOT-NEXT: vmv8r.v v16, v0
; NODOT-NEXT: csrr a0, vlenb
; NODOT-NEXT: slli a0, a0, 3
; NODOT-NEXT: mv a1, a0
; NODOT-NEXT: slli a0, a0, 2
; NODOT-NEXT: add a0, a0, a1
; NODOT-NEXT: add sp, sp, a0
; NODOT-NEXT: .cfi_def_cfa sp, 16
; NODOT-NEXT: addi sp, sp, 16
; NODOT-NEXT: .cfi_def_cfa_offset 0
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_partial_v64i32_v256i8:
; DOT: # %bb.0: # %entry
; DOT-NEXT: addi sp, sp, -16
; DOT-NEXT: .cfi_def_cfa_offset 16
; DOT-NEXT: csrr a1, vlenb
; DOT-NEXT: slli a1, a1, 5
; DOT-NEXT: sub sp, sp, a1
; DOT-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x20, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 32 * vlenb
; DOT-NEXT: csrr a1, vlenb
; DOT-NEXT: slli a1, a1, 3
; DOT-NEXT: mv a2, a1
; DOT-NEXT: slli a1, a1, 1
; DOT-NEXT: add a1, a1, a2
; DOT-NEXT: add a1, sp, a1
; DOT-NEXT: addi a1, a1, 16
; DOT-NEXT: vs8r.v v16, (a1) # vscale x 64-byte Folded Spill
; DOT-NEXT: csrr a1, vlenb
; DOT-NEXT: slli a1, a1, 4
; DOT-NEXT: add a1, sp, a1
; DOT-NEXT: addi a1, a1, 16
; DOT-NEXT: vs8r.v v8, (a1) # vscale x 64-byte Folded Spill
; DOT-NEXT: addi a1, a0, 128
; DOT-NEXT: li a2, 128
; DOT-NEXT: vsetvli zero, a2, e8, m8, ta, ma
; DOT-NEXT: vle8.v v8, (a0)
; DOT-NEXT: csrr a0, vlenb
; DOT-NEXT: slli a0, a0, 3
; DOT-NEXT: add a0, sp, a0
; DOT-NEXT: addi a0, a0, 16
; DOT-NEXT: vs8r.v v8, (a0) # vscale x 64-byte Folded Spill
; DOT-NEXT: li a0, 32
; DOT-NEXT: vle8.v v8, (a1)
; DOT-NEXT: addi a1, sp, 16
; DOT-NEXT: vs8r.v v8, (a1) # vscale x 64-byte Folded Spill
; DOT-NEXT: vsetvli zero, a0, e32, m8, ta, ma
; DOT-NEXT: vmv.v.i v24, 0
; DOT-NEXT: vmv.v.i v0, 0
; DOT-NEXT: csrr a0, vlenb
; DOT-NEXT: slli a0, a0, 4
; DOT-NEXT: add a0, sp, a0
; DOT-NEXT: addi a0, a0, 16
; DOT-NEXT: vl8r.v v16, (a0) # vscale x 64-byte Folded Reload
; DOT-NEXT: csrr a0, vlenb
; DOT-NEXT: slli a0, a0, 3
; DOT-NEXT: add a0, sp, a0
; DOT-NEXT: addi a0, a0, 16
; DOT-NEXT: vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
; DOT-NEXT: vqdotsu.vv v0, v16, v8
; DOT-NEXT: csrr a0, vlenb
; DOT-NEXT: slli a0, a0, 3
; DOT-NEXT: mv a1, a0
; DOT-NEXT: slli a0, a0, 1
; DOT-NEXT: add a0, a0, a1
; DOT-NEXT: add a0, sp, a0
; DOT-NEXT: addi a0, a0, 16
; DOT-NEXT: vl8r.v v16, (a0) # vscale x 64-byte Folded Reload
; DOT-NEXT: addi a0, sp, 16
; DOT-NEXT: vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
; DOT-NEXT: vqdotsu.vv v24, v16, v8
; DOT-NEXT: vmv.v.v v8, v0
; DOT-NEXT: vmv.v.v v16, v24
; DOT-NEXT: csrr a0, vlenb
; DOT-NEXT: slli a0, a0, 5
; DOT-NEXT: add sp, sp, a0
; DOT-NEXT: .cfi_def_cfa sp, 16
; DOT-NEXT: addi sp, sp, 16
; DOT-NEXT: .cfi_def_cfa_offset 0
; DOT-NEXT: ret
entry:
%a.ext = sext <256 x i8> %a to <256 x i32>
%b.ext = zext <256 x i8> %b to <256 x i32>
%mul = mul <256 x i32> %b.ext, %a.ext
%res = call <64 x i32> @llvm.vector.partial.reduce.add(<64 x i32> zeroinitializer, <256 x i32> %mul)
ret <64 x i32> %res
}
; Test legalization - integer promote
define <4 x i31> @vqdotsu_vv_partial_v4i31_v16i7(<16 x i7> %a, <16 x i7> %b) {
; NODOT-LABEL: vqdotsu_vv_partial_v4i31_v16i7:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vzext.vf4 v12, v8
; NODOT-NEXT: li a0, 127
; NODOT-NEXT: vsetvli zero, zero, e8, m1, ta, ma
; NODOT-NEXT: vand.vx v16, v9, a0
; NODOT-NEXT: lui a0, 524288
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vsll.vi v8, v12, 25
; NODOT-NEXT: addi a0, a0, -1
; NODOT-NEXT: vsra.vi v8, v8, 25
; NODOT-NEXT: vzext.vf4 v12, v16
; NODOT-NEXT: vmul.vv v8, v12, v8
; NODOT-NEXT: vand.vx v8, v8, a0
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v12, v8, 12
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v16, v12, v8
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v12, v8, 8
; NODOT-NEXT: vsetivli zero, 4, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v8, 4
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v8, v8, v12
; NODOT-NEXT: vadd.vv v8, v8, v16
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_partial_v4i31_v16i7:
; DOT: # %bb.0: # %entry
; DOT-NEXT: li a0, 127
; DOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; DOT-NEXT: vadd.vv v8, v8, v8
; DOT-NEXT: vand.vx v9, v9, a0
; DOT-NEXT: vsra.vi v10, v8, 1
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v8, 0
; DOT-NEXT: vqdotsu.vv v8, v10, v9
; DOT-NEXT: ret
entry:
%a.ext = sext <16 x i7> %a to <16 x i31>
%b.ext = zext <16 x i7> %b to <16 x i31>
%mul = mul <16 x i31> %b.ext, %a.ext
%res = call <4 x i31> @llvm.vector.partial.reduce.add(<4 x i31> zeroinitializer, <16 x i31> %mul)
ret <4 x i31> %res
}
; Test legalization - expand
define <1 x i32> @vqdotsu_vv_partial_v1i32_v2i8(<2 x i8> %a, <2 x i8> %b) {
; CHECK-LABEL: vqdotsu_vv_partial_v1i32_v2i8:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
; CHECK-NEXT: vsext.vf2 v10, v8
; CHECK-NEXT: vzext.vf2 v8, v9
; CHECK-NEXT: vwmulsu.vv v9, v10, v8
; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
; CHECK-NEXT: vslidedown.vi v8, v9, 1
; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v8, v8, v9
; CHECK-NEXT: ret
entry:
%a.ext = sext <2 x i8> %a to <2 x i32>
%b.ext = zext <2 x i8> %b to <2 x i32>
%mul = mul <2 x i32> %b.ext, %a.ext
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <2 x i32> %mul)
ret <1 x i32> %res
}
; TODO: This isn't legal, but we could split it into two halves, and use
; a pair of slides + two vqdotsu_vv here. Or alternatively, the mul
; sequence + one vredsum, or a vadd reduce tree.
define <1 x i32> @vqdotsu_vv_partial_v1i32_v8i8(<8 x i8> %a, <8 x i8> %b) {
; CHECK-LABEL: vqdotsu_vv_partial_v1i32_v8i8:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
; CHECK-NEXT: vsext.vf2 v10, v8
; CHECK-NEXT: vzext.vf2 v11, v9
; CHECK-NEXT: vwmulsu.vv v8, v10, v11
; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma
; CHECK-NEXT: vslidedown.vi v10, v8, 6
; CHECK-NEXT: vslidedown.vi v12, v8, 5
; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v12, v12, v10
; CHECK-NEXT: vsetivli zero, 1, e32, m2, ta, ma
; CHECK-NEXT: vslidedown.vi v10, v8, 7
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; CHECK-NEXT: vslidedown.vi v11, v8, 3
; CHECK-NEXT: vslidedown.vi v13, v8, 2
; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v10, v10, v8
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
; CHECK-NEXT: vslidedown.vi v14, v8, 1
; CHECK-NEXT: vsetivli zero, 1, e32, m2, ta, ma
; CHECK-NEXT: vslidedown.vi v8, v8, 4
; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; CHECK-NEXT: vadd.vv v8, v11, v8
; CHECK-NEXT: vadd.vv v9, v14, v13
; CHECK-NEXT: vadd.vv v10, v12, v10
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vadd.vv v8, v8, v10
; CHECK-NEXT: ret
entry:
%a.ext = sext <8 x i8> %a to <8 x i32>
%b.ext = zext <8 x i8> %b to <8 x i32>
%mul = mul <8 x i32> %b.ext, %a.ext
%res = call <1 x i32> @llvm.vector.partial.reduce.add(<1 x i32> zeroinitializer, <8 x i32> %mul)
ret <1 x i32> %res
}
define <4 x i32> @partial_of_sext(<16 x i8> %a) {
; NODOT-LABEL: partial_of_sext:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vsext.vf4 v12, v8
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v12, 12
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v16, v8, v12
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v12, 8
; NODOT-NEXT: vsetivli zero, 4, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v10, v12, 4
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v8, v10, v8
; NODOT-NEXT: vadd.vv v8, v8, v16
; NODOT-NEXT: ret
;
; DOT-LABEL: partial_of_sext:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 1
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v9, 0
; DOT-NEXT: vqdot.vv v9, v8, v10
; DOT-NEXT: vmv.v.v v8, v9
; DOT-NEXT: ret
entry:
%a.ext = sext <16 x i8> %a to <16 x i32>
%res = call <4 x i32> @llvm.vector.partial.reduce.add(<4 x i32> zeroinitializer, <16 x i32> %a.ext)
ret <4 x i32> %res
}
define <4 x i32> @partial_of_zext(<16 x i8> %a) {
; NODOT-LABEL: partial_of_zext:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; NODOT-NEXT: vzext.vf4 v12, v8
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v12, 12
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v16, v8, v12
; NODOT-NEXT: vsetivli zero, 4, e32, m4, ta, ma
; NODOT-NEXT: vslidedown.vi v8, v12, 8
; NODOT-NEXT: vsetivli zero, 4, e32, m2, ta, ma
; NODOT-NEXT: vslidedown.vi v10, v12, 4
; NODOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; NODOT-NEXT: vadd.vv v8, v10, v8
; NODOT-NEXT: vadd.vv v8, v8, v16
; NODOT-NEXT: ret
;
; DOT-LABEL: partial_of_zext:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; DOT-NEXT: vmv.v.i v10, 1
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv.v.i v9, 0
; DOT-NEXT: vqdotu.vv v9, v8, v10
; DOT-NEXT: vmv.v.v v8, v9
; DOT-NEXT: ret
entry:
%a.ext = zext <16 x i8> %a to <16 x i32>
%res = call <4 x i32> @llvm.vector.partial.reduce.add(<4 x i32> zeroinitializer, <16 x i32> %a.ext)
ret <4 x i32> %res
}
define i32 @vqdot_vv_accum_disjoint_or(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; NODOT-LABEL: vqdot_vv_accum_disjoint_or:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v16, v8
; NODOT-NEXT: vsext.vf2 v18, v9
; NODOT-NEXT: vwmul.vv v8, v16, v18
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vor.vv v8, v8, v12
; NODOT-NEXT: vmv.s.x v12, zero
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdot_vv_accum_disjoint_or:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv1r.v v16, v12
; DOT-NEXT: vqdot.vv v16, v8, v9
; DOT-NEXT: vsetivli zero, 4, e32, m4, tu, ma
; DOT-NEXT: vmv.v.v v12, v16
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%add = or disjoint <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define i32 @vqdot_vv_accum_or(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; CHECK-LABEL: vqdot_vv_accum_or:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; CHECK-NEXT: vsext.vf2 v16, v8
; CHECK-NEXT: vsext.vf2 v18, v9
; CHECK-NEXT: vwmul.vv v8, v16, v18
; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; CHECK-NEXT: vor.vv v8, v8, v12
; CHECK-NEXT: vmv.s.x v12, zero
; CHECK-NEXT: vredsum.vs v8, v8, v12
; CHECK-NEXT: vmv.x.s a0, v8
; CHECK-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.sext = sext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.sext
%add = or <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define i32 @vqdotu_vv_accum_disjoint_or(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; NODOT-LABEL: vqdotu_vv_accum_disjoint_or:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; NODOT-NEXT: vwmulu.vv v10, v8, v9
; NODOT-NEXT: vsetvli zero, zero, e16, m2, ta, ma
; NODOT-NEXT: vwaddu.wv v12, v12, v10
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vmv.s.x v8, zero
; NODOT-NEXT: vredsum.vs v8, v12, v8
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotu_vv_accum_disjoint_or:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv1r.v v16, v12
; DOT-NEXT: vqdotu.vv v16, v8, v9
; DOT-NEXT: vsetivli zero, 4, e32, m4, tu, ma
; DOT-NEXT: vmv.v.v v12, v16
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.zext = zext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.zext, %b.zext
%add = or disjoint <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
define i32 @vqdotsu_vv_accum_disjoint_or(<16 x i8> %a, <16 x i8> %b, <16 x i32> %x) {
; NODOT-LABEL: vqdotsu_vv_accum_disjoint_or:
; NODOT: # %bb.0: # %entry
; NODOT-NEXT: vsetivli zero, 16, e16, m2, ta, ma
; NODOT-NEXT: vsext.vf2 v16, v8
; NODOT-NEXT: vzext.vf2 v18, v9
; NODOT-NEXT: vwmulsu.vv v8, v16, v18
; NODOT-NEXT: vsetvli zero, zero, e32, m4, ta, ma
; NODOT-NEXT: vor.vv v8, v8, v12
; NODOT-NEXT: vmv.s.x v12, zero
; NODOT-NEXT: vredsum.vs v8, v8, v12
; NODOT-NEXT: vmv.x.s a0, v8
; NODOT-NEXT: ret
;
; DOT-LABEL: vqdotsu_vv_accum_disjoint_or:
; DOT: # %bb.0: # %entry
; DOT-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; DOT-NEXT: vmv1r.v v16, v12
; DOT-NEXT: vqdotsu.vv v16, v8, v9
; DOT-NEXT: vsetivli zero, 4, e32, m4, tu, ma
; DOT-NEXT: vmv.v.v v12, v16
; DOT-NEXT: vmv.s.x v8, zero
; DOT-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; DOT-NEXT: vredsum.vs v8, v12, v8
; DOT-NEXT: vmv.x.s a0, v8
; DOT-NEXT: ret
entry:
%a.sext = sext <16 x i8> %a to <16 x i32>
%b.zext = zext <16 x i8> %b to <16 x i32>
%mul = mul <16 x i32> %a.sext, %b.zext
%add = or disjoint <16 x i32> %mul, %x
%sum = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %sum
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; DOT32: {{.*}}
; DOT64: {{.*}}