[llvm] [SelectionDAG] Add GET_ACTIVE_LANE_MASK to ComputeNumSignBits (PR #208977)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 11 22:04:06 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Usman Nadeem (UsmanNadeem)

<details>
<summary>Changes</summary>

`GET_ACTIVE_LANE_MASK ` acts like `icmp ult` so code is similar to `SETCC`.

---
Full diff: https://github.com/llvm/llvm-project/pull/208977.diff


3 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+6) 
- (modified) llvm/test/CodeGen/AArch64/fold-sext-in-reg-predicate-fixed-length.ll (+31) 
- (modified) llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp (+25) 


``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 626803ed92a40..bf720addf5b8a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5225,6 +5225,12 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
       return VTBits;
     break;
   }
+  case ISD::GET_ACTIVE_LANE_MASK:
+    // Semantically similar to icmp ult.
+    if (TLI->getBooleanContents(VT.isVector(), /*isFloat=*/false) ==
+        TargetLowering::ZeroOrNegativeOneBooleanContent)
+      return VTBits;
+    break;
   case ISD::ROTL:
   case ISD::ROTR:
     Tmp = ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1);
diff --git a/llvm/test/CodeGen/AArch64/fold-sext-in-reg-predicate-fixed-length.ll b/llvm/test/CodeGen/AArch64/fold-sext-in-reg-predicate-fixed-length.ll
index 783cd6f693ed8..747c1619187f4 100644
--- a/llvm/test/CodeGen/AArch64/fold-sext-in-reg-predicate-fixed-length.ll
+++ b/llvm/test/CodeGen/AArch64/fold-sext-in-reg-predicate-fixed-length.ll
@@ -17,3 +17,34 @@ entry:
   %data = call <16 x i8> @llvm.masked.load.v16i8.p0(ptr %p, i32 1, <16 x i1> %mask, <16 x i8> zeroinitializer)
   ret <16 x i8> %data
 }
+
+define void @active_lane_mask_mstore_vscaleX2(ptr %p, i64 %n) #0 {
+; CHECK-LABEL: active_lane_mask_mstore_vscaleX2:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    whilelo p0.b, xzr, x1
+; CHECK-NEXT:    mov z0.h, #123 // =0x7b
+; CHECK-NEXT:    punpklo p0.h, p0.b
+; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
+; CHECK-NEXT:    ret
+entry:
+  %mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1(i64 0, i64 %n)
+  call void @llvm.masked.store.v16i16.p0(<16 x i16> splat(i16 123), ptr %p, <16 x i1> %mask)
+  ret void
+}
+
+define void @active_lane_mask_mstore_vscaleX4(ptr %p, i64 %n) #1 {
+; CHECK-LABEL: active_lane_mask_mstore_vscaleX4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    whilelo p0.b, xzr, x1
+; CHECK-NEXT:    mov z0.s, #123 // =0x7b
+; CHECK-NEXT:    punpklo p0.h, p0.b
+; CHECK-NEXT:    punpklo p0.h, p0.b
+; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
+; CHECK-NEXT:    ret
+  %mask =  call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 0, i64 %n)
+  call void @llvm.masked.store.v16i32.p0(<16 x i32> splat(i32 123), ptr %p, <16 x i1> %mask)
+  ret void
+}
+
+attributes #0 = { vscale_range(2,2) }
+attributes #1 = { vscale_range(4,4) }
diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
index b144060afe925..2362500254dc5 100644
--- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
+++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
@@ -128,6 +128,31 @@ TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {
   EXPECT_TRUE(Known.isZero());
 }
 
+TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_GET_ACTIVE_LANE_MASK) {
+  // GET_ACTIVE_LANE_MASK promoted/widened to a vector integer type wider
+  // than i1 (e.g. v8i8) should report that all bits of each lane are sign
+  // bits.
+  SDLoc Loc;
+  auto Int64VT = EVT::getIntegerVT(Context, 64);
+  auto MaskVT = MVT::v8i8;
+  auto Base = DAG->getConstant(0, Loc, Int64VT);
+  auto TripCount = DAG->getConstant(8, Loc, Int64VT);
+  auto Op =
+      DAG->getNode(ISD::GET_ACTIVE_LANE_MASK, Loc, MaskVT, Base, TripCount);
+  EXPECT_EQ(DAG->ComputeNumSignBits(Op), 8u);
+}
+
+TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_GET_ACTIVE_LANE_MASK) {
+  SDLoc Loc;
+  auto Int64VT = EVT::getIntegerVT(Context, 64);
+  auto MaskVT = MVT::nxv8i16;
+  auto Base = DAG->getConstant(0, Loc, Int64VT);
+  auto TripCount = DAG->getConstant(8, Loc, Int64VT);
+  auto Op =
+      DAG->getNode(ISD::GET_ACTIVE_LANE_MASK, Loc, MaskVT, Base, TripCount);
+  EXPECT_EQ(DAG->ComputeNumSignBits(Op), 16u);
+}
+
 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
   SDLoc Loc;
   auto Int8VT = EVT::getIntegerVT(Context, 8);

``````````

</details>


https://github.com/llvm/llvm-project/pull/208977


More information about the llvm-commits mailing list