; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=riscv32 -mattr=+v,+zvfh,+zvfbfmin,+m | FileCheck --check-prefixes=CHECK,RV32 %s ; RUN: llc < %s -mtriple=riscv64 -mattr=+v,+zvfh,+zvfbfmin,+m | FileCheck --check-prefixes=CHECK,RV64 %s ; RUN: llc < %s -mtriple=riscv32 -mattr=+v,+zvfhmin,+zvfbfmin,+m | FileCheck --check-prefixes=CHECK,RV32 %s ; RUN: llc < %s -mtriple=riscv64 -mattr=+v,+zvfhmin,+zvfbfmin,+m | FileCheck --check-prefixes=CHECK,RV64 %s ; Integers define {, } @vector_deinterleave_load_nxv16i1_nxv32i1(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv16i1_nxv32i1: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m4, ta, ma ; CHECK-NEXT: vlm.v v8, (a0) ; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: srli a0, a0, 2 ; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, ma ; CHECK-NEXT: vslidedown.vx v0, v8, a0 ; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma ; CHECK-NEXT: vmv.v.i v12, 0 ; CHECK-NEXT: vmerge.vim v10, v12, 1, v0 ; CHECK-NEXT: vmv1r.v v0, v8 ; CHECK-NEXT: vmerge.vim v8, v12, 1, v0 ; CHECK-NEXT: vnsrl.wi v12, v8, 0 ; CHECK-NEXT: vnsrl.wi v14, v8, 8 ; CHECK-NEXT: vmsne.vi v0, v12, 0 ; CHECK-NEXT: vmsne.vi v8, v14, 0 ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv32i1( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv16i8_nxv32i8(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv16i8_nxv32i8: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma ; CHECK-NEXT: vlseg2e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv32i8( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define @vector_deinterleave_load_nxv16i8_nxv32i8_oneactive(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv16i8_nxv32i8_oneactive: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma ; CHECK-NEXT: vlseg2e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv32i8( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 ret %t0 } define @vector_deinterleave_load_nxv16i8_nxv32i8_oneactive2(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv16i8_nxv32i8_oneactive2: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma ; CHECK-NEXT: vlseg2e8.v v6, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv32i8( %vec) %t1 = extractvalue { , } %deinterleaved.results, 1 ret %t1 } ; Shouldn't be lowered to vlseg because it's unaligned define {, } @vector_deinterleave_load_nxv8i16_nxv16i16_align1(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv8i16_nxv16i16_align1: ; CHECK: # %bb.0: ; CHECK-NEXT: vl4r.v v12, (a0) ; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, ma ; CHECK-NEXT: vnsrl.wi v8, v12, 0 ; CHECK-NEXT: vnsrl.wi v10, v12, 16 ; CHECK-NEXT: ret %vec = load , ptr %p, align 1 %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv16i16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv8i16_nxv16i16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv8i16_nxv16i16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, m2, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv16i16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv4i32_nxvv8i32(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv4i32_nxvv8i32: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma ; CHECK-NEXT: vlseg2e32.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv8i32( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv2i64_nxv4i64(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv2i64_nxv4i64: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e64, m2, ta, ma ; CHECK-NEXT: vlseg2e64.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv4i64( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv4i64_nxv8i64(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv4i64_nxv8i64: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e64, m4, ta, ma ; CHECK-NEXT: vlseg2e64.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv8i64( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } ; This shouldn't be lowered to a vlseg because EMUL * NFIELDS >= 8 define {, } @vector_deinterleave_load_nxv8i64_nxv16i64(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv8i64_nxv16i64: ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: csrr a1, vlenb ; CHECK-NEXT: slli a1, a1, 4 ; CHECK-NEXT: sub sp, sp, a1 ; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x10, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 16 * vlenb ; CHECK-NEXT: li a1, 85 ; CHECK-NEXT: vsetvli a2, zero, e8, mf8, ta, ma ; CHECK-NEXT: vmv.v.x v16, a1 ; CHECK-NEXT: csrr a1, vlenb ; CHECK-NEXT: vl8re64.v v24, (a0) ; CHECK-NEXT: slli a1, a1, 3 ; CHECK-NEXT: add a0, a0, a1 ; CHECK-NEXT: li a1, 170 ; CHECK-NEXT: vl8re64.v v0, (a0) ; CHECK-NEXT: vmv.v.x v17, a1 ; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma ; CHECK-NEXT: vcompress.vm v8, v24, v16 ; CHECK-NEXT: vmv1r.v v12, v16 ; CHECK-NEXT: vmv1r.v v13, v17 ; CHECK-NEXT: vcompress.vm v16, v24, v13 ; CHECK-NEXT: vcompress.vm v24, v0, v12 ; CHECK-NEXT: addi a0, sp, 16 ; CHECK-NEXT: vs8r.v v24, (a0) # vscale x 64-byte Folded Spill ; CHECK-NEXT: vcompress.vm v24, v0, v13 ; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: slli a0, a0, 3 ; CHECK-NEXT: add a0, sp, a0 ; CHECK-NEXT: addi a0, a0, 16 ; CHECK-NEXT: vs8r.v v24, (a0) # vscale x 64-byte Folded Spill ; CHECK-NEXT: addi a0, sp, 16 ; CHECK-NEXT: vl8r.v v24, (a0) # vscale x 64-byte Folded Reload ; CHECK-NEXT: vmv4r.v v12, v24 ; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: slli a0, a0, 3 ; CHECK-NEXT: add a0, sp, a0 ; CHECK-NEXT: addi a0, a0, 16 ; CHECK-NEXT: vl8r.v v24, (a0) # vscale x 64-byte Folded Reload ; CHECK-NEXT: vmv4r.v v20, v24 ; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: slli a0, a0, 4 ; 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 %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv16i64( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } ; Floats define {, } @vector_deinterleave_load_nxv2bf16_nxv4bf16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv2bf16_nxv4bf16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, mf2, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv4bf16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv4bf16_nxv8bf16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv4bf16_nxv8bf16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv8bf16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv2f16_nxv4f16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv2f16_nxv4f16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, mf2, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv4f16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv4f16_nxv8f16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv4f16_nxv8f16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv8f16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv2f32_nxv4f32(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv2f32_nxv4f32: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma ; CHECK-NEXT: vlseg2e32.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv4f32( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv8bf16_nxv16bf16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv8bf16_nxv16bf16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, m2, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv16bf16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv8f16_nxv16f16(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv8f16_nxv16f16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e16, m2, ta, ma ; CHECK-NEXT: vlseg2e16.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv16f16( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv4f32_nxv8f32(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv4f32_nxv8f32: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma ; CHECK-NEXT: vlseg2e32.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv8f32( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv2f64_nxv4f64(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_nxv2f64_nxv4f64: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e64, m2, ta, ma ; CHECK-NEXT: vlseg2e64.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv4f64( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define {, } @vector_deinterleave_load_nxv2p0_nxv4p0(ptr %p) { ; RV32-LABEL: vector_deinterleave_load_nxv2p0_nxv4p0: ; RV32: # %bb.0: ; RV32-NEXT: vsetvli a1, zero, e32, m1, ta, ma ; RV32-NEXT: vlseg2e32.v v8, (a0) ; RV32-NEXT: ret ; ; RV64-LABEL: vector_deinterleave_load_nxv2p0_nxv4p0: ; RV64: # %bb.0: ; RV64-NEXT: vsetvli a1, zero, e64, m2, ta, ma ; RV64-NEXT: vlseg2e64.v v8, (a0) ; RV64-NEXT: ret %vec = load , ptr %p %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv4p0( %vec) %t0 = extractvalue { , } %deinterleaved.results, 0 %t1 = extractvalue { , } %deinterleaved.results, 1 %res0 = insertvalue { , } poison, %t0, 0 %res1 = insertvalue { , } %res0, %t1, 1 ret {, } %res1 } define { , , } @vector_deinterleave_load_factor3(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor3: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg3e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call {, , } @llvm.vector.deinterleave3( %vec) %t0 = extractvalue {, , } %d0, 0 %t1 = extractvalue {, , } %d0, 1 %t2 = extractvalue {, , } %d0, 2 %res0 = insertvalue { , , } poison, %t0, 0 %res1 = insertvalue { , , } %res0, %t1, 1 %res2 = insertvalue { , , } %res1, %t2, 2 ret { , , } %res2 } define { , , , } @vector_deinterleave_load_factor4(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor4: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg4e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call { , , , } @llvm.vector.deinterleave4( %vec) %t0 = extractvalue { , , , } %d0, 0 %t1 = extractvalue { , , , } %d0, 1 %t2 = extractvalue { , , , } %d0, 2 %t3 = extractvalue { , , , } %d0, 3 %res0 = insertvalue { , , , } poison, %t0, 0 %res1 = insertvalue { , , , } %res0, %t1, 1 %res2 = insertvalue { , , , } %res1, %t2, 2 %res3 = insertvalue { , , , } %res2, %t3, 3 ret { , , , } %res3 } define @vector_deinterleave_load_factor4_oneactive(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor4_oneactive: ; CHECK: # %bb.0: ; CHECK-NEXT: li a1, 4 ; CHECK-NEXT: vsetvli a2, zero, e8, m1, ta, ma ; CHECK-NEXT: vlse8.v v8, (a0), a1 ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call { , , , } @llvm.vector.deinterleave4( %vec) %t0 = extractvalue { , , , } %d0, 0 ret %t0 } define @vector_deinterleave_load_factor4_oneactive2(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor4_oneactive2: ; CHECK: # %bb.0: ; CHECK-NEXT: addi a0, a0, 3 ; CHECK-NEXT: li a1, 4 ; CHECK-NEXT: vsetvli a2, zero, e8, m1, ta, ma ; CHECK-NEXT: vlse8.v v8, (a0), a1 ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call { , , , } @llvm.vector.deinterleave4( %vec) %t0 = extractvalue { , , , } %d0, 3 ret %t0 } define { , , , } @vector_deinterleave_load_factor4_twoactive(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor4_twoactive: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg4e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call { , , , } @llvm.vector.deinterleave4( %vec) %t0 = extractvalue { , , , } %d0, 0 %t1 = extractvalue { , , , } %d0, 1 %res0 = insertvalue { , , , } poison, %t0, 0 %res1 = insertvalue { , , , } %res0, %t1, 1 ret { , , , } %res1 } define { , , , , } @vector_deinterleave_load_factor5(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor5: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg5e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call {, , , , } @llvm.vector.deinterleave5( %vec) %t0 = extractvalue { , , , , } %d0, 0 %t1 = extractvalue { , , , , } %d0, 1 %t2 = extractvalue { , , , , } %d0, 2 %t3 = extractvalue { , , , , } %d0, 3 %t4 = extractvalue { , , , , } %d0, 4 %res0 = insertvalue { , , , , } poison, %t0, 0 %res1 = insertvalue { , , , , } %res0, %t1, 1 %res2 = insertvalue { , , , , } %res1, %t2, 2 %res3 = insertvalue { , , , , } %res2, %t3, 3 %res4 = insertvalue { , , , , } %res3, %t4, 4 ret { , , , , } %res4 } define { , , , , , } @vector_deinterleave_load_factor6(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor6: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg6e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call { , , , , , } @llvm.vector.deinterleave6( %vec) %t0 = extractvalue { , , , , , } %d0, 0 %t1 = extractvalue { , , , , , } %d0, 1 %t2 = extractvalue { , , , , , } %d0, 2 %t3 = extractvalue { , , , , , } %d0, 3 %t4 = extractvalue { , , , , , } %d0, 4 %t5 = extractvalue { , , , , , } %d0, 5 %res0 = insertvalue { , , , , , } poison, %t0, 0 %res1 = insertvalue { , , , , , } %res0, %t1, 1 %res2 = insertvalue { , , , , , } %res1, %t2, 2 %res3 = insertvalue { , , , , , } %res2, %t3, 3 %res4 = insertvalue { , , , , , } %res3, %t4, 4 %res5 = insertvalue { , , , , , } %res4, %t5, 5 ret { , , , , , } %res5 } define { , , , , , , } @vector_deinterleave_load_factor7(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor7: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg7e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call {, , , , , , } @llvm.vector.deinterleave7( %vec) %t0 = extractvalue { , , , , , , } %d0, 0 %t1 = extractvalue { , , , , , , } %d0, 1 %t2 = extractvalue { , , , , , , } %d0, 2 %t3 = extractvalue { , , , , , , } %d0, 3 %t4 = extractvalue { , , , , , , } %d0, 4 %t5 = extractvalue { , , , , , , } %d0, 5 %t6 = extractvalue { , , , , , , } %d0, 6 %res0 = insertvalue { , , , , , , } poison, %t0, 0 %res1 = insertvalue { , , , , , , } %res0, %t1, 1 %res2 = insertvalue { , , , , , , } %res1, %t2, 2 %res3 = insertvalue { , , , , , , } %res2, %t3, 3 %res4 = insertvalue { , , , , , , } %res3, %t4, 4 %res5 = insertvalue { , , , , , , } %res4, %t5, 5 %res6 = insertvalue { , , , , , , } %res5, %t6, 6 ret { , , , , , , } %res6 } define { , , , , , , , } @vector_deinterleave_load_factor8(ptr %p) { ; CHECK-LABEL: vector_deinterleave_load_factor8: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg8e8.v v8, (a0) ; CHECK-NEXT: ret %vec = load , ptr %p %d0 = call { , , , , , , , } @llvm.vector.deinterleave8( %vec) %t0 = extractvalue { , , , , , , , } %d0, 0 %t1 = extractvalue { , , , , , , , } %d0, 1 %t2 = extractvalue { , , , , , , , } %d0, 2 %t3 = extractvalue { , , , , , , , } %d0, 3 %t4 = extractvalue { , , , , , , , } %d0, 4 %t5 = extractvalue { , , , , , , , } %d0, 5 %t6 = extractvalue { , , , , , , , } %d0, 6 %t7 = extractvalue { , , , , , , , } %d0, 7 %res0 = insertvalue { , , , , , , , } poison, %t0, 0 %res1 = insertvalue { , , , , , , , } %res0, %t1, 1 %res2 = insertvalue { , , , , , , , } %res1, %t2, 2 %res3 = insertvalue { , , , , , , , } %res2, %t3, 3 %res4 = insertvalue { , , , , , , , } %res3, %t4, 4 %res5 = insertvalue { , , , , , , , } %res4, %t5, 5 %res6 = insertvalue { , , , , , , , } %res5, %t6, 6 %res7 = insertvalue { , , , , , , , } %res6, %t7, 7 ret { , , , , , , , } %res7 } define {, } @masked_load_factor2(ptr %p) { ; CHECK-LABEL: masked_load_factor2: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma ; CHECK-NEXT: vlseg2e8.v v8, (a0) ; CHECK-NEXT: ret %vec = call @llvm.masked.load(ptr %p, i32 4, splat (i1 true), poison) %deinterleaved.results = call {, } @llvm.vector.deinterleave2.nxv32i8( %vec) ret {, } %deinterleaved.results } define {, , , } @masked_load_factor4(ptr %p) { ; CHECK-LABEL: masked_load_factor4: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg4e8.v v8, (a0) ; CHECK-NEXT: ret %vec = call @llvm.masked.load(ptr %p, i32 4, splat (i1 true), poison) %deinterleaved.results = call {, , , } @llvm.vector.deinterleave4.nxv32i8( %vec) ret {, , , } %deinterleaved.results } define {, , , } @masked_load_factor4_mask(ptr %p, %mask) { ; CHECK-LABEL: masked_load_factor4_mask: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg4e8.v v8, (a0), v0.t ; CHECK-NEXT: ret %interleaved.mask = tail call @llvm.vector.interleave4.nxv32i1( %mask, %mask, %mask, %mask) %vec = call @llvm.masked.load(ptr %p, i32 4, %interleaved.mask, poison) %deinterleaved.results = call {, , , } @llvm.vector.deinterleave4.nxv32i8( %vec) ret {, , , } %deinterleaved.results } ; Negative test - some of the deinterleaved elements might come from the ; passthru not the load define {, , , } @masked_load_factor4_passthru(ptr %p, %mask, %passthru) { ; CHECK-LABEL: masked_load_factor4_passthru: ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: csrr a1, vlenb ; CHECK-NEXT: slli a1, a1, 3 ; CHECK-NEXT: sub sp, sp, a1 ; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 8 * vlenb ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vmv.v.i v12, 0 ; CHECK-NEXT: addi a1, sp, 16 ; CHECK-NEXT: csrr a2, vlenb ; CHECK-NEXT: vmerge.vim v12, v12, 1, v0 ; CHECK-NEXT: add a3, a1, a2 ; CHECK-NEXT: vmv.v.v v13, v12 ; CHECK-NEXT: srli a4, a2, 2 ; CHECK-NEXT: vmv.v.v v14, v12 ; CHECK-NEXT: srli a5, a2, 3 ; CHECK-NEXT: vmv.v.v v15, v12 ; CHECK-NEXT: vsseg4e8.v v12, (a1) ; CHECK-NEXT: vl1r.v v12, (a1) ; CHECK-NEXT: add a1, a4, a5 ; CHECK-NEXT: vl1r.v v13, (a3) ; CHECK-NEXT: add a3, a3, a2 ; CHECK-NEXT: add a2, a3, a2 ; CHECK-NEXT: vl1r.v v14, (a3) ; CHECK-NEXT: vl1r.v v15, (a2) ; CHECK-NEXT: vmsne.vi v13, v13, 0 ; CHECK-NEXT: vmsne.vi v0, v12, 0 ; CHECK-NEXT: vmsne.vi v12, v14, 0 ; CHECK-NEXT: vmsne.vi v14, v15, 0 ; CHECK-NEXT: vsetvli zero, a4, e8, mf2, tu, ma ; CHECK-NEXT: vslideup.vx v0, v13, a5 ; CHECK-NEXT: vsetvli zero, a1, e8, mf2, tu, ma ; CHECK-NEXT: vslideup.vx v0, v12, a4 ; CHECK-NEXT: vsetvli a2, zero, e8, mf2, ta, ma ; CHECK-NEXT: vslideup.vx v0, v14, a1 ; CHECK-NEXT: vsetvli a1, zero, e8, m4, ta, mu ; CHECK-NEXT: vle8.v v8, (a0), v0.t ; 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: vs4r.v v8, (a0) ; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma ; CHECK-NEXT: vlseg4e8.v v8, (a0) ; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: slli a0, a0, 3 ; 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 %interleaved.mask = tail call @llvm.vector.interleave4.nxv32i1( %mask, %mask, %mask, %mask) %vec = call @llvm.masked.load(ptr %p, i32 4, %interleaved.mask, %passthru) %deinterleaved.results = call {, , , } @llvm.vector.deinterleave4.nxv32i8( %vec) ret {, , , } %deinterleaved.results } define { <8 x float>, <8 x float> } @deinterleave_unrelated(<16 x float> %arg) { ; CHECK-LABEL: deinterleave_unrelated: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma ; CHECK-NEXT: vfabs.v v12, v8 ; CHECK-NEXT: li a0, 32 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma ; CHECK-NEXT: vnsrl.wx v10, v12, a0 ; CHECK-NEXT: vnsrl.wi v8, v12, 0 ; CHECK-NEXT: ret entry: %abs = call <16 x float> @llvm.fabs(<16 x float> %arg) %res = call { <8 x float>, <8 x float> } @llvm.vector.deinterleave2.v16f32(<16 x float> %abs) ret { <8 x float>, <8 x float> } %res }