[llvm] [RISCV] Extract subregister if VLEN is known when lowering extract_subvector (PR #65392)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 5 10:36:35 PDT 2023
https://github.com/lukel97 created https://github.com/llvm/llvm-project/pull/65392:
If we know VLEN at compile time, then we can workout what subregister an index into a fixed length vector will be at.
We can use this information when lowering extract_subvector to perform the vslidedown on a smaller subregister. This allows us to use a smaller LMUL, or if the extract is aligned to a vector register then we can avoid the slide
altogether.
The logic here is a bit tangled with the scalable path: If people find this too unwieldy, I can separate it out and duplicate it for the fixed case.
This technique could be applied to extract_vector_elt, insert_vector_elt and insert_subvector too.
This is stacked upon https://github.com/llvm/llvm-project/pull/65391
>From 9bba3ddfe0f551ab6590c1019cef1c563a962eb3 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Tue, 5 Sep 2023 14:27:15 +0100
Subject: [PATCH 1/3] [RISCV] Add extract_subvector tests for a
statically-known VLEN. NFC
This is partly a precommit for an upcoming patch, and partly to remove the
fixed length LMUL restriction similarly to what was done in
https://reviews.llvm.org/D158270, since it's no longer that relevant.
---
.../rvv/fixed-vectors-extract-subvector.ll | 513 +++++++++---------
1 file changed, 265 insertions(+), 248 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
index ed84a97c804f6d4..92b052fcaab8394 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv64 -mattr=+m,+v -riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=2 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX2
-; RUN: llc -mtriple=riscv64 -mattr=+m,+v -riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=1 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX1
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,UNKNOWNVLEN
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v -riscv-v-vector-bits-min=128 -riscv-v-vector-bits-max=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,KNOWNVLEN
define void @extract_v2i8_v4i8_0(ptr %x, ptr %y) {
; CHECK-LABEL: extract_v2i8_v4i8_0:
@@ -62,22 +62,46 @@ define void @extract_v2i8_v8i8_6(ptr %x, ptr %y) {
ret void
}
+define void @extract_v1i32_v8i32_4(ptr %x, ptr %y) {
+; CHECK-LABEL: extract_v1i32_v8i32_4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; 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: vse32.v v8, (a1)
+; CHECK-NEXT: ret
+ %a = load <8 x i32>, ptr %x
+ %c = call <1 x i32> @llvm.vector.extract.v1i32.v8i32(<8 x i32> %a, i64 4)
+ store <1 x i32> %c, ptr %y
+ ret void
+}
+
+define void @extract_v1i32_v8i32_5(ptr %x, ptr %y) {
+; CHECK-LABEL: extract_v1i32_v8i32_5:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 1, e32, m2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 5
+; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a1)
+; CHECK-NEXT: ret
+ %a = load <8 x i32>, ptr %x
+ %c = call <1 x i32> @llvm.vector.extract.v1i32.v8i32(<8 x i32> %a, i64 5)
+ store <1 x i32> %c, ptr %y
+ ret void
+}
+
define void @extract_v2i32_v8i32_0(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v2i32_v8i32_0:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; LMULMAX2-NEXT: vle32.v v8, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; LMULMAX2-NEXT: vse32.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v2i32_v8i32_0:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; LMULMAX1-NEXT: vle32.v v8, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; LMULMAX1-NEXT: vse32.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v2i32_v8i32_0:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 0)
store <2 x i32> %c, ptr %y
@@ -85,52 +109,47 @@ define void @extract_v2i32_v8i32_0(ptr %x, ptr %y) {
}
define void @extract_v2i32_v8i32_2(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v2i32_v8i32_2:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; LMULMAX2-NEXT: vle32.v v8, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 2, e32, m2, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 2
-; LMULMAX2-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; LMULMAX2-NEXT: vse32.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v2i32_v8i32_2:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; LMULMAX1-NEXT: vle32.v v8, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 2, e32, m1, ta, ma
-; LMULMAX1-NEXT: vslidedown.vi v8, v8, 2
-; LMULMAX1-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; LMULMAX1-NEXT: vse32.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v2i32_v8i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 2
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 2)
store <2 x i32> %c, ptr %y
ret void
}
+define void @extract_v2i32_v8i32_4(ptr %x, ptr %y) {
+; CHECK-LABEL: extract_v2i32_v8i32_4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 4
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a1)
+; CHECK-NEXT: ret
+ %a = load <8 x i32>, ptr %x
+ %c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 4)
+ store <2 x i32> %c, ptr %y
+ ret void
+}
+
define void @extract_v2i32_v8i32_6(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v2i32_v8i32_6:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; LMULMAX2-NEXT: vle32.v v8, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 2, e32, m2, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 6
-; LMULMAX2-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; LMULMAX2-NEXT: vse32.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v2i32_v8i32_6:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: addi a0, a0, 16
-; LMULMAX1-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; LMULMAX1-NEXT: vle32.v v8, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 2, e32, m1, ta, ma
-; LMULMAX1-NEXT: vslidedown.vi v8, v8, 2
-; LMULMAX1-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; LMULMAX1-NEXT: vse32.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v2i32_v8i32_6:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 6
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 6)
store <2 x i32> %c, ptr %y
@@ -148,6 +167,33 @@ define void @extract_v2i32_nxv16i32_0(<vscale x 16 x i32> %x, ptr %y) {
ret void
}
+
+define void @extract_v2i32_nxv16i32_2(<vscale x 16 x i32> %x, ptr %y) {
+; CHECK-LABEL: extract_v2i32_nxv16i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 2
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 2)
+ store <2 x i32> %c, ptr %y
+ ret void
+}
+
+define void @extract_v2i32_nxv16i32_4(<vscale x 16 x i32> %x, ptr %y) {
+; CHECK-LABEL: extract_v2i32_nxv16i32_4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 4
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 4)
+ store <2 x i32> %c, ptr %y
+ ret void
+}
+
define void @extract_v2i32_nxv16i32_6(<vscale x 16 x i32> %x, ptr %y) {
; CHECK-LABEL: extract_v2i32_nxv16i32_6:
; CHECK: # %bb.0:
@@ -161,6 +207,19 @@ define void @extract_v2i32_nxv16i32_6(<vscale x 16 x i32> %x, ptr %y) {
ret void
}
+define void @extract_v2i32_nxv16i32_8(<vscale x 16 x i32> %x, ptr %y) {
+; CHECK-LABEL: extract_v2i32_nxv16i32_8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 8
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 8)
+ store <2 x i32> %c, ptr %y
+ ret void
+}
+
define void @extract_v2i8_nxv2i8_0(<vscale x 2 x i8> %x, ptr %y) {
; CHECK-LABEL: extract_v2i8_nxv2i8_0:
; CHECK: # %bb.0:
@@ -185,47 +244,54 @@ define void @extract_v2i8_nxv2i8_2(<vscale x 2 x i8> %x, ptr %y) {
ret void
}
+define void @extract_v2i8_nxv2i8_4(<vscale x 2 x i8> %x, ptr %y) {
+; CHECK-LABEL: extract_v2i8_nxv2i8_4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 4
+; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-NEXT: vse8.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <2 x i8> @llvm.vector.extract.v2i8.nxv2i8(<vscale x 2 x i8> %x, i64 4)
+ store <2 x i8> %c, ptr %y
+ ret void
+}
+
+define void @extract_v2i8_nxv2i8_6(<vscale x 2 x i8> %x, ptr %y) {
+; CHECK-LABEL: extract_v2i8_nxv2i8_6:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 6
+; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-NEXT: vse8.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <2 x i8> @llvm.vector.extract.v2i8.nxv2i8(<vscale x 2 x i8> %x, i64 6)
+ store <2 x i8> %c, ptr %y
+ ret void
+}
+
define void @extract_v8i32_nxv16i32_8(<vscale x 16 x i32> %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v8i32_nxv16i32_8:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: vsetivli zero, 8, e32, m8, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 8
-; LMULMAX2-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; LMULMAX2-NEXT: vse32.v v8, (a0)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v8i32_nxv16i32_8:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 4, e32, m8, ta, ma
-; LMULMAX1-NEXT: vslidedown.vi v16, v8, 8
-; LMULMAX1-NEXT: vslidedown.vi v8, v8, 12
-; LMULMAX1-NEXT: addi a1, a0, 16
-; LMULMAX1-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; LMULMAX1-NEXT: vse32.v v8, (a1)
-; LMULMAX1-NEXT: vse32.v v16, (a0)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v8i32_nxv16i32_8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m8, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 8
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: ret
%c = call <8 x i32> @llvm.vector.extract.v8i32.nxv16i32(<vscale x 16 x i32> %x, i64 8)
store <8 x i32> %c, ptr %y
ret void
}
define void @extract_v8i1_v64i1_0(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v8i1_v64i1_0:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: li a2, 32
-; LMULMAX2-NEXT: vsetvli zero, a2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vlm.v v8, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vsm.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v8i1_v64i1_0:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; LMULMAX1-NEXT: vlm.v v8, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vsm.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v8i1_v64i1_0:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a2, 64
+; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-NEXT: vlm.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vsm.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <8 x i1> @llvm.vector.extract.v8i1.v64i1(<64 x i1> %a, i64 0)
store <8 x i1> %c, ptr %y
@@ -233,26 +299,16 @@ define void @extract_v8i1_v64i1_0(ptr %x, ptr %y) {
}
define void @extract_v8i1_v64i1_8(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v8i1_v64i1_8:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: li a2, 32
-; LMULMAX2-NEXT: vsetvli zero, a2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vlm.v v8, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 1, e8, mf4, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 1
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vsm.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v8i1_v64i1_8:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; LMULMAX1-NEXT: vlm.v v8, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 1, e8, mf8, ta, ma
-; LMULMAX1-NEXT: vslidedown.vi v8, v8, 1
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vsm.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v8i1_v64i1_8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a2, 64
+; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-NEXT: vlm.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 1
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vsm.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <8 x i1> @llvm.vector.extract.v8i1.v64i1(<64 x i1> %a, i64 8)
store <8 x i1> %c, ptr %y
@@ -260,26 +316,16 @@ define void @extract_v8i1_v64i1_8(ptr %x, ptr %y) {
}
define void @extract_v8i1_v64i1_48(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v8i1_v64i1_48:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: addi a0, a0, 4
-; LMULMAX2-NEXT: li a2, 32
-; LMULMAX2-NEXT: vsetvli zero, a2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vlm.v v8, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 1, e8, mf4, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 2
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vsm.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v8i1_v64i1_48:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: addi a0, a0, 6
-; LMULMAX1-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; LMULMAX1-NEXT: vlm.v v8, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vsm.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v8i1_v64i1_48:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a2, 64
+; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-NEXT: vlm.v v8, (a0)
+; CHECK-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 6
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vsm.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <8 x i1> @llvm.vector.extract.v8i1.v64i1(<64 x i1> %a, i64 48)
store <8 x i1> %c, ptr %y
@@ -334,40 +380,49 @@ define void @extract_v8i1_nxv64i1_48(<vscale x 64 x i1> %x, ptr %y) {
ret void
}
+define void @extract_v8i1_nxv64i1_128(<vscale x 64 x i1> %x, ptr %y) {
+; CHECK-LABEL: extract_v8i1_nxv64i1_128:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 1, e8, m1, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v0, 16
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vsm.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <8 x i1> @llvm.vector.extract.v8i1.nxv64i1(<vscale x 64 x i1> %x, i64 128)
+ store <8 x i1> %c, ptr %y
+ ret void
+}
+
+define void @extract_v8i1_nxv64i1_192(<vscale x 64 x i1> %x, ptr %y) {
+; CHECK-LABEL: extract_v8i1_nxv64i1_192:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 1, e8, m1, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v0, 24
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vsm.v v8, (a0)
+; CHECK-NEXT: ret
+ %c = call <8 x i1> @llvm.vector.extract.v8i1.nxv64i1(<vscale x 64 x i1> %x, i64 192)
+ store <8 x i1> %c, ptr %y
+ ret void
+}
define void @extract_v2i1_v64i1_0(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v2i1_v64i1_0:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: li a2, 32
-; LMULMAX2-NEXT: vsetvli zero, a2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vlm.v v0, (a0)
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; LMULMAX2-NEXT: vmv.v.i v8, 0
-; LMULMAX2-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vmv.v.i v9, 0
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; LMULMAX2-NEXT: vmv.v.v v9, v8
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vmsne.vi v8, v9, 0
-; LMULMAX2-NEXT: vsm.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v2i1_v64i1_0:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; LMULMAX1-NEXT: vlm.v v0, (a0)
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; LMULMAX1-NEXT: vmv.v.i v8, 0
-; LMULMAX1-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vmv.v.i v9, 0
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; LMULMAX1-NEXT: vmv.v.v v9, v8
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vmsne.vi v8, v9, 0
-; LMULMAX1-NEXT: vsm.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v2i1_v64i1_0:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a2, 64
+; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-NEXT: vlm.v v0, (a0)
+; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmv.v.i v9, 0
+; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-NEXT: vmv.v.v v9, v8
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmsne.vi v8, v9, 0
+; CHECK-NEXT: vsm.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 0)
store <2 x i1> %c, ptr %y
@@ -375,48 +430,27 @@ define void @extract_v2i1_v64i1_0(ptr %x, ptr %y) {
}
define void @extract_v2i1_v64i1_2(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v2i1_v64i1_2:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: li a2, 32
-; LMULMAX2-NEXT: vsetvli zero, a2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vlm.v v0, (a0)
-; LMULMAX2-NEXT: vmv.v.i v8, 0
-; LMULMAX2-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 2
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; LMULMAX2-NEXT: vmsne.vi v0, v8, 0
-; LMULMAX2-NEXT: vmv.v.i v8, 0
-; LMULMAX2-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vmv.v.i v9, 0
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; LMULMAX2-NEXT: vmv.v.v v9, v8
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vmsne.vi v8, v9, 0
-; LMULMAX2-NEXT: vsm.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v2i1_v64i1_2:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; LMULMAX1-NEXT: vlm.v v0, (a0)
-; LMULMAX1-NEXT: vmv.v.i v8, 0
-; LMULMAX1-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, m1, ta, ma
-; LMULMAX1-NEXT: vslidedown.vi v8, v8, 2
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; LMULMAX1-NEXT: vmsne.vi v0, v8, 0
-; LMULMAX1-NEXT: vmv.v.i v8, 0
-; LMULMAX1-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vmv.v.i v9, 0
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; LMULMAX1-NEXT: vmv.v.v v9, v8
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vmsne.vi v8, v9, 0
-; LMULMAX1-NEXT: vsm.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v2i1_v64i1_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a2, 64
+; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-NEXT: vlm.v v0, (a0)
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 2
+; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-NEXT: vmsne.vi v0, v8, 0
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmv.v.i v9, 0
+; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-NEXT: vmv.v.v v9, v8
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmsne.vi v8, v9, 0
+; CHECK-NEXT: vsm.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 2)
store <2 x i1> %c, ptr %y
@@ -424,50 +458,28 @@ define void @extract_v2i1_v64i1_2(ptr %x, ptr %y) {
}
define void @extract_v2i1_v64i1_42(ptr %x, ptr %y) {
-; LMULMAX2-LABEL: extract_v2i1_v64i1_42:
-; LMULMAX2: # %bb.0:
-; LMULMAX2-NEXT: addi a0, a0, 4
-; LMULMAX2-NEXT: li a2, 32
-; LMULMAX2-NEXT: vsetvli zero, a2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vlm.v v0, (a0)
-; LMULMAX2-NEXT: vmv.v.i v8, 0
-; LMULMAX2-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, m2, ta, ma
-; LMULMAX2-NEXT: vslidedown.vi v8, v8, 10
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; LMULMAX2-NEXT: vmsne.vi v0, v8, 0
-; LMULMAX2-NEXT: vmv.v.i v8, 0
-; LMULMAX2-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vmv.v.i v9, 0
-; LMULMAX2-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; LMULMAX2-NEXT: vmv.v.v v9, v8
-; LMULMAX2-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX2-NEXT: vmsne.vi v8, v9, 0
-; LMULMAX2-NEXT: vsm.v v8, (a1)
-; LMULMAX2-NEXT: ret
-;
-; LMULMAX1-LABEL: extract_v2i1_v64i1_42:
-; LMULMAX1: # %bb.0:
-; LMULMAX1-NEXT: addi a0, a0, 4
-; LMULMAX1-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; LMULMAX1-NEXT: vlm.v v0, (a0)
-; LMULMAX1-NEXT: vmv.v.i v8, 0
-; LMULMAX1-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, m1, ta, ma
-; LMULMAX1-NEXT: vslidedown.vi v8, v8, 10
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; LMULMAX1-NEXT: vmsne.vi v0, v8, 0
-; LMULMAX1-NEXT: vmv.v.i v8, 0
-; LMULMAX1-NEXT: vmerge.vim v8, v8, 1, v0
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vmv.v.i v9, 0
-; LMULMAX1-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; LMULMAX1-NEXT: vmv.v.v v9, v8
-; LMULMAX1-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; LMULMAX1-NEXT: vmsne.vi v8, v9, 0
-; LMULMAX1-NEXT: vsm.v v8, (a1)
-; LMULMAX1-NEXT: ret
+; CHECK-LABEL: extract_v2i1_v64i1_42:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a2, 64
+; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-NEXT: vlm.v v0, (a0)
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: li a0, 42
+; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; CHECK-NEXT: vslidedown.vx v8, v8, a0
+; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-NEXT: vmsne.vi v0, v8, 0
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmv.v.i v9, 0
+; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-NEXT: vmv.v.v v9, v8
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmsne.vi v8, v9, 0
+; CHECK-NEXT: vsm.v v8, (a1)
+; CHECK-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 42)
store <2 x i1> %c, ptr %y
@@ -640,9 +652,14 @@ declare <8 x i1> @llvm.vector.extract.v8i1.nxv64i1(<vscale x 64 x i1> %vec, i64
declare <2 x i8> @llvm.vector.extract.v2i8.v4i8(<4 x i8> %vec, i64 %idx)
declare <2 x i8> @llvm.vector.extract.v2i8.v8i8(<8 x i8> %vec, i64 %idx)
+
+declare <1 x i32> @llvm.vector.extract.v1i32.v8i32(<8 x i32> %vec, i64 %idx)
declare <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %vec, i64 %idx)
declare <2 x i8> @llvm.vector.extract.v2i8.nxv2i8(<vscale x 2 x i8> %vec, i64 %idx)
declare <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %vec, i64 %idx)
declare <8 x i32> @llvm.vector.extract.v8i32.nxv16i32(<vscale x 16 x i32> %vec, i64 %idx)
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; KNOWNVLEN: {{.*}}
+; UNKNOWNVLEN: {{.*}}
>From 032a5a67d6574a3c60a76ae4e63e95cbc2cf539d Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Tue, 5 Sep 2023 17:26:59 +0100
Subject: [PATCH 2/3] [RISCV] Refactor extract_subvector slightly. NFC
This patch refactors extract_subvector to lower to extract_subreg directly, and
to shortcut whenever the index is 0 when extracting a scalable vector. This
doesn't change any of the existing behaviour, but makes an upcoming patch that
extends the scalable path slightly easier to read.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ab93f6a80077592..54f37c541043a2a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8622,6 +8622,11 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
return DAG.getSetCC(DL, SubVecVT, Vec, SplatZero, ISD::SETNE);
}
}
+
+ // With an index of 0 this is a cast-like subvector, which can be performed
+ // with subregister operations.
+ if (OrigIdx == 0)
+ return Op;
// If the subvector vector is a fixed-length type, we cannot use subregister
// manipulation to simplify the codegen; we don't know which register of a
@@ -8629,10 +8634,6 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
// register size. Therefore we must slide the vector group down the full
// amount.
if (SubVecVT.isFixedLengthVector()) {
- // With an index of 0 this is a cast-like subvector, which can be performed
- // with subregister operations.
- if (OrigIdx == 0)
- return Op;
MVT ContainerVT = VecVT;
if (VecVT.isFixedLengthVector()) {
ContainerVT = getContainerForFixedLengthVector(VecVT);
@@ -8664,17 +8665,15 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
if (RemIdx == 0)
return Op;
- // Else we must shift our vector register directly to extract the subvector.
- // Do this using VSLIDEDOWN.
+ // Else SubVecVT is a fractional LMUL and needs to be slid down.
+ assert(RISCVVType::decodeVLMUL(getLMUL(SubVecVT)).second);
// If the vector type is an LMUL-group type, extract a subvector equal to the
- // nearest full vector register type. This should resolve to a EXTRACT_SUBREG
- // instruction.
+ // nearest full vector register type.
MVT InterSubVT = VecVT;
if (VecVT.bitsGT(getLMUL1VT(VecVT))) {
InterSubVT = getLMUL1VT(VecVT);
- Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InterSubVT, Vec,
- DAG.getConstant(OrigIdx - RemIdx, DL, XLenVT));
+ Vec = DAG.getTargetExtractSubreg(SubRegIdx, DL, InterSubVT, Vec);
}
// Slide this vector register down by the desired number of elements in order
>From 50b189480cf1a401eef4ce788ef9ffb2df72d67a Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Mon, 4 Sep 2023 17:42:52 +0100
Subject: [PATCH 3/3] [RISCV] Extract subregister if VLEN is known when
lowering extract_subvector
If we know VLEN at compile time, then we can workout what subregister an index
into a fixed length vector will be at.
We can use this information when lowering extract_subvector to perform the
vslidedown on a smaller subregister. This allows us to use a smaller LMUL, or
if the extract is aligned to a vector register then we can avoid the slide
altogether.
The logic here is a bit tangled with the scalable path: If people find this too
unwieldy, I can separate it out and duplicate it for the fixed case.
This technique could be applied to extract_vector_elt, insert_vector_elt and
insert_subvector too.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 56 +-
llvm/lib/Target/RISCV/RISCVSubtarget.h | 5 +
.../rvv/fixed-vectors-extract-subvector.ll | 549 ++++++++++++------
3 files changed, 416 insertions(+), 194 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 54f37c541043a2a..d8cf831da2d2905 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8628,12 +8628,14 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
if (OrigIdx == 0)
return Op;
+ auto KnownVLen = Subtarget.getRealKnownVLen();
+
// If the subvector vector is a fixed-length type, we cannot use subregister
- // manipulation to simplify the codegen; we don't know which register of a
- // LMUL group contains the specific subvector as we only know the minimum
- // register size. Therefore we must slide the vector group down the full
- // amount.
- if (SubVecVT.isFixedLengthVector()) {
+ // manipulation to simplify the codegen if we don't know VLEN; we don't know
+ // which register of a LMUL group contains the specific subvector as we only
+ // know the minimum register size. Therefore we must slide the vector group
+ // down the full amount.
+ if (SubVecVT.isFixedLengthVector() && !KnownVLen) {
MVT ContainerVT = VecVT;
if (VecVT.isFixedLengthVector()) {
ContainerVT = getContainerForFixedLengthVector(VecVT);
@@ -8654,19 +8656,46 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
return DAG.getBitcast(Op.getValueType(), Slidedown);
}
+ if (VecVT.isFixedLengthVector()) {
+ VecVT = getContainerForFixedLengthVector(VecVT);
+ Vec = convertToScalableVector(VecVT, Vec, DAG, Subtarget);
+ }
+
+ // The semantics of extract_subvector are that if the extracted subvector is
+ // scalable, then the index is scaled by vscale. So if we have a fixed length
+ // subvector, we need to factor that in before we decompose it to
+ // subregisters...
+ MVT ContainerSubVecVT = SubVecVT;
+ unsigned EffectiveIdx = OrigIdx;
+ unsigned Vscale = *KnownVLen / RISCV::RVVBitsPerBlock;
+ if (SubVecVT.isFixedLengthVector()) {
+ assert(KnownVLen);
+ ContainerSubVecVT = getContainerForFixedLengthVector(SubVecVT);
+ EffectiveIdx = OrigIdx / Vscale;
+ }
+
unsigned SubRegIdx, RemIdx;
std::tie(SubRegIdx, RemIdx) =
RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs(
- VecVT, SubVecVT, OrigIdx, TRI);
+ VecVT, ContainerSubVecVT, EffectiveIdx, TRI);
+
+ // ... and scale the remainder back afterwards.
+ if (SubVecVT.isFixedLengthVector())
+ RemIdx = (RemIdx * Vscale) + (OrigIdx % Vscale);
// If the Idx has been completely eliminated then this is a subvector extract
// which naturally aligns to a vector register. These can easily be handled
// using subregister manipulation.
- if (RemIdx == 0)
+ if (RemIdx == 0) {
+ if (SubVecVT.isFixedLengthVector()) {
+ Vec = DAG.getTargetExtractSubreg(SubRegIdx, DL, ContainerSubVecVT, Vec);
+ return convertFromScalableVector(SubVecVT, Vec, DAG, Subtarget);
+ }
return Op;
+ }
// Else SubVecVT is a fractional LMUL and needs to be slid down.
- assert(RISCVVType::decodeVLMUL(getLMUL(SubVecVT)).second);
+ assert(RISCVVType::decodeVLMUL(getLMUL(ContainerSubVecVT)).second);
// If the vector type is an LMUL-group type, extract a subvector equal to the
// nearest full vector register type.
@@ -8678,10 +8707,17 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
// Slide this vector register down by the desired number of elements in order
// to place the desired subvector starting at element 0.
- SDValue SlidedownAmt =
- DAG.getVScale(DL, XLenVT, APInt(XLenVT.getSizeInBits(), RemIdx));
+ SDValue SlidedownAmt;
+ if (SubVecVT.isFixedLengthVector())
+ SlidedownAmt = DAG.getConstant(RemIdx, DL, Subtarget.getXLenVT());
+ else
+ SlidedownAmt =
+ DAG.getVScale(DL, XLenVT, APInt(XLenVT.getSizeInBits(), RemIdx));
auto [Mask, VL] = getDefaultScalableVLOps(InterSubVT, DL, DAG, Subtarget);
+ if (SubVecVT.isFixedLengthVector())
+ VL = getVLOp(SubVecVT.getVectorNumElements(), DL, DAG, Subtarget);
+
SDValue Slidedown =
getVSlidedown(DAG, Subtarget, DL, InterSubVT, DAG.getUNDEF(InterSubVT),
Vec, SlidedownAmt, Mask, VL);
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index cf64dbc21bd8a8b..86dd9d686136270 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -152,6 +152,11 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
unsigned VLen = getMaxRVVVectorSizeInBits();
return VLen == 0 ? 65536 : VLen;
}
+ std::optional<unsigned> getRealKnownVLen() const {
+ if (getRealMinVLen() == getRealMaxVLen())
+ return getRealMinVLen();
+ return std::nullopt;
+ }
RISCVABI::ABI getTargetABI() const { return TargetABI; }
bool isSoftFPABI() const {
return TargetABI == RISCVABI::ABI_LP64 ||
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
index 92b052fcaab8394..a89a0065be55518 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
@@ -63,15 +63,23 @@ define void @extract_v2i8_v8i8_6(ptr %x, ptr %y) {
}
define void @extract_v1i32_v8i32_4(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v1i32_v8i32_4:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; CHECK-NEXT: vle32.v v8, (a0)
-; 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: vse32.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v1i32_v8i32_4:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vle32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: vsetivli zero, 1, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 4
+; UNKNOWNVLEN-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v1i32_v8i32_4:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; KNOWNVLEN-NEXT: vle32.v v8, (a0)
+; KNOWNVLEN-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v9, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <1 x i32> @llvm.vector.extract.v1i32.v8i32(<8 x i32> %a, i64 4)
store <1 x i32> %c, ptr %y
@@ -79,15 +87,25 @@ define void @extract_v1i32_v8i32_4(ptr %x, ptr %y) {
}
define void @extract_v1i32_v8i32_5(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v1i32_v8i32_5:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; CHECK-NEXT: vle32.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 1, e32, m2, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 5
-; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v1i32_v8i32_5:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vle32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: vsetivli zero, 1, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 5
+; UNKNOWNVLEN-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v1i32_v8i32_5:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; KNOWNVLEN-NEXT: vle32.v v8, (a0)
+; KNOWNVLEN-NEXT: vsetivli zero, 1, e32, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v9, 1
+; KNOWNVLEN-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v8, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <1 x i32> @llvm.vector.extract.v1i32.v8i32(<8 x i32> %a, i64 5)
store <1 x i32> %c, ptr %y
@@ -109,15 +127,25 @@ define void @extract_v2i32_v8i32_0(ptr %x, ptr %y) {
}
define void @extract_v2i32_v8i32_2(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_v8i32_2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; CHECK-NEXT: vle32.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 2
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_v8i32_2:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vle32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_v8i32_2:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; KNOWNVLEN-NEXT: vle32.v v8, (a0)
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v8, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 2)
store <2 x i32> %c, ptr %y
@@ -125,15 +153,23 @@ define void @extract_v2i32_v8i32_2(ptr %x, ptr %y) {
}
define void @extract_v2i32_v8i32_4(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_v8i32_4:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; CHECK-NEXT: vle32.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 4
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_v8i32_4:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vle32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 4
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_v8i32_4:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; KNOWNVLEN-NEXT: vle32.v v8, (a0)
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v9, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 4)
store <2 x i32> %c, ptr %y
@@ -141,15 +177,25 @@ define void @extract_v2i32_v8i32_4(ptr %x, ptr %y) {
}
define void @extract_v2i32_v8i32_6(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_v8i32_6:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; CHECK-NEXT: vle32.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 6
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_v8i32_6:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vle32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 6
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_v8i32_6:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; KNOWNVLEN-NEXT: vle32.v v8, (a0)
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v9, 2
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v8, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <8 x i32>, ptr %x
%c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 6)
store <2 x i32> %c, ptr %y
@@ -169,52 +215,80 @@ define void @extract_v2i32_nxv16i32_0(<vscale x 16 x i32> %x, ptr %y) {
define void @extract_v2i32_nxv16i32_2(<vscale x 16 x i32> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_nxv16i32_2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 2
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_nxv16i32_2:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_nxv16i32_2:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v8, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 2)
store <2 x i32> %c, ptr %y
ret void
}
define void @extract_v2i32_nxv16i32_4(<vscale x 16 x i32> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_nxv16i32_4:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 4
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_nxv16i32_4:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 4
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_nxv16i32_4:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v9, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 4)
store <2 x i32> %c, ptr %y
ret void
}
define void @extract_v2i32_nxv16i32_6(<vscale x 16 x i32> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_nxv16i32_6:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 6
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_nxv16i32_6:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 6
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_nxv16i32_6:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v9, 2
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v8, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 6)
store <2 x i32> %c, ptr %y
ret void
}
define void @extract_v2i32_nxv16i32_8(<vscale x 16 x i32> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i32_nxv16i32_8:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e32, m8, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 8
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i32_nxv16i32_8:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i32_nxv16i32_8:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v10, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %x, i64 8)
store <2 x i32> %c, ptr %y
ret void
@@ -271,13 +345,19 @@ define void @extract_v2i8_nxv2i8_6(<vscale x 2 x i8> %x, ptr %y) {
}
define void @extract_v8i32_nxv16i32_8(<vscale x 16 x i32> %x, ptr %y) {
-; CHECK-LABEL: extract_v8i32_nxv16i32_8:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e32, m8, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 8
-; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; CHECK-NEXT: vse32.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v8i32_nxv16i32_8:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; UNKNOWNVLEN-NEXT: vse32.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v8i32_nxv16i32_8:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; KNOWNVLEN-NEXT: vse32.v v10, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <8 x i32> @llvm.vector.extract.v8i32.nxv16i32(<vscale x 16 x i32> %x, i64 8)
store <8 x i32> %c, ptr %y
ret void
@@ -430,27 +510,49 @@ define void @extract_v2i1_v64i1_0(ptr %x, ptr %y) {
}
define void @extract_v2i1_v64i1_2(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_v64i1_2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v0, (a0)
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 2
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i1_v64i1_2:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: li a2, 64
+; UNKNOWNVLEN-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; UNKNOWNVLEN-NEXT: vlm.v v0, (a0)
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v9, 0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; UNKNOWNVLEN-NEXT: vmv.v.v v9, v8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; UNKNOWNVLEN-NEXT: vsm.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i1_v64i1_2:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: li a2, 64
+; KNOWNVLEN-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; KNOWNVLEN-NEXT: vlm.v v0, (a0)
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v9, 0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; KNOWNVLEN-NEXT: vmv.v.v v9, v8
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; KNOWNVLEN-NEXT: vsm.v v8, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 2)
store <2 x i1> %c, ptr %y
@@ -458,28 +560,50 @@ define void @extract_v2i1_v64i1_2(ptr %x, ptr %y) {
}
define void @extract_v2i1_v64i1_42(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_v64i1_42:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v0, (a0)
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: li a0, 42
-; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma
-; CHECK-NEXT: vslidedown.vx v8, v8, a0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i1_v64i1_42:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: li a2, 64
+; UNKNOWNVLEN-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; UNKNOWNVLEN-NEXT: vlm.v v0, (a0)
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: li a0, 42
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vx v8, v8, a0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v9, 0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; UNKNOWNVLEN-NEXT: vmv.v.v v9, v8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; UNKNOWNVLEN-NEXT: vsm.v v8, (a1)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i1_v64i1_42:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: li a2, 64
+; KNOWNVLEN-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; KNOWNVLEN-NEXT: vlm.v v0, (a0)
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v10, 10
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v9, 0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; KNOWNVLEN-NEXT: vmv.v.v v9, v8
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; KNOWNVLEN-NEXT: vsm.v v8, (a1)
+; KNOWNVLEN-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 42)
store <2 x i1> %c, ptr %y
@@ -550,76 +674,136 @@ define void @extract_v2i1_nxv64i1_0(<vscale x 64 x i1> %x, ptr %y) {
}
define void @extract_v2i1_nxv64i1_2(<vscale x 64 x i1> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_nxv64i1_2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a1, zero, e8, m8, ta, ma
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 2, e8, m8, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 2
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i1_nxv64i1_2:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetvli a1, zero, e8, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v9, 0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; UNKNOWNVLEN-NEXT: vmv.v.v v9, v8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; UNKNOWNVLEN-NEXT: vsm.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i1_nxv64i1_2:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetvli a1, zero, e8, m8, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v8, 2
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v9, 0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; KNOWNVLEN-NEXT: vmv.v.v v9, v8
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; KNOWNVLEN-NEXT: vsm.v v8, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i1> @llvm.vector.extract.v2i1.nxv64i1(<vscale x 64 x i1> %x, i64 2)
store <2 x i1> %c, ptr %y
ret void
}
define void @extract_v2i1_nxv64i1_42(<vscale x 64 x i1> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_nxv64i1_42:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a1, zero, e8, m8, ta, ma
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: li a1, 42
-; CHECK-NEXT: vsetivli zero, 2, e8, m8, ta, ma
-; CHECK-NEXT: vslidedown.vx v8, v8, a1
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i1_nxv64i1_42:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetvli a1, zero, e8, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: li a1, 42
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, m8, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vx v8, v8, a1
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v9, 0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; UNKNOWNVLEN-NEXT: vmv.v.v v9, v8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; UNKNOWNVLEN-NEXT: vsm.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i1_nxv64i1_42:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetvli a1, zero, e8, m8, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v10, 10
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v9, 0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; KNOWNVLEN-NEXT: vmv.v.v v9, v8
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; KNOWNVLEN-NEXT: vsm.v v8, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i1> @llvm.vector.extract.v2i1.nxv64i1(<vscale x 64 x i1> %x, i64 42)
store <2 x i1> %c, ptr %y
ret void
}
define void @extract_v2i1_nxv32i1_26(<vscale x 32 x i1> %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_nxv32i1_26:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a1, zero, e8, m4, ta, ma
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 26
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a0)
-; CHECK-NEXT: ret
+; UNKNOWNVLEN-LABEL: extract_v2i1_nxv32i1_26:
+; UNKNOWNVLEN: # %bb.0:
+; UNKNOWNVLEN-NEXT: vsetvli a1, zero, e8, m4, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; UNKNOWNVLEN-NEXT: vslidedown.vi v8, v8, 26
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; UNKNOWNVLEN-NEXT: vmv.v.i v8, 0
+; UNKNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmv.v.i v9, 0
+; UNKNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; UNKNOWNVLEN-NEXT: vmv.v.v v9, v8
+; UNKNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; UNKNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; UNKNOWNVLEN-NEXT: vsm.v v8, (a0)
+; UNKNOWNVLEN-NEXT: ret
+;
+; KNOWNVLEN-LABEL: extract_v2i1_nxv32i1_26:
+; KNOWNVLEN: # %bb.0:
+; KNOWNVLEN-NEXT: vsetvli a1, zero, e8, m4, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; KNOWNVLEN-NEXT: vslidedown.vi v8, v9, 10
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v0, v8, 0
+; KNOWNVLEN-NEXT: vmv.v.i v8, 0
+; KNOWNVLEN-NEXT: vmerge.vim v8, v8, 1, v0
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmv.v.i v9, 0
+; KNOWNVLEN-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; KNOWNVLEN-NEXT: vmv.v.v v9, v8
+; KNOWNVLEN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; KNOWNVLEN-NEXT: vmsne.vi v8, v9, 0
+; KNOWNVLEN-NEXT: vsm.v v8, (a0)
+; KNOWNVLEN-NEXT: ret
%c = call <2 x i1> @llvm.vector.extract.v2i1.nxv32i1(<vscale x 32 x i1> %x, i64 26)
store <2 x i1> %c, ptr %y
ret void
@@ -660,6 +844,3 @@ declare <2 x i8> @llvm.vector.extract.v2i8.nxv2i8(<vscale x 2 x i8> %vec, i64 %i
declare <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %vec, i64 %idx)
declare <8 x i32> @llvm.vector.extract.v8i32.nxv16i32(<vscale x 16 x i32> %vec, i64 %idx)
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; KNOWNVLEN: {{.*}}
-; UNKNOWNVLEN: {{.*}}
More information about the llvm-commits
mailing list