diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index e9396ae76776b..67984658b5110 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -16340,10 +16340,18 @@ AArch64TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op, EVT VT = Op.getOperand(0).getValueType(); if (VT.getScalarType() == MVT::i1) { + SDLoc DL(Op); + // There are no operations to extend a nxv1i1 predicate to a nxv1i128 vector + // An easy lowering is widening the input predicate to nxv2i1. + if (VT == MVT::nxv1i1) { + SDValue WidenedPred = DAG.getInsertSubvector( + DL, DAG.getPOISON(MVT::nxv2i1), Op->getOperand(0), 0); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, Op.getValueType(), + WidenedPred, Op.getOperand(1)); + } // We can't directly extract from an SVE predicate; extend it first. // (This isn't the only possible lowering, but it's straightforward.) EVT VectorVT = getPromotedVTForPredicate(VT); - SDLoc DL(Op); SDValue Extend = DAG.getNode(ISD::ANY_EXTEND, DL, VectorVT, Op.getOperand(0)); MVT ExtractTy = VectorVT == MVT::nxv2i64 ? MVT::i64 : MVT::i32; diff --git a/llvm/test/CodeGen/AArch64/sve-extract-element.ll b/llvm/test/CodeGen/AArch64/sve-extract-element.ll index 721e47cb27240..d8fbda2839b58 100644 --- a/llvm/test/CodeGen/AArch64/sve-extract-element.ll +++ b/llvm/test/CodeGen/AArch64/sve-extract-element.ll @@ -781,6 +781,32 @@ define i1 @test_lane4_2xi1( %a) #0 { ret i1 %b } +define i1 @test_lane0_1xi1( %a) #0 { +; CHECK-LABEL: test_lane0_1xi1: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 p0.d, p0.d, p0.d +; CHECK-NEXT: mov z0.d, p0/z, #1 // =0x1 +; CHECK-NEXT: fmov w8, s0 +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %b = extractelement %a, i32 0 + ret i1 %b +} + +define i1 @test_lanex_1xi1( %a, i32 %x) #0 { +; CHECK-LABEL: test_lanex_1xi1: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 p0.d, p0.d, p0.d +; CHECK-NEXT: mov w8, w0 +; CHECK-NEXT: mov z0.d, p0/z, #1 // =0x1 +; CHECK-NEXT: whilels p0.d, xzr, x8 +; CHECK-NEXT: lastb x8, p0, z0.d +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %b = extractelement %a, i32 %x + ret i1 %b +} + declare i64 @llvm.vscale.i64() attributes #0 = { "target-features"="+sve,+bf16" }