; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -mattr=+v,+zvfhmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32 ; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfhmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64 ; RUN: llc -mtriple=riscv32 -mattr=+v,+zvfhmin,+zvfbfmin,+experimental-zvzip -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ZVZIP,ZVZIP-RV32 ; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfhmin,+zvfbfmin,+experimental-zvzip -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ZVZIP,ZVZIP-RV64 define <4 x i32> @zipeven_v4i32(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: zipeven_v4i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vslideup.vi v8, v9, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4i32: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpaire.vv v10, v8, v9 ; ZVZIP-NEXT: vmv.v.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> ret <4 x i32> %c } define <4 x i32> @zipeven_v4i32_swapped(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: zipeven_v4i32_swapped: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vslideup.vi v9, v8, 1, v0.t ; CHECK-NEXT: vmv.v.v v8, v9 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4i32_swapped: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpaire.vv v10, v9, v8 ; ZVZIP-NEXT: vmv.v.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> ret <4 x i32> %c } define <4 x i64> @zipeven_v4i64(<4 x i64> %a, <4 x i64> %b) { ; CHECK-LABEL: zipeven_v4i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 1, e8, mf8, ta, ma ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, mu ; CHECK-NEXT: vslideup.vi v8, v10, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4i64: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e64, m2, ta, ma ; ZVZIP-NEXT: vpaire.vv v12, v8, v10 ; ZVZIP-NEXT: vmv.v.v v8, v12 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> ret <4 x i64> %c } define <4 x half> @zipeven_v4f16(<4 x half> %a, <4 x half> %b) { ; CHECK-LABEL: zipeven_v4f16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, mu ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vslideup.vi v8, v9, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4f16: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e16, mf2, ta, ma ; ZVZIP-NEXT: vpaire.vv v10, v8, v9 ; ZVZIP-NEXT: vmv1r.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x half> %a, <4 x half> %b, <4 x i32> ret <4 x half> %c } define <4 x bfloat> @zipeven_v4bf16(<4 x bfloat> %a, <4 x bfloat> %b) { ; CHECK-LABEL: zipeven_v4bf16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, mu ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vslideup.vi v8, v9, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4bf16: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e16, mf2, ta, ma ; ZVZIP-NEXT: vpaire.vv v10, v8, v9 ; ZVZIP-NEXT: vmv1r.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x bfloat> %a, <4 x bfloat> %b, <4 x i32> ret <4 x bfloat> %c } define <4 x float> @zipeven_v4f32(<4 x float> %a, <4 x float> %b) { ; CHECK-LABEL: zipeven_v4f32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vslideup.vi v8, v9, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4f32: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpaire.vv v10, v8, v9 ; ZVZIP-NEXT: vmv.v.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> ret <4 x float> %c } define <4 x double> @zipeven_v4f64(<4 x double> %a, <4 x double> %b) { ; CHECK-LABEL: zipeven_v4f64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 1, e8, mf8, ta, ma ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, mu ; CHECK-NEXT: vslideup.vi v8, v10, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4f64: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e64, m2, ta, ma ; ZVZIP-NEXT: vpaire.vv v12, v8, v10 ; ZVZIP-NEXT: vmv.v.v v8, v12 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> ret <4 x double> %c } define <4 x i32> @zipodd_v4i32(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: zipodd_v4i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 5 ; CHECK-NEXT: vslidedown.vi v9, v8, 1, v0.t ; CHECK-NEXT: vmv.v.v v8, v9 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v4i32: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpairo.vv v10, v8, v9 ; ZVZIP-NEXT: vmv.v.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> ret <4 x i32> %c } define <4 x i32> @zipodd_v4i32_swapped(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: zipodd_v4i32_swapped: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 5 ; CHECK-NEXT: vslidedown.vi v8, v9, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v4i32_swapped: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpairo.vv v10, v9, v8 ; ZVZIP-NEXT: vmv.v.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> ret <4 x i32> %c } ; This is the zipeven pattern with a poison second operand. That happens ; to also be described as an identity shuffle, so this is testing that we ; don't emit the zipeven instruction. define <4 x i32> @zipeven_v4i32_single(<4 x i32> %a) { ; CHECK-LABEL: zipeven_v4i32_single: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4i32_single: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> poison, <4 x i32> ret <4 x i32> %c } ; This is the zipodd pattern with a poison second operand. That happens ; to also be described as a single slide, so this is testing that we ; don't emit the zipodd instruction. define <4 x i32> @zipodd_v4i32_single(<4 x i32> %a) { ; CHECK-LABEL: zipodd_v4i32_single: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v8, v8, 1 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v4i32_single: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vslidedown.vi v8, v8, 1 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> poison, <4 x i32> ret <4 x i32> %c } define <4 x i32> @zipodd_v4i32_both(<4 x i32> %a) { ; CHECK-LABEL: zipodd_v4i32_both: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 5 ; CHECK-NEXT: vslidedown.vi v8, v8, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v4i32_both: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpairo.vv v9, v8, v8 ; ZVZIP-NEXT: vmv.v.v v8, v9 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> poison, <4 x i32> ret <4 x i32> %c } define <4 x i32> @zipeven_v4i32_both(<4 x i32> %a) { ; CHECK-LABEL: zipeven_v4i32_both: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 10 ; CHECK-NEXT: vmv1r.v v9, v8 ; CHECK-NEXT: vslideup.vi v9, v8, 1, v0.t ; CHECK-NEXT: vmv.v.v v8, v9 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4i32_both: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpaire.vv v9, v8, v8 ; ZVZIP-NEXT: vmv.v.v v8, v9 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> poison, <4 x i32> ret <4 x i32> %c } define <4 x i32> @zipeven_v4i32_partial(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: zipeven_v4i32_partial: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, ma ; CHECK-NEXT: vslideup.vi v8, v9, 1 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v4i32_partial: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 2, e32, m1, tu, ma ; ZVZIP-NEXT: vslideup.vi v8, v9, 1 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> ret <4 x i32> %c } define <4 x i32> @zipodd_v4i32_partial(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: zipodd_v4i32_partial: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu ; CHECK-NEXT: vmv.v.i v0, 5 ; CHECK-NEXT: vslidedown.vi v9, v8, 1, v0.t ; CHECK-NEXT: vmv.v.v v8, v9 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v4i32_partial: ; ZVZIP: # %bb.0: # %entry ; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma ; ZVZIP-NEXT: vpairo.vv v10, v8, v9 ; ZVZIP-NEXT: vmv.v.v v8, v10 ; ZVZIP-NEXT: ret entry: %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> ret <4 x i32> %c } define <8 x i32> @zipeven_v8i32(<8 x i32> %v1, <8 x i32> %v2) { ; CHECK-LABEL: zipeven_v8i32: ; CHECK: # %bb.0: ; CHECK-NEXT: li a0, 170 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu ; CHECK-NEXT: vmv.s.x v0, a0 ; CHECK-NEXT: vslideup.vi v8, v10, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v8i32: ; ZVZIP: # %bb.0: ; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma ; ZVZIP-NEXT: vpaire.vv v12, v8, v10 ; ZVZIP-NEXT: vmv.v.v v8, v12 ; ZVZIP-NEXT: ret %out = shufflevector <8 x i32> %v1, <8 x i32> %v2, <8 x i32> ret <8 x i32> %out } define <8 x i32> @zipodd_v8i32(<8 x i32> %v1, <8 x i32> %v2) { ; CHECK-LABEL: zipodd_v8i32: ; CHECK: # %bb.0: ; CHECK-NEXT: li a0, 85 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu ; CHECK-NEXT: vmv.s.x v0, a0 ; CHECK-NEXT: vslidedown.vi v10, v8, 1, v0.t ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v8i32: ; ZVZIP: # %bb.0: ; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma ; ZVZIP-NEXT: vpairo.vv v12, v8, v10 ; ZVZIP-NEXT: vmv.v.v v8, v12 ; ZVZIP-NEXT: ret %out = shufflevector <8 x i32> %v1, <8 x i32> %v2, <8 x i32> ret <8 x i32> %out } define <16 x i64> @zipeven_v16i64(<16 x i64> %v1, <16 x i64> %v2) { ; CHECK-LABEL: zipeven_v16i64: ; CHECK: # %bb.0: ; CHECK-NEXT: lui a0, 11 ; CHECK-NEXT: addi a0, a0, -1366 ; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, mu ; CHECK-NEXT: vmv.s.x v0, a0 ; CHECK-NEXT: vslideup.vi v8, v16, 1, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v16i64: ; ZVZIP: # %bb.0: ; ZVZIP-NEXT: vsetivli zero, 16, e64, m8, ta, ma ; ZVZIP-NEXT: vpaire.vv v24, v8, v16 ; ZVZIP-NEXT: vmv.v.v v8, v24 ; ZVZIP-NEXT: ret %out = shufflevector <16 x i64> %v1, <16 x i64> %v2, <16 x i32> ret <16 x i64> %out } define <16 x i64> @zipodd_v16i64(<16 x i64> %v1, <16 x i64> %v2) { ; CHECK-LABEL: zipodd_v16i64: ; CHECK: # %bb.0: ; CHECK-NEXT: lui a0, 5 ; CHECK-NEXT: addi a0, a0, 1365 ; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, mu ; CHECK-NEXT: vmv.s.x v0, a0 ; CHECK-NEXT: vslidedown.vi v16, v8, 1, v0.t ; CHECK-NEXT: vmv.v.v v8, v16 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v16i64: ; ZVZIP: # %bb.0: ; ZVZIP-NEXT: vsetivli zero, 16, e64, m8, ta, ma ; ZVZIP-NEXT: vpairo.vv v24, v8, v16 ; ZVZIP-NEXT: vmv.v.v v8, v24 ; ZVZIP-NEXT: ret %out = shufflevector <16 x i64> %v1, <16 x i64> %v2, <16 x i32> ret <16 x i64> %out } define <8 x i32> @zipeven_v8i32_as_v4i64(<8 x i32> %v1, <8 x i32> %v2) { ; CHECK-LABEL: zipeven_v8i32_as_v4i64: ; CHECK: # %bb.0: ; CHECK-NEXT: li a0, 204 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu ; CHECK-NEXT: vmv.s.x v0, a0 ; CHECK-NEXT: vslideup.vi v8, v10, 2, v0.t ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipeven_v8i32_as_v4i64: ; ZVZIP: # %bb.0: ; ZVZIP-NEXT: vsetivli zero, 4, e64, m2, ta, ma ; ZVZIP-NEXT: vpaire.vv v12, v8, v10 ; ZVZIP-NEXT: vmv.v.v v8, v12 ; ZVZIP-NEXT: ret %out = shufflevector <8 x i32> %v1, <8 x i32> %v2, <8 x i32> ret <8 x i32> %out } define <8 x i32> @zipodd_v8i32_as_v4i64(<8 x i32> %v1, <8 x i32> %v2) { ; CHECK-LABEL: zipodd_v8i32_as_v4i64: ; CHECK: # %bb.0: ; CHECK-NEXT: li a0, 51 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu ; CHECK-NEXT: vmv.s.x v0, a0 ; CHECK-NEXT: vslidedown.vi v10, v8, 2, v0.t ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret ; ; ZVZIP-LABEL: zipodd_v8i32_as_v4i64: ; ZVZIP: # %bb.0: ; ZVZIP-NEXT: vsetivli zero, 4, e64, m2, ta, ma ; ZVZIP-NEXT: vpairo.vv v12, v8, v10 ; ZVZIP-NEXT: vmv.v.v v8, v12 ; ZVZIP-NEXT: ret %out = shufflevector <8 x i32> %v1, <8 x i32> %v2, <8 x i32> ret <8 x i32> %out } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; RV32: {{.*}} ; RV64: {{.*}} ; ZVZIP-RV32: {{.*}} ; ZVZIP-RV64: {{.*}}