[llvm] [SDAG] Widen TRUNCATE to intermediate type to avoid ISel failure (PR #172473)
Gaƫtan Bossu via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 18 07:10:57 PST 2025
https://github.com/gbossu updated https://github.com/llvm/llvm-project/pull/172473
>From cd09bf8a272b718d270b1b0e27d3a2f8d092cb51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABtan=20Bossu?= <gaetan.bossu at arm.com>
Date: Mon, 15 Dec 2025 16:59:42 +0000
Subject: [PATCH 1/3] [SDAG] Widen TRUNCATE to intermediate type to avoid ISel
failure
SelectionDAG offered no way to widen TRUNCATE for pathological types
like <vscale x 1 x ...> as they do not allow scalarisation.
One way to go further to is widen to an intermediate type which will
allow to promote the element type in a later run of legalisation.
---
.../SelectionDAG/LegalizeVectorTypes.cpp | 10 ++
.../CodeGen/AArch64/saturating-vec-smull.ll | 2 +-
llvm/test/CodeGen/AArch64/sve-trunc.ll | 120 ++++++++++++++++++
3 files changed, 131 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 543072eba6d97..2c7e01af4859f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -5663,6 +5663,16 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
if (Opcode == ISD::ZERO_EXTEND)
return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
}
+
+ // For TRUNCATE, try to widen using the legal EC of the input type instead
+ // if the legalisation action for that intermediate type is not widening.
+ EVT MidResVT =
+ EVT::getVectorVT(Ctx, WidenVT.getVectorElementType(), InVTEC);
+ if (N->getOpcode() == ISD::TRUNCATE &&
+ getTypeAction(MidResVT) == TargetLowering::TypePromoteInteger) {
+ SDValue MidRes = DAG.getNode(ISD::TRUNCATE, DL, MidResVT, InOp, Flags);
+ return DAG.getInsertSubvector(DL, DAG.getUNDEF(WidenVT), MidRes, 0);
+ }
}
if (TLI.isTypeLegal(InWidenVT)) {
diff --git a/llvm/test/CodeGen/AArch64/saturating-vec-smull.ll b/llvm/test/CodeGen/AArch64/saturating-vec-smull.ll
index b647daf72ca35..15d72087fc7b4 100644
--- a/llvm/test/CodeGen/AArch64/saturating-vec-smull.ll
+++ b/llvm/test/CodeGen/AArch64/saturating-vec-smull.ll
@@ -211,7 +211,7 @@ define <1 x i16> @saturating_1xi16(<1 x i16> %a, <1 x i16> %b) {
; CHECK-NEXT: movi v1.2s, #127, msl #8
; CHECK-NEXT: sshr v0.2s, v0.2s, #15
; CHECK-NEXT: smin v0.2s, v0.2s, v1.2s
-; CHECK-NEXT: uzp1 v0.4h, v0.4h, v0.4h
+; CHECK-NEXT: xtn v0.4h, v0.4s
; CHECK-NEXT: ret
%as = sext <1 x i16> %a to <1 x i32>
%bs = sext <1 x i16> %b to <1 x i32>
diff --git a/llvm/test/CodeGen/AArch64/sve-trunc.ll b/llvm/test/CodeGen/AArch64/sve-trunc.ll
index be1f844c7f118..543e5bacd513b 100644
--- a/llvm/test/CodeGen/AArch64/sve-trunc.ll
+++ b/llvm/test/CodeGen/AArch64/sve-trunc.ll
@@ -56,6 +56,126 @@ entry:
ret <vscale x 2 x i32> %out
}
+define <vscale x 4 x i32> @trunc_i64toi32_legal_abi(<vscale x 2 x i64> %in) {
+; CHECK-LABEL: trunc_i64toi32_legal_abi:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
+; CHECK-NEXT: ret
+entry:
+ %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i32>
+ %out.legal = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv2i32(<vscale x 4 x i32> poison, <vscale x 2 x i32> %out, i64 0)
+ ret <vscale x 4 x i32> %out.legal
+}
+
+define <vscale x 8 x i16> @trunc_i64toi16_legal_abi(<vscale x 2 x i64> %in) {
+; CHECK-LABEL: trunc_i64toi16_legal_abi:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: ret
+entry:
+ %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i16>
+ %out.legal = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv2i16(<vscale x 8 x i16> poison, <vscale x 2 x i16> %out, i64 0)
+ ret <vscale x 8 x i16> %out.legal
+}
+
+; Truncating from an "illegal" small type to an even smaller type
+; requires promoting the element type first.
+
+define <vscale x 16 x i8> @trunc_4i16toi8(<vscale x 8 x i16> %in) {
+; CHECK-LABEL: trunc_4i16toi8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uunpklo z0.s, z0.h
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 4 x i16> @llvm.vector.extract.nvv4i16.nxv8i16(<vscale x 8 x i16> %in, i64 0)
+ %out = trunc <vscale x 4 x i16> %subvec to <vscale x 4 x i8>
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.nxv4i8(<vscale x 16 x i8> poison, <vscale x 4 x i8> %out, i64 0)
+ ret <vscale x 16 x i8> %out.legal
+}
+
+; <vscale x 1 x ...> types are tricky because their element type cannot be
+; promoted to form a legal vector type. Instead, they need widening.
+; Note: The uzp1 operations are due to vector.insert().
+
+define <vscale x 4 x i32> @trunc_1i64toi32(<vscale x 2 x i64> %in) {
+; CHECK-LABEL: trunc_1i64toi32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 2 x i64> %in, i64 0)
+ %out = trunc <vscale x 1 x i64> %subvec to <vscale x 1 x i32>
+ %out.legal = call <vscale x 4 x i32> @llvm.vector.insert.nxv8i32.nxv1i32(<vscale x 4 x i32> poison, <vscale x 1 x i32> %out, i64 0)
+ ret <vscale x 4 x i32> %out.legal
+}
+
+define <vscale x 8 x i16> @trunc_1i64toi16(<vscale x 2 x i64> %in) {
+; CHECK-LABEL: trunc_1i64toi16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 2 x i64> %in, i64 0)
+ %out = trunc <vscale x 1 x i64> %subvec to <vscale x 1 x i16>
+ %out.legal = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv1i16(<vscale x 8 x i16> poison, <vscale x 1 x i16> %out, i64 0)
+ ret <vscale x 8 x i16> %out.legal
+}
+
+define <vscale x 16 x i8> @trunc_1i64toi8(<vscale x 2 x i64> %in) {
+; CHECK-LABEL: trunc_1i64toi8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 2 x i64> %in, i64 0)
+ %out = trunc <vscale x 1 x i64> %subvec to <vscale x 1 x i8>
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv8i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
+ ret <vscale x 16 x i8> %out.legal
+}
+
+define <vscale x 8 x i16> @trunc_1i32toi16(<vscale x 4 x i32> %in) {
+; CHECK-LABEL: trunc_1i32toi16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 1 x i32> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 4 x i32> %in, i64 0)
+ %out = trunc <vscale x 1 x i32> %subvec to <vscale x 1 x i16>
+ %out.legal = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv1i16(<vscale x 8 x i16> poison, <vscale x 1 x i16> %out, i64 0)
+ ret <vscale x 8 x i16> %out.legal
+}
+
+define <vscale x 16 x i8> @trunc_1i32toi8(<vscale x 4 x i32> %in) {
+; CHECK-LABEL: trunc_1i32toi8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 1 x i32> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 4 x i32> %in, i64 0)
+ %out = trunc <vscale x 1 x i32> %subvec to <vscale x 1 x i8>
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv8i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
+ ret <vscale x 16 x i8> %out.legal
+}
+
+define <vscale x 16 x i8> @trunc_1i16toi8(<vscale x 8 x i16> %in) {
+; CHECK-LABEL: trunc_1i16toi8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
+; CHECK-NEXT: ret
+entry:
+ %subvec = call <vscale x 1 x i16> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 8 x i16> %in, i64 0)
+ %out = trunc <vscale x 1 x i16> %subvec to <vscale x 1 x i8>
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv8i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
+ ret <vscale x 16 x i8> %out.legal
+}
+
; Truncating to i1 requires convert it to a cmp
define <vscale x 2 x i1> @trunc_i64toi1(<vscale x 2 x i64> %in) {
>From ecc2f0e31782d24b4a58f756a163dbcd4996f066 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABtan=20Bossu?= <gaetan.bossu at arm.com>
Date: Thu, 18 Dec 2025 08:44:11 +0000
Subject: [PATCH 2/3] Comments:
* get rid of tests using well-defined ABI and not testing new code
* replace getUNDEF with getPOISON
---
.../SelectionDAG/LegalizeVectorTypes.cpp | 2 +-
llvm/test/CodeGen/AArch64/sve-trunc.ll | 40 -------------------
2 files changed, 1 insertion(+), 41 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 2c7e01af4859f..b404aadcf0f0c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -5671,7 +5671,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
if (N->getOpcode() == ISD::TRUNCATE &&
getTypeAction(MidResVT) == TargetLowering::TypePromoteInteger) {
SDValue MidRes = DAG.getNode(ISD::TRUNCATE, DL, MidResVT, InOp, Flags);
- return DAG.getInsertSubvector(DL, DAG.getUNDEF(WidenVT), MidRes, 0);
+ return DAG.getInsertSubvector(DL, DAG.getPOISON(WidenVT), MidRes, 0);
}
}
diff --git a/llvm/test/CodeGen/AArch64/sve-trunc.ll b/llvm/test/CodeGen/AArch64/sve-trunc.ll
index 543e5bacd513b..ec5086a091516 100644
--- a/llvm/test/CodeGen/AArch64/sve-trunc.ll
+++ b/llvm/test/CodeGen/AArch64/sve-trunc.ll
@@ -56,46 +56,6 @@ entry:
ret <vscale x 2 x i32> %out
}
-define <vscale x 4 x i32> @trunc_i64toi32_legal_abi(<vscale x 2 x i64> %in) {
-; CHECK-LABEL: trunc_i64toi32_legal_abi:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
-; CHECK-NEXT: ret
-entry:
- %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i32>
- %out.legal = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv2i32(<vscale x 4 x i32> poison, <vscale x 2 x i32> %out, i64 0)
- ret <vscale x 4 x i32> %out.legal
-}
-
-define <vscale x 8 x i16> @trunc_i64toi16_legal_abi(<vscale x 2 x i64> %in) {
-; CHECK-LABEL: trunc_i64toi16_legal_abi:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
-; CHECK-NEXT: ret
-entry:
- %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i16>
- %out.legal = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv2i16(<vscale x 8 x i16> poison, <vscale x 2 x i16> %out, i64 0)
- ret <vscale x 8 x i16> %out.legal
-}
-
-; Truncating from an "illegal" small type to an even smaller type
-; requires promoting the element type first.
-
-define <vscale x 16 x i8> @trunc_4i16toi8(<vscale x 8 x i16> %in) {
-; CHECK-LABEL: trunc_4i16toi8:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: uunpklo z0.s, z0.h
-; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
-; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
-; CHECK-NEXT: ret
-entry:
- %subvec = call <vscale x 4 x i16> @llvm.vector.extract.nvv4i16.nxv8i16(<vscale x 8 x i16> %in, i64 0)
- %out = trunc <vscale x 4 x i16> %subvec to <vscale x 4 x i8>
- %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.nxv4i8(<vscale x 16 x i8> poison, <vscale x 4 x i8> %out, i64 0)
- ret <vscale x 16 x i8> %out.legal
-}
-
; <vscale x 1 x ...> types are tricky because their element type cannot be
; promoted to form a legal vector type. Instead, they need widening.
; Note: The uzp1 operations are due to vector.insert().
>From b722bdeaab80c033a481e89ccddc806fa33f4449 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABtan=20Bossu?= <gaetan.bossu at arm.com>
Date: Thu, 18 Dec 2025 15:08:55 +0000
Subject: [PATCH 3/3] Comments
- Fix invalid types in intrinsic names
- Add example for widening
---
.../SelectionDAG/LegalizeVectorTypes.cpp | 5 +++++
llvm/test/CodeGen/AArch64/sve-trunc.ll | 19 ++++++++++---------
2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index b404aadcf0f0c..b5c6582449d45 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -5666,6 +5666,11 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
// For TRUNCATE, try to widen using the legal EC of the input type instead
// if the legalisation action for that intermediate type is not widening.
+ // E.g. for trunc nxv1i64 -> nxv1i8 where
+ // - nxv1i64 input gets widened to nxv2i64
+ // - nxv1i8 output gets widened to nxv16i8
+ // Then one can try widening the result to nxv2i8 (instead of going all the
+ // way to nxv16i8) if this later allows type promotion.
EVT MidResVT =
EVT::getVectorVT(Ctx, WidenVT.getVectorElementType(), InVTEC);
if (N->getOpcode() == ISD::TRUNCATE &&
diff --git a/llvm/test/CodeGen/AArch64/sve-trunc.ll b/llvm/test/CodeGen/AArch64/sve-trunc.ll
index ec5086a091516..42500b53222a2 100644
--- a/llvm/test/CodeGen/AArch64/sve-trunc.ll
+++ b/llvm/test/CodeGen/AArch64/sve-trunc.ll
@@ -58,7 +58,8 @@ entry:
; <vscale x 1 x ...> types are tricky because their element type cannot be
; promoted to form a legal vector type. Instead, they need widening.
-; Note: The uzp1 operations are due to vector.insert().
+; Note: The uzp1 operations are due to vector.insert(), which is required
+; to avoid relying on an undefined ABI.
define <vscale x 4 x i32> @trunc_1i64toi32(<vscale x 2 x i64> %in) {
; CHECK-LABEL: trunc_1i64toi32:
@@ -66,9 +67,9 @@ define <vscale x 4 x i32> @trunc_1i64toi32(<vscale x 2 x i64> %in) {
; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
; CHECK-NEXT: ret
entry:
- %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 2 x i64> %in, i64 0)
+ %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i64.nxv2i64(<vscale x 2 x i64> %in, i64 0)
%out = trunc <vscale x 1 x i64> %subvec to <vscale x 1 x i32>
- %out.legal = call <vscale x 4 x i32> @llvm.vector.insert.nxv8i32.nxv1i32(<vscale x 4 x i32> poison, <vscale x 1 x i32> %out, i64 0)
+ %out.legal = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv1i32(<vscale x 4 x i32> poison, <vscale x 1 x i32> %out, i64 0)
ret <vscale x 4 x i32> %out.legal
}
@@ -79,7 +80,7 @@ define <vscale x 8 x i16> @trunc_1i64toi16(<vscale x 2 x i64> %in) {
; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
; CHECK-NEXT: ret
entry:
- %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 2 x i64> %in, i64 0)
+ %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i64.nxv2i64(<vscale x 2 x i64> %in, i64 0)
%out = trunc <vscale x 1 x i64> %subvec to <vscale x 1 x i16>
%out.legal = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv1i16(<vscale x 8 x i16> poison, <vscale x 1 x i16> %out, i64 0)
ret <vscale x 8 x i16> %out.legal
@@ -93,9 +94,9 @@ define <vscale x 16 x i8> @trunc_1i64toi8(<vscale x 2 x i64> %in) {
; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
; CHECK-NEXT: ret
entry:
- %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 2 x i64> %in, i64 0)
+ %subvec = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i64.nxv2i64(<vscale x 2 x i64> %in, i64 0)
%out = trunc <vscale x 1 x i64> %subvec to <vscale x 1 x i8>
- %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv8i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
ret <vscale x 16 x i8> %out.legal
}
@@ -120,7 +121,7 @@ define <vscale x 16 x i8> @trunc_1i32toi8(<vscale x 4 x i32> %in) {
entry:
%subvec = call <vscale x 1 x i32> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 4 x i32> %in, i64 0)
%out = trunc <vscale x 1 x i32> %subvec to <vscale x 1 x i8>
- %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv8i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
ret <vscale x 16 x i8> %out.legal
}
@@ -130,9 +131,9 @@ define <vscale x 16 x i8> @trunc_1i16toi8(<vscale x 8 x i16> %in) {
; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
; CHECK-NEXT: ret
entry:
- %subvec = call <vscale x 1 x i16> @llvm.vector.extract.nxv1i32.nxv4i32(<vscale x 8 x i16> %in, i64 0)
+ %subvec = call <vscale x 1 x i16> @llvm.vector.extract.nxv1i16.nxv8i16(<vscale x 8 x i16> %in, i64 0)
%out = trunc <vscale x 1 x i16> %subvec to <vscale x 1 x i8>
- %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv8i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
+ %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0)
ret <vscale x 16 x i8> %out.legal
}
More information about the llvm-commits
mailing list