[llvm] [LLVM][CodeGen][SVE] Implement custom lowering for insert_vector_elt_nxv1i1. (PR #192494)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 10:36:25 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Paul Walker (paulwalker-arm)
<details>
<summary>Changes</summary>
We cannot use promotion as we do for the other predicate types because nv1i8 is not a legal type. Instead the vector is widened to nxv2i1, which the existing lowering code can then promote.
Also refactors the promotion code to be more explicit.
Fixes https://github.com/llvm/llvm-project/issues/180497
---
Full diff: https://github.com/llvm/llvm-project/pull/192494.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+22-14)
- (modified) llvm/test/CodeGen/AArch64/sve-insert-element.ll (+36)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 178842f9761cd..490a65fee8a3d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -16870,26 +16870,34 @@ SDValue AArch64TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
!Subtarget->isNeonAvailable()))
return LowerFixedLengthInsertVectorElt(Op, DAG);
- EVT VT = Op.getOperand(0).getValueType();
+ EVT VT = Op.getValueType();
+ SDValue Vec = Op.getOperand(0);
+ SDValue Elt = Op.getOperand(1);
+ SDValue Idx = Op.getOperand(2);
if (VT.getScalarType() == MVT::i1) {
- EVT VectorVT = getPromotedVTForPredicate(VT);
SDLoc DL(Op);
- SDValue ExtendedVector =
- DAG.getAnyExtOrTrunc(Op.getOperand(0), DL, VectorVT);
- SDValue ExtendedValue =
- DAG.getAnyExtOrTrunc(Op.getOperand(1), DL,
- VectorVT.getScalarType().getSizeInBits() < 32
- ? MVT::i32
- : VectorVT.getScalarType());
- ExtendedVector =
- DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VectorVT, ExtendedVector,
- ExtendedValue, Op.getOperand(2));
- return DAG.getAnyExtOrTrunc(ExtendedVector, DL, VT);
+
+ // MVT::nxv1i8 is not a legal type so widen->insert->shrink instead.
+ if (VT == MVT::nxv1i1) {
+ SDValue WidenVec =
+ DAG.getInsertSubvector(DL, DAG.getPOISON(MVT::nxv2i1), Vec, 0);
+ SDValue Insert = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::nxv2i1,
+ WidenVec, Elt, Idx);
+ return DAG.getExtractSubvector(DL, MVT::nxv1i1, Insert, 0);
+ }
+
+ EVT PromoteVT = getPromotedVTForPredicate(VT);
+ SDValue PromoteVec = DAG.getNode(ISD::ANY_EXTEND, DL, PromoteVT, Vec);
+ if (PromoteVT.getVectorElementType() == MVT::i64)
+ Elt = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Elt);
+ SDValue Insert = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, PromoteVT,
+ PromoteVec, Elt, Idx);
+ return DAG.getNode(ISD::TRUNCATE, DL, VT, Insert);
}
// Check for non-constant or out of range lane.
- ConstantSDNode *CI = dyn_cast<ConstantSDNode>(Op.getOperand(2));
+ ConstantSDNode *CI = dyn_cast<ConstantSDNode>(Idx);
if (!CI || CI->getZExtValue() >= VT.getVectorNumElements())
return SDValue();
diff --git a/llvm/test/CodeGen/AArch64/sve-insert-element.ll b/llvm/test/CodeGen/AArch64/sve-insert-element.ll
index 777577e2d3b49..023fedcce23cd 100644
--- a/llvm/test/CodeGen/AArch64/sve-insert-element.ll
+++ b/llvm/test/CodeGen/AArch64/sve-insert-element.ll
@@ -452,6 +452,23 @@ define <vscale x 2 x double> @test_insert_with_index_nxv2f64(<vscale x 2 x doubl
}
;Predicate insert
+define <vscale x 1 x i1> @test_predicate_insert_1xi1_immediate(<vscale x 1 x i1> %vec, i1 %elt) {
+; CHECK-LABEL: test_predicate_insert_1xi1_immediate:
+; CHECK: // %bb.0:
+; CHECK-NEXT: uzp1 p0.d, p0.d, p0.d
+; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
+; CHECK-NEXT: mov z0.d, p0/z, #1 // =0x1
+; CHECK-NEXT: ptrue p0.d, vl1
+; CHECK-NEXT: mov z0.d, p0/m, x0
+; CHECK-NEXT: ptrue p0.d
+; CHECK-NEXT: and z0.d, z0.d, #0x1
+; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0
+; CHECK-NEXT: punpklo p0.h, p0.b
+; CHECK-NEXT: ret
+ %res = insertelement <vscale x 1 x i1> %vec, i1 %elt, i32 0
+ ret <vscale x 1 x i1> %res
+}
+
define <vscale x 2 x i1> @test_predicate_insert_2xi1_immediate (<vscale x 2 x i1> %val, i1 %elt) {
; CHECK-LABEL: test_predicate_insert_2xi1_immediate:
; CHECK: // %bb.0:
@@ -520,6 +537,25 @@ define <vscale x 16 x i1> @test_predicate_insert_16xi1_immediate (<vscale x 16 x
ret <vscale x 16 x i1> %res
}
+define <vscale x 1 x i1> @test_predicate_insert_1xi1(<vscale x 1 x i1> %vec, i1 %elt, i32 %idx) {
+; CHECK-LABEL: test_predicate_insert_1xi1:
+; CHECK: // %bb.0:
+; CHECK-NEXT: index z0.d, #0, #1
+; CHECK-NEXT: mov w8, w1
+; CHECK-NEXT: ptrue p1.d
+; CHECK-NEXT: mov z1.d, x8
+; CHECK-NEXT: uzp1 p0.d, p0.d, p0.d
+; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
+; CHECK-NEXT: cmpeq p2.d, p1/z, z0.d, z1.d
+; CHECK-NEXT: mov z0.d, p0/z, #1 // =0x1
+; CHECK-NEXT: mov z0.d, p2/m, x0
+; CHECK-NEXT: and z0.d, z0.d, #0x1
+; CHECK-NEXT: cmpne p0.d, p1/z, z0.d, #0
+; CHECK-NEXT: punpklo p0.h, p0.b
+; CHECK-NEXT: ret
+ %res = insertelement <vscale x 1 x i1> %vec, i1 %elt, i32 %idx
+ ret <vscale x 1 x i1> %res
+}
define <vscale x 2 x i1> @test_predicate_insert_2xi1(<vscale x 2 x i1> %val, i1 %elt, i32 %idx) {
; CHECK-LABEL: test_predicate_insert_2xi1:
``````````
</details>
https://github.com/llvm/llvm-project/pull/192494
More information about the llvm-commits
mailing list