[llvm] [ConstantFolding] Fold scalable get_active_lane_masks (PR #156659)

Matthew Devereau via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 4 04:59:19 PDT 2025


https://github.com/MDevereau updated https://github.com/llvm/llvm-project/pull/156659

>From 49833a23854be79658ed29b71743655bd970f6a6 Mon Sep 17 00:00:00 2001
From: Matthew Devereau <matthew.devereau at arm.com>
Date: Wed, 3 Sep 2025 12:42:57 +0000
Subject: [PATCH 1/2] [ConstantFolding] Fold scalable get_active_lane_masks

Scalable get_active_lane_mask intrinsics with a range of 0 can be lowered to
zeroinitializer. This helps remove no-op scalable masked stores and loads.

When the second operand is 0, this cannot be done (see #152140)
---
 llvm/lib/Analysis/ConstantFolding.cpp         |  7 ++++
 .../ConstProp/active-lane-mask.ll             | 34 +++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 2148431c1acce..8d849fd230648 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -4238,6 +4238,13 @@ static Constant *ConstantFoldScalableVectorCall(
 
     return ConstantInt::getFalse(SVTy);
   }
+  case Intrinsic::get_active_lane_mask: {
+    auto Op0 = cast<ConstantInt>(Operands[0])->getValue();
+    auto Op1 = cast<ConstantInt>(Operands[1])->getValue();
+    if ((Op0.uge(Op1) && (!Op1.isZero())))
+      return ConstantVector::getNullValue(SVTy);
+    break;
+  }
   default:
     break;
   }
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll b/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
index a904e697cc975..c4a465aa17f36 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
@@ -307,6 +307,40 @@ entry:
   ret <4 x float> %var33
 }
 
+define <vscale x 4 x i1> @nxv4i1_12_12() {
+; CHECK-LABEL: @nxv4i1_12_12(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <vscale x 4 x i1> zeroinitializer
+;
+entry:
+  %mask = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i32(i32 12, i32 12)
+  ret <vscale x 4 x i1> %mask
+}
+
+define <vscale x 4 x i1> @nxv4i1_8_4() {
+; CHECK-LABEL: @nxv4i1_8_4(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <vscale x 4 x i1> zeroinitializer
+;
+entry:
+  %mask = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i32(i32 8, i32 4)
+  ret <vscale x 4 x i1> %mask
+}
+
+define <vscale x 16 x i1> @nxv16i1_0_0() {
+; CHECK-LABEL: @nxv16i1_0_0(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[MASK:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 0, i64 0)
+; CHECK-NEXT:    ret <vscale x 16 x i1> [[MASK]]
+;
+entry:
+  %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 0, i64 0)
+  ret <vscale x 16 x i1> %mask
+}
+
 declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32, i32)
 declare <8 x i1> @llvm.get.active.lane.mask.v8i1.i32(i32, i32)
 declare <16 x i1> @llvm.get.active.lane.mask.v16i1.i32(i32, i32)
+
+declare <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i32(i32, i32)
+declare <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64, i64)

>From 042b0292ec02d8c2ecb5ed81829b48c6967ee16f Mon Sep 17 00:00:00 2001
From: Matthew Devereau <matthew.devereau at arm.com>
Date: Thu, 4 Sep 2025 11:57:14 +0000
Subject: [PATCH 2/2] Remove Op1.isZero() condition

---
 llvm/lib/Analysis/ConstantFolding.cpp                          | 2 +-
 .../test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 8d849fd230648..67e6be5b70cb6 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -4241,7 +4241,7 @@ static Constant *ConstantFoldScalableVectorCall(
   case Intrinsic::get_active_lane_mask: {
     auto Op0 = cast<ConstantInt>(Operands[0])->getValue();
     auto Op1 = cast<ConstantInt>(Operands[1])->getValue();
-    if ((Op0.uge(Op1) && (!Op1.isZero())))
+    if (Op0.uge(Op1))
       return ConstantVector::getNullValue(SVTy);
     break;
   }
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll b/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
index c4a465aa17f36..ed26deb58eae4 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
@@ -330,8 +330,7 @@ entry:
 define <vscale x 16 x i1> @nxv16i1_0_0() {
 ; CHECK-LABEL: @nxv16i1_0_0(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[MASK:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 0, i64 0)
-; CHECK-NEXT:    ret <vscale x 16 x i1> [[MASK]]
+; CHECK-NEXT:    ret <vscale x 16 x i1> zeroinitializer
 ;
 entry:
   %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 0, i64 0)



More information about the llvm-commits mailing list