[llvm] [AArch64] Tighten conditions for expanding GET_ACTIVE_LANE_MASK (PR #208962)

Usman Nadeem via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 08:52:27 PDT 2026


https://github.com/UsmanNadeem updated https://github.com/llvm/llvm-project/pull/208962

>From 26b9c683e6c94128a686dc172adac68efc9e4228 Mon Sep 17 00:00:00 2001
From: Usman Nadeem <mnadeem at qti.qualcomm.com>
Date: Sat, 11 Jul 2026 15:35:18 -0700
Subject: [PATCH 1/3] [AArch64] Tighten conditions for expanding
 GET_ACTIVE_LANE_MASK

Lower to whilelo in more cases.

For fixed-width even if the operands are <32 bits expanding is
going to be more expensive compared to promoting the operands
from a smaller type.

For SVE I also added lowering for nxv1i1 type as:
  nxv2i1 -> extract nxv1i1.

Change-Id: I80cf668a90eec6a48d0909025df4472a43cf41cc
---
 .../Target/AArch64/AArch64ISelLowering.cpp    |  23 ++-
 .../CostModel/AArch64/sve-intrinsics.ll       |   8 +-
 llvm/test/CodeGen/AArch64/active_lane_mask.ll | 131 +++++-------------
 3 files changed, 52 insertions(+), 110 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index f33d953eec747..7535e4a942867 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1649,6 +1649,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::GET_ACTIVE_LANE_MASK, VT, Legal);
     }
 
+    setOperationAction(ISD::GET_ACTIVE_LANE_MASK, MVT::nxv1i1, Custom);
+
     if (Subtarget->isSVEorStreamingSVEAvailable() &&
         (Subtarget->hasSVE2p1() || Subtarget->hasSME2()))
       setOperationAction(ISD::GET_ACTIVE_LANE_MASK, MVT::nxv32i1, Custom);
@@ -2447,10 +2449,9 @@ bool AArch64TargetLowering::shouldExpandGetActiveLaneMask(EVT ResVT,
       ResVT.getVectorElementType() != MVT::i1)
     return true;
 
-  // Only support illegal types if the result is scalable and min elements > 1.
-  if (ResVT.getVectorMinNumElements() == 1 ||
-      (ResVT.isFixedLengthVector() && (ResVT.getVectorNumElements() > 16 ||
-                                       (OpVT != MVT::i32 && OpVT != MVT::i64))))
+  // Only support illegal types if the result is scalable.
+  if ((ResVT.isFixedLengthVector() && (ResVT.getVectorNumElements() > 16 ||
+                                       ResVT.getVectorNumElements() == 1)))
     return true;
 
   // 32 & 64 bit operands are supported. We can promote anything < 64 bits,
@@ -34374,15 +34375,23 @@ SDValue
 AArch64TargetLowering::LowerGET_ACTIVE_LANE_MASK(SDValue Op,
                                                  SelectionDAG &DAG) const {
   EVT VT = Op.getValueType();
-  assert(VT.isFixedLengthVector() && "Expected fixed length vector type!");
+  assert((VT.isFixedLengthVector() || VT == MVT::nxv1i1) &&
+         "Expected fixed length vector type or nxv1i1!");
 
   assert(Subtarget->isSVEorStreamingSVEAvailable() &&
          "Lowering fixed length get_active_lane_mask requires SVE!");
 
+  SDLoc DL(Op);
+  if (VT == MVT::nxv1i1) {
+    EVT NewMaskTy = MVT::nxv2i1;
+    SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, NewMaskTy,
+                               Op.getOperand(0), Op.getOperand(1));
+    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Mask,
+                       DAG.getVectorIdxConstant(0, DL));
+  }
+
   // There are no dedicated fixed-length instructions for GET_ACTIVE_LANE_MASK,
   // but we can use SVE when available.
-
-  SDLoc DL(Op);
   EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
   EVT WhileVT = ContainerVT.changeElementType(*DAG.getContext(), MVT::i1);
 
diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll b/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll
index d5bd4bd7081a3..2e67a97b7a053 100644
--- a/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll
@@ -867,7 +867,7 @@ define void @get_lane_mask() #0 {
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
-; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 6 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
+; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
 ; CHECK-SVE-LABEL: 'get_lane_mask'
@@ -891,7 +891,7 @@ define void @get_lane_mask() #0 {
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
-; CHECK-SVE-NEXT:  Cost Model: Found costs of 6 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
+; CHECK-SVE-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
 ; CHECK-SVE2p1-OR-SME2-LABEL: 'get_lane_mask'
@@ -915,7 +915,7 @@ define void @get_lane_mask() #0 {
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
-; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 6 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
+; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
 ; TYPE_BASED_ONLY-LABEL: 'get_lane_mask'
@@ -939,7 +939,7 @@ define void @get_lane_mask() #0 {
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
-; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 6 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
+; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
   %mask_nxv16i1_i64 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 poison)
diff --git a/llvm/test/CodeGen/AArch64/active_lane_mask.ll b/llvm/test/CodeGen/AArch64/active_lane_mask.ll
index 778be79038a78..848aea36fbfba 100644
--- a/llvm/test/CodeGen/AArch64/active_lane_mask.ll
+++ b/llvm/test/CodeGen/AArch64/active_lane_mask.ll
@@ -178,13 +178,7 @@ define <vscale x 7 x i1> @lane_mask_nxv7i1_i64(i64 %index, i64 %TC) {
 define <vscale x 1 x i1> @lane_mask_nxv1i1_i32(i32 %index, i32 %TC) {
 ; CHECK-LABEL: lane_mask_nxv1i1_i32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    index z0.s, #0, #1
-; CHECK-NEXT:    mov z1.s, w0
-; CHECK-NEXT:    ptrue p0.s
-; CHECK-NEXT:    uqadd z0.s, z0.s, z1.s
-; CHECK-NEXT:    mov z1.s, w1
-; CHECK-NEXT:    cmphi p1.s, p0/z, z1.s, z0.s
-; CHECK-NEXT:    punpklo p0.h, p1.b
+; CHECK-NEXT:    whilelo p0.d, w0, w1
 ; CHECK-NEXT:    punpklo p0.h, p0.b
 ; CHECK-NEXT:    ret
   %active.lane.mask = call <vscale x 1 x i1> @llvm.get.active.lane.mask.nxv1i1.i32(i32 %index, i32 %TC)
@@ -285,113 +279,49 @@ define <2 x i1> @lane_mask_v2i1_i64(i64 %index, i64 %TC) {
 }
 
 define <16 x i1> @lane_mask_v16i1_i8(i8 %index, i8 %TC) {
-; CHECK-SVE-LABEL: lane_mask_v16i1_i8:
-; CHECK-SVE:       // %bb.0:
-; CHECK-SVE-NEXT:    index z0.b, #0, #1
-; CHECK-SVE-NEXT:    dup v1.16b, w0
-; CHECK-SVE-NEXT:    uqadd v0.16b, v1.16b, v0.16b
-; CHECK-SVE-NEXT:    dup v1.16b, w1
-; CHECK-SVE-NEXT:    cmhi v0.16b, v1.16b, v0.16b
-; CHECK-SVE-NEXT:    ret
-;
-; CHECK-STREAMING-LABEL: lane_mask_v16i1_i8:
-; CHECK-STREAMING:       // %bb.0:
-; CHECK-STREAMING-NEXT:    index z0.b, w0, #1
-; CHECK-STREAMING-NEXT:    mov z1.b, w0
-; CHECK-STREAMING-NEXT:    ptrue p0.b, vl16
-; CHECK-STREAMING-NEXT:    cmphi p1.b, p0/z, z1.b, z0.b
-; CHECK-STREAMING-NEXT:    mov z1.b, p1/z, #-1 // =0xffffffffffffffff
-; CHECK-STREAMING-NEXT:    orr z0.d, z0.d, z1.d
-; CHECK-STREAMING-NEXT:    mov z1.b, w1
-; CHECK-STREAMING-NEXT:    cmphi p1.b, p0/z, z1.b, z0.b
-; CHECK-STREAMING-NEXT:    mov z0.b, p1/z, #-1 // =0xffffffffffffffff
-; CHECK-STREAMING-NEXT:    ret
+; CHECK-LABEL: lane_mask_v16i1_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w1, #0xff
+; CHECK-NEXT:    and w9, w0, #0xff
+; CHECK-NEXT:    whilelo p0.b, w9, w8
+; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    ret
   %active.lane.mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i8(i8 %index, i8 %TC)
   ret <16 x i1> %active.lane.mask
 }
 
 define <8 x i1> @lane_mask_v8i1_i8(i8 %index, i8 %TC) {
-; CHECK-SVE-LABEL: lane_mask_v8i1_i8:
-; CHECK-SVE:       // %bb.0:
-; CHECK-SVE-NEXT:    index z0.b, #0, #1
-; CHECK-SVE-NEXT:    dup v1.8b, w0
-; CHECK-SVE-NEXT:    uqadd v0.8b, v1.8b, v0.8b
-; CHECK-SVE-NEXT:    dup v1.8b, w1
-; CHECK-SVE-NEXT:    cmhi v0.8b, v1.8b, v0.8b
-; CHECK-SVE-NEXT:    ret
-;
-; CHECK-STREAMING-LABEL: lane_mask_v8i1_i8:
-; CHECK-STREAMING:       // %bb.0:
-; CHECK-STREAMING-NEXT:    index z0.b, w0, #1
-; CHECK-STREAMING-NEXT:    mov z1.b, w0
-; CHECK-STREAMING-NEXT:    ptrue p0.b, vl8
-; CHECK-STREAMING-NEXT:    cmphi p1.b, p0/z, z1.b, z0.b
-; CHECK-STREAMING-NEXT:    mov z1.b, p1/z, #-1 // =0xffffffffffffffff
-; CHECK-STREAMING-NEXT:    orr z0.d, z0.d, z1.d
-; CHECK-STREAMING-NEXT:    mov z1.b, w1
-; CHECK-STREAMING-NEXT:    cmphi p1.b, p0/z, z1.b, z0.b
-; CHECK-STREAMING-NEXT:    mov z0.b, p1/z, #-1 // =0xffffffffffffffff
-; CHECK-STREAMING-NEXT:    ret
+; CHECK-LABEL: lane_mask_v8i1_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w1, #0xff
+; CHECK-NEXT:    and w9, w0, #0xff
+; CHECK-NEXT:    whilelo p0.b, w9, w8
+; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    ret
   %active.lane.mask = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i8(i8 %index, i8 %TC)
   ret <8 x i1> %active.lane.mask
 }
 
 define <4 x i1> @lane_mask_v4i1_i8(i8 %index, i8 %TC) {
-; CHECK-SVE-LABEL: lane_mask_v4i1_i8:
-; CHECK-SVE:       // %bb.0:
-; CHECK-SVE-NEXT:    dup v0.4h, w0
-; CHECK-SVE-NEXT:    index z1.h, #0, #1
-; CHECK-SVE-NEXT:    movi d2, #0xff00ff00ff00ff
-; CHECK-SVE-NEXT:    dup v3.4h, w1
-; CHECK-SVE-NEXT:    bic v0.4h, #255, lsl #8
-; CHECK-SVE-NEXT:    bic v3.4h, #255, lsl #8
-; CHECK-SVE-NEXT:    add v0.4h, v0.4h, v1.4h
-; CHECK-SVE-NEXT:    umin v0.4h, v0.4h, v2.4h
-; CHECK-SVE-NEXT:    cmhi v0.4h, v3.4h, v0.4h
-; CHECK-SVE-NEXT:    ret
-;
-; CHECK-STREAMING-LABEL: lane_mask_v4i1_i8:
-; CHECK-STREAMING:       // %bb.0:
-; CHECK-STREAMING-NEXT:    mov z1.h, w0
-; CHECK-STREAMING-NEXT:    index z0.h, #0, #1
-; CHECK-STREAMING-NEXT:    ptrue p0.h, vl4
-; CHECK-STREAMING-NEXT:    and z1.h, z1.h, #0xff
-; CHECK-STREAMING-NEXT:    add z0.h, z1.h, z0.h
-; CHECK-STREAMING-NEXT:    mov z1.h, w1
-; CHECK-STREAMING-NEXT:    umin z0.h, z0.h, #255
-; CHECK-STREAMING-NEXT:    and z1.h, z1.h, #0xff
-; CHECK-STREAMING-NEXT:    cmphi p1.h, p0/z, z1.h, z0.h
-; CHECK-STREAMING-NEXT:    mov z0.h, p1/z, #-1 // =0xffffffffffffffff
-; CHECK-STREAMING-NEXT:    ret
+; CHECK-LABEL: lane_mask_v4i1_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w1, #0xff
+; CHECK-NEXT:    and w9, w0, #0xff
+; CHECK-NEXT:    whilelo p0.h, w9, w8
+; CHECK-NEXT:    mov z0.h, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    ret
   %active.lane.mask = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i8(i8 %index, i8 %TC)
   ret <4 x i1> %active.lane.mask
 }
 
 define <2 x i1> @lane_mask_v2i1_i8(i8 %index, i8 %TC) {
-; CHECK-SVE-LABEL: lane_mask_v2i1_i8:
-; CHECK-SVE:       // %bb.0:
-; CHECK-SVE-NEXT:    movi d0, #0x0000ff000000ff
-; CHECK-SVE-NEXT:    dup v1.2s, w0
-; CHECK-SVE-NEXT:    index z2.s, #0, #1
-; CHECK-SVE-NEXT:    dup v3.2s, w1
-; CHECK-SVE-NEXT:    and v1.8b, v1.8b, v0.8b
-; CHECK-SVE-NEXT:    add v1.2s, v1.2s, v2.2s
-; CHECK-SVE-NEXT:    and v2.8b, v3.8b, v0.8b
-; CHECK-SVE-NEXT:    umin v0.2s, v1.2s, v0.2s
-; CHECK-SVE-NEXT:    cmhi v0.2s, v2.2s, v0.2s
-; CHECK-SVE-NEXT:    ret
-;
-; CHECK-STREAMING-LABEL: lane_mask_v2i1_i8:
-; CHECK-STREAMING:       // %bb.0:
-; CHECK-STREAMING-NEXT:    and w8, w0, #0xff
-; CHECK-STREAMING-NEXT:    ptrue p0.s, vl2
-; CHECK-STREAMING-NEXT:    index z0.s, w8, #1
-; CHECK-STREAMING-NEXT:    and w8, w1, #0xff
-; CHECK-STREAMING-NEXT:    mov z1.s, w8
-; CHECK-STREAMING-NEXT:    umin z0.s, z0.s, #255
-; CHECK-STREAMING-NEXT:    cmphi p1.s, p0/z, z1.s, z0.s
-; CHECK-STREAMING-NEXT:    mov z0.s, p1/z, #-1 // =0xffffffffffffffff
-; CHECK-STREAMING-NEXT:    ret
+; CHECK-LABEL: lane_mask_v2i1_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w1, #0xff
+; CHECK-NEXT:    and w9, w0, #0xff
+; CHECK-NEXT:    whilelo p0.s, w9, w8
+; CHECK-NEXT:    mov z0.s, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    ret
   %active.lane.mask = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i8(i8 %index, i8 %TC)
   ret <2 x i1> %active.lane.mask
 }
@@ -494,3 +424,6 @@ declare <16 x i1> @llvm.get.active.lane.mask.v16i1.i8(i8, i8)
 declare <8 x i1> @llvm.get.active.lane.mask.v8i1.i8(i8, i8)
 declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i8(i8, i8)
 declare <2 x i1> @llvm.get.active.lane.mask.v2i1.i8(i8, i8)
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK-STREAMING: {{.*}}
+; CHECK-SVE: {{.*}}

>From abeeab7e5ee14078c6485f1e8f3137b330a98b4c Mon Sep 17 00:00:00 2001
From: Usman Nadeem <mnadeem at qti.qualcomm.com>
Date: Mon, 13 Jul 2026 14:44:50 -0700
Subject: [PATCH 2/3] Add tests for v1i1 and v32i1, relax condition of fixed
 >16. Address review comments

Change-Id: I61b311e871616c64bd7c1b1ea149d98af436254c
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 11 +--
 .../CostModel/AArch64/sve-intrinsics.ll       |  8 +-
 llvm/test/CodeGen/AArch64/active_lane_mask.ll | 93 ++++++++++++++++++-
 .../CodeGen/AArch64/sve-mask-partition.ll     | 83 +++--------------
 4 files changed, 107 insertions(+), 88 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 7535e4a942867..907ff016c2570 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2449,9 +2449,8 @@ bool AArch64TargetLowering::shouldExpandGetActiveLaneMask(EVT ResVT,
       ResVT.getVectorElementType() != MVT::i1)
     return true;
 
-  // Only support illegal types if the result is scalable.
-  if ((ResVT.isFixedLengthVector() && (ResVT.getVectorNumElements() > 16 ||
-                                       ResVT.getVectorNumElements() == 1)))
+  // Expand 1 length fixed length vector.
+  if (ResVT.isFixedLengthVector() && ResVT.getVectorNumElements() == 1)
     return true;
 
   // 32 & 64 bit operands are supported. We can promote anything < 64 bits,
@@ -34383,11 +34382,9 @@ AArch64TargetLowering::LowerGET_ACTIVE_LANE_MASK(SDValue Op,
 
   SDLoc DL(Op);
   if (VT == MVT::nxv1i1) {
-    EVT NewMaskTy = MVT::nxv2i1;
-    SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, NewMaskTy,
+    SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, MVT::nxv2i1,
                                Op.getOperand(0), Op.getOperand(1));
-    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Mask,
-                       DAG.getVectorIdxConstant(0, DL));
+    return DAG.getExtractSubvector(DL, VT, Mask, 0);
   }
 
   // There are no dedicated fixed-length instructions for GET_ACTIVE_LANE_MASK,
diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll b/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll
index 2e67a97b7a053..c0dd67ae0619a 100644
--- a/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll
@@ -866,7 +866,7 @@ define void @get_lane_mask() #0 {
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 16 for: %mask_v8i1_i32 = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i32(i32 poison, i32 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
-; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
+; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 64 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; CHECK-VSCALE-1-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
@@ -890,7 +890,7 @@ define void @get_lane_mask() #0 {
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 16 for: %mask_v8i1_i32 = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
-; CHECK-SVE-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
+; CHECK-SVE-NEXT:  Cost Model: Found costs of 64 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; CHECK-SVE-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
@@ -914,7 +914,7 @@ define void @get_lane_mask() #0 {
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 16 for: %mask_v8i1_i32 = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
-; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
+; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 64 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; CHECK-SVE2p1-OR-SME2-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
@@ -938,7 +938,7 @@ define void @get_lane_mask() #0 {
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 16 for: %mask_v8i1_i32 = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i32(i32 poison, i32 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 8 for: %mask_v4i1_i32 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 4 for: %mask_v2i1_i32 = call <2 x i1> @llvm.get.active.lane.mask.v2i1.i32(i32 poison, i32 poison)
-; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 48 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
+; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 64 for: %mask_v32i1_i64 = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 poison, i64 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of 32 for: %mask_v16i1_i16 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i16(i16 poison, i16 poison)
 ; TYPE_BASED_ONLY-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
 ;
diff --git a/llvm/test/CodeGen/AArch64/active_lane_mask.ll b/llvm/test/CodeGen/AArch64/active_lane_mask.ll
index 848aea36fbfba..f0d7532cb7047 100644
--- a/llvm/test/CodeGen/AArch64/active_lane_mask.ll
+++ b/llvm/test/CodeGen/AArch64/active_lane_mask.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -enable-subreg-liveness -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SVE
-; RUN: llc -enable-subreg-liveness -mtriple=aarch64-linux-gnu -mattr=+sme -force-streaming < %s | FileCheck %s --check-prefixes=CHECK,CHECK-STREAMING
+; RUN: llc -enable-subreg-liveness -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
+; RUN: llc -enable-subreg-liveness -mtriple=aarch64-linux-gnu -mattr=+sme -force-streaming < %s | FileCheck %s
 
 ; == Scalable ==
 
@@ -198,6 +198,23 @@ define <vscale x 64 x i1> @lane_mask_nxv64i1_i64(i64 %index, i64 %TC) {
 
 ; == Fixed width ==
 
+define void @lane_mask_v32i1_i32(i32 %index, i32 %TC) {
+; CHECK-LABEL: lane_mask_v32i1_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adds w8, w0, #16
+; CHECK-NEXT:    csinv w8, w8, wzr, lo
+; CHECK-NEXT:    whilelo p0.b, w0, w1
+; CHECK-NEXT:    whilelo p1.b, w8, w1
+; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    mov z1.b, p1/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    // fake_use: $q0
+; CHECK-NEXT:    // fake_use: $q1
+; CHECK-NEXT:    ret
+  %active.lane.mask = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i32(i32 %index, i32 %TC)
+  call void (...) @llvm.fake.use(<32 x i1> %active.lane.mask)
+  ret void
+}
+
 define <16 x i1> @lane_mask_v16i1_i32(i32 %index, i32 %TC) {
 ; CHECK-LABEL: lane_mask_v16i1_i32:
 ; CHECK:       // %bb.0:
@@ -238,6 +255,33 @@ define <2 x i1> @lane_mask_v2i1_i32(i32 %index, i32 %TC) {
   ret <2 x i1> %active.lane.mask
 }
 
+define <1 x i1> @lane_mask_v1i1_i32(i32 %index, i32 %TC) {
+; CHECK-LABEL: lane_mask_v1i1_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    cmp w0, w1
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %active.lane.mask = call <1 x i1> @llvm.get.active.lane.mask.v1i1.i32(i32 %index, i32 %TC)
+  ret <1 x i1> %active.lane.mask
+}
+
+define void @lane_mask_v32i1_i64(i64 %index, i64 %TC) {
+; CHECK-LABEL: lane_mask_v32i1_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adds x8, x0, #16
+; CHECK-NEXT:    csinv x8, x8, xzr, lo
+; CHECK-NEXT:    whilelo p0.b, x0, x1
+; CHECK-NEXT:    whilelo p1.b, x8, x1
+; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    mov z1.b, p1/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    // fake_use: $q0
+; CHECK-NEXT:    // fake_use: $q1
+; CHECK-NEXT:    ret
+  %active.lane.mask = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 %index, i64 %TC)
+  call void (...) @llvm.fake.use(<32 x i1> %active.lane.mask)
+  ret void
+}
+
 define <16 x i1> @lane_mask_v16i1_i64(i64 %index, i64 %TC) {
 ; CHECK-LABEL: lane_mask_v16i1_i64:
 ; CHECK:       // %bb.0:
@@ -278,6 +322,37 @@ define <2 x i1> @lane_mask_v2i1_i64(i64 %index, i64 %TC) {
   ret <2 x i1> %active.lane.mask
 }
 
+define <1 x i1> @lane_mask_v1i1_i64(i64 %index, i64 %TC) {
+; CHECK-LABEL: lane_mask_v1i1_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    cmp x0, x1
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %active.lane.mask = call <1 x i1> @llvm.get.active.lane.mask.v1i1.i64(i64 %index, i64 %TC)
+  ret <1 x i1> %active.lane.mask
+}
+
+define void @lane_mask_v32i1_i8(i8 %index, i8 %TC) {
+; CHECK-LABEL: lane_mask_v32i1_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w9, w0, #0xff
+; CHECK-NEXT:    mov w8, #255 // =0xff
+; CHECK-NEXT:    and w11, w1, #0xff
+; CHECK-NEXT:    add w10, w9, #16
+; CHECK-NEXT:    cmp w10, #255
+; CHECK-NEXT:    csel w8, w10, w8, lo
+; CHECK-NEXT:    whilelo p0.b, w9, w11
+; CHECK-NEXT:    whilelo p1.b, w8, w11
+; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    mov z1.b, p1/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    // fake_use: $q0
+; CHECK-NEXT:    // fake_use: $q1
+; CHECK-NEXT:    ret
+  %active.lane.mask = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i8(i8 %index, i8 %TC)
+  call void (...) @llvm.fake.use(<32 x i1> %active.lane.mask)
+  ret void
+}
+
 define <16 x i1> @lane_mask_v16i1_i8(i8 %index, i8 %TC) {
 ; CHECK-LABEL: lane_mask_v16i1_i8:
 ; CHECK:       // %bb.0:
@@ -326,6 +401,17 @@ define <2 x i1> @lane_mask_v2i1_i8(i8 %index, i8 %TC) {
   ret <2 x i1> %active.lane.mask
 }
 
+define <1 x i1> @lane_mask_v1i1_i8(i8 %index, i8 %TC) {
+; CHECK-LABEL: lane_mask_v1i1_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w0, #0xff
+; CHECK-NEXT:    cmp w8, w1, uxtb
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %active.lane.mask = call <1 x i1> @llvm.get.active.lane.mask.v1i1.i8(i8 %index, i8 %TC)
+  ret <1 x i1> %active.lane.mask
+}
+
 define <vscale x 4 x i1> @lane_mask_nxv4i1_imm3() {
 ; CHECK-LABEL: lane_mask_nxv4i1_imm3:
 ; CHECK:       // %bb.0: // %entry
@@ -424,6 +510,3 @@ declare <16 x i1> @llvm.get.active.lane.mask.v16i1.i8(i8, i8)
 declare <8 x i1> @llvm.get.active.lane.mask.v8i1.i8(i8, i8)
 declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i8(i8, i8)
 declare <2 x i1> @llvm.get.active.lane.mask.v2i1.i8(i8, i8)
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-STREAMING: {{.*}}
-; CHECK-SVE: {{.*}}
diff --git a/llvm/test/CodeGen/AArch64/sve-mask-partition.ll b/llvm/test/CodeGen/AArch64/sve-mask-partition.ll
index ec31054e7f12a..98855998c9cb3 100644
--- a/llvm/test/CodeGen/AArch64/sve-mask-partition.ll
+++ b/llvm/test/CodeGen/AArch64/sve-mask-partition.ll
@@ -247,6 +247,7 @@ define <32 x i1> @mask_exclude_active_v32(<32 x i1> %mask.in) {
 ; CHECK-NEXT:    fmov s0, w0
 ; CHECK-NEXT:    ldr w10, [sp, #72]
 ; CHECK-NEXT:    ptrue p0.b, vl16
+; CHECK-NEXT:    mov w11, #16 // =0x10
 ; CHECK-NEXT:    fmov s1, w9
 ; CHECK-NEXT:    ldr w9, [sp, #80]
 ; CHECK-NEXT:    mov v0.b[1], w1
@@ -303,92 +304,30 @@ define <32 x i1> @mask_exclude_active_v32(<32 x i1> %mask.in) {
 ; CHECK-NEXT:    shl v0.16b, v0.16b, #7
 ; CHECK-NEXT:    shl v1.16b, v1.16b, #7
 ; CHECK-NEXT:    cmpne p1.b, p0/z, z0.b, #0
-; CHECK-NEXT:    index z0.d, #0, #1
 ; CHECK-NEXT:    cmpne p2.b, p0/z, z1.b, #0
 ; CHECK-NEXT:    brkb p1.b, p0/z, p1.b
-; CHECK-NEXT:    movprfx z1, z0
-; CHECK-NEXT:    add z1.d, z1.d, #14 // =0xe
-; CHECK-NEXT:    movprfx z2, z0
-; CHECK-NEXT:    add z2.d, z2.d, #12 // =0xc
-; CHECK-NEXT:    movprfx z3, z0
-; CHECK-NEXT:    add z3.d, z3.d, #10 // =0xa
-; CHECK-NEXT:    movprfx z4, z0
-; CHECK-NEXT:    add z4.d, z4.d, #8 // =0x8
-; CHECK-NEXT:    movprfx z5, z0
-; CHECK-NEXT:    add z5.d, z5.d, #6 // =0x6
 ; CHECK-NEXT:    brkb p2.b, p0/z, p2.b
-; CHECK-NEXT:    movprfx z6, z0
-; CHECK-NEXT:    add z6.d, z6.d, #4 // =0x4
-; CHECK-NEXT:    movprfx z7, z0
-; CHECK-NEXT:    add z7.d, z7.d, #2 // =0x2
 ; CHECK-NEXT:    cntp x9, p1, p1.b
-; CHECK-NEXT:    movprfx z17, z0
-; CHECK-NEXT:    add z17.d, z17.d, #30 // =0x1e
-; CHECK-NEXT:    movprfx z18, z0
-; CHECK-NEXT:    add z18.d, z18.d, #28 // =0x1c
 ; CHECK-NEXT:    cntp x10, p2, p2.b
-; CHECK-NEXT:    movprfx z19, z0
-; CHECK-NEXT:    add z19.d, z19.d, #26 // =0x1a
-; CHECK-NEXT:    movprfx z20, z0
-; CHECK-NEXT:    add z20.d, z20.d, #24 // =0x18
-; CHECK-NEXT:    movprfx z21, z0
-; CHECK-NEXT:    add z21.d, z21.d, #22 // =0x16
-; CHECK-NEXT:    movprfx z22, z0
-; CHECK-NEXT:    add z22.d, z22.d, #20 // =0x14
-; CHECK-NEXT:    movprfx z23, z0
-; CHECK-NEXT:    add z23.d, z23.d, #18 // =0x12
-; CHECK-NEXT:    movprfx z24, z0
-; CHECK-NEXT:    add z24.d, z24.d, #16 // =0x10
 ; CHECK-NEXT:    cmp x9, #16
 ; CHECK-NEXT:    add x10, x10, #16
 ; CHECK-NEXT:    csel x9, x9, x10, ne
-; CHECK-NEXT:    dup v16.2d, x9
+; CHECK-NEXT:    whilelo p0.b, x11, x9
+; CHECK-NEXT:    whilelo p1.b, xzr, x9
 ; CHECK-NEXT:    adrp x9, .LCPI17_0
-; CHECK-NEXT:    cmhi v1.2d, v16.2d, v1.2d
-; CHECK-NEXT:    cmhi v2.2d, v16.2d, v2.2d
-; CHECK-NEXT:    cmhi v3.2d, v16.2d, v3.2d
-; CHECK-NEXT:    cmhi v4.2d, v16.2d, v4.2d
-; CHECK-NEXT:    cmhi v5.2d, v16.2d, v5.2d
-; CHECK-NEXT:    cmhi v17.2d, v16.2d, v17.2d
-; CHECK-NEXT:    cmhi v18.2d, v16.2d, v18.2d
-; CHECK-NEXT:    cmhi v19.2d, v16.2d, v19.2d
-; CHECK-NEXT:    cmhi v20.2d, v16.2d, v20.2d
-; CHECK-NEXT:    cmhi v21.2d, v16.2d, v21.2d
-; CHECK-NEXT:    cmhi v22.2d, v16.2d, v22.2d
-; CHECK-NEXT:    cmhi v23.2d, v16.2d, v23.2d
-; CHECK-NEXT:    cmhi v24.2d, v16.2d, v24.2d
-; CHECK-NEXT:    cmhi v6.2d, v16.2d, v6.2d
-; CHECK-NEXT:    cmhi v7.2d, v16.2d, v7.2d
-; CHECK-NEXT:    cmhi v0.2d, v16.2d, v0.2d
-; CHECK-NEXT:    uzp1 v1.4s, v2.4s, v1.4s
-; CHECK-NEXT:    uzp1 v2.4s, v18.4s, v17.4s
-; CHECK-NEXT:    uzp1 v16.4s, v20.4s, v19.4s
-; CHECK-NEXT:    uzp1 v17.4s, v22.4s, v21.4s
-; CHECK-NEXT:    uzp1 v3.4s, v4.4s, v3.4s
-; CHECK-NEXT:    uzp1 v18.4s, v24.4s, v23.4s
-; CHECK-NEXT:    uzp1 v4.4s, v6.4s, v5.4s
-; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v7.4s
-; CHECK-NEXT:    uzp1 v2.8h, v16.8h, v2.8h
-; CHECK-NEXT:    uzp1 v1.8h, v3.8h, v1.8h
-; CHECK-NEXT:    uzp1 v5.8h, v18.8h, v17.8h
-; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v4.8h
-; CHECK-NEXT:    uzp1 v2.16b, v5.16b, v2.16b
-; CHECK-NEXT:    uzp1 v0.16b, v0.16b, v1.16b
-; CHECK-NEXT:    shl v1.16b, v2.16b, #7
-; CHECK-NEXT:    ldr q2, [x9, :lo12:.LCPI17_0]
-; CHECK-NEXT:    shl v0.16b, v0.16b, #7
-; CHECK-NEXT:    cmlt v1.16b, v1.16b, #0
-; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
-; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-NEXT:    and v0.16b, v0.16b, v2.16b
-; CHECK-NEXT:    addp v1.16b, v1.16b, v1.16b
+; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    ldr q1, [x9, :lo12:.LCPI17_0]
+; CHECK-NEXT:    mov z2.b, p1/z, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
+; CHECK-NEXT:    and v1.16b, v2.16b, v1.16b
 ; CHECK-NEXT:    addp v0.16b, v0.16b, v0.16b
 ; CHECK-NEXT:    addp v1.16b, v1.16b, v1.16b
 ; CHECK-NEXT:    addp v0.16b, v0.16b, v0.16b
 ; CHECK-NEXT:    addp v1.16b, v1.16b, v1.16b
 ; CHECK-NEXT:    addp v0.16b, v0.16b, v0.16b
-; CHECK-NEXT:    str h1, [x8, #2]
-; CHECK-NEXT:    str h0, [x8]
+; CHECK-NEXT:    addp v1.16b, v1.16b, v1.16b
+; CHECK-NEXT:    str h0, [x8, #2]
+; CHECK-NEXT:    str h1, [x8]
 ; CHECK-NEXT:    ret
   %tz.elts = call i64 @llvm.experimental.cttz.elts.i64.v32i1(<32 x i1> %mask.in, i1 false)
   %mask.out = call <32 x i1> @llvm.get.active.lane.mask.v32i1.i64(i64 0, i64 %tz.elts)

>From ded1b5c56252c7644f18dbbf5e25a79b00b8bd21 Mon Sep 17 00:00:00 2001
From: Usman Nadeem <mnadeem at qti.qualcomm.com>
Date: Tue, 14 Jul 2026 08:52:03 -0700
Subject: [PATCH 3/3] Move assert

Change-Id: Ic396675cf917f02554b86395f22536cc3851181b
---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 907ff016c2570..a836e78620588 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -34373,14 +34373,11 @@ AArch64TargetLowering::LowerPARTIAL_REDUCE_MLA(SDValue Op,
 SDValue
 AArch64TargetLowering::LowerGET_ACTIVE_LANE_MASK(SDValue Op,
                                                  SelectionDAG &DAG) const {
-  EVT VT = Op.getValueType();
-  assert((VT.isFixedLengthVector() || VT == MVT::nxv1i1) &&
-         "Expected fixed length vector type or nxv1i1!");
-
   assert(Subtarget->isSVEorStreamingSVEAvailable() &&
          "Lowering fixed length get_active_lane_mask requires SVE!");
 
   SDLoc DL(Op);
+  EVT VT = Op.getValueType();
   if (VT == MVT::nxv1i1) {
     SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, MVT::nxv2i1,
                                Op.getOperand(0), Op.getOperand(1));
@@ -34389,6 +34386,7 @@ AArch64TargetLowering::LowerGET_ACTIVE_LANE_MASK(SDValue Op,
 
   // There are no dedicated fixed-length instructions for GET_ACTIVE_LANE_MASK,
   // but we can use SVE when available.
+  assert(VT.isFixedLengthVector() && "Expected fixed length vector type!");
   EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
   EVT WhileVT = ContainerVT.changeElementType(*DAG.getContext(), MVT::i1);
 



More information about the llvm-commits mailing list