[llvm] [InstSimplify] Fold active.lane.mask to poison (PR #203333)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 10:47:42 PDT 2026


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/203333

>From 8f3a1c40393e2a673f0e2775a4fe578517c739d9 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 11 Jun 2026 17:25:40 +0100
Subject: [PATCH 1/5] [InstSimplify] Add coverage for active.lane.mask fold

Add missing test coverage for exercising constant-folding of
llvm.get.active.lane.mask.
---
 .../InstSimplify/fold-intrinsics.ll           | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index ef97d42834ac8..1268266e424c4 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -670,3 +670,33 @@ define void @umul_extractvalue_vec(ptr %P, <4 x i32> %x) {
 
   ret void
 }
+
+define <16 x i1> @active_lane_mask_fixed() {
+; CHECK-LABEL: @active_lane_mask_fixed(
+; CHECK-NEXT:    [[MASK2:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
+; CHECK-NEXT:    [[MASK3:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
+; CHECK-NEXT:    [[ADD1:%.*]] = add <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, [[MASK2]]
+; CHECK-NEXT:    [[RES:%.*]] = add <16 x i1> [[ADD1]], [[MASK3]]
+; CHECK-NEXT:    ret <16 x i1> [[RES]]
+;
+  %mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 2, i64 6)
+  %mask1 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 6)
+  %mask2 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
+  %mask3 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
+  %add = add <16 x i1> %mask, %mask1
+  %add1 = add <16 x i1> %add, %mask2
+  %res = add <16 x i1> %add1, %mask3
+  ret <16 x i1> %res
+}
+
+define <vscale x 16 x i1> @active_lane_mask_scalable() {
+; CHECK-LABEL: @active_lane_mask_scalable(
+; CHECK-NEXT:    ret <vscale x 16 x i1> zeroinitializer
+;
+  %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 6)
+  %mask2 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
+  %mask3 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
+  %add = add <vscale x 16 x i1> %mask, %mask2
+  %res = add <vscale x 16 x i1> %add, %mask3
+  ret <vscale x 16 x i1> %mask
+}

>From c370b049ca6eb034c1901b0a2bf4e4bbed134185 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 11 Jun 2026 18:12:55 +0100
Subject: [PATCH 2/5] [InstSimplify] Fix typo

---
 llvm/test/Transforms/InstSimplify/fold-intrinsics.ll | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index 1268266e424c4..f439b7d034556 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -691,12 +691,15 @@ define <16 x i1> @active_lane_mask_fixed() {
 
 define <vscale x 16 x i1> @active_lane_mask_scalable() {
 ; CHECK-LABEL: @active_lane_mask_scalable(
-; CHECK-NEXT:    ret <vscale x 16 x i1> zeroinitializer
+; CHECK-NEXT:    [[MASK2:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
+; CHECK-NEXT:    [[MASK3:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
+; CHECK-NEXT:    [[RES:%.*]] = add <vscale x 16 x i1> [[MASK2]], [[MASK3]]
+; CHECK-NEXT:    ret <vscale x 16 x i1> [[RES]]
 ;
   %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 6)
   %mask2 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
   %mask3 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
   %add = add <vscale x 16 x i1> %mask, %mask2
   %res = add <vscale x 16 x i1> %add, %mask3
-  ret <vscale x 16 x i1> %mask
+  ret <vscale x 16 x i1> %res
 }

>From da2d3f778b222a96b9407e4add8c9eb669baa354 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 11 Jun 2026 18:18:33 +0100
Subject: [PATCH 3/5] [InstSimplify] Use nxv for scalable tests

---
 llvm/test/Transforms/InstSimplify/fold-intrinsics.ll | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index f439b7d034556..0cc179e773abd 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -696,9 +696,9 @@ define <vscale x 16 x i1> @active_lane_mask_scalable() {
 ; CHECK-NEXT:    [[RES:%.*]] = add <vscale x 16 x i1> [[MASK2]], [[MASK3]]
 ; CHECK-NEXT:    ret <vscale x 16 x i1> [[RES]]
 ;
-  %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 6)
-  %mask2 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
-  %mask3 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
+  %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 6)
+  %mask2 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
+  %mask3 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
   %add = add <vscale x 16 x i1> %mask, %mask2
   %res = add <vscale x 16 x i1> %add, %mask3
   ret <vscale x 16 x i1> %res

>From fa06a39369681967d525d1e9bb284999a951660c Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 11 Jun 2026 18:33:52 +0100
Subject: [PATCH 4/5] [InstSimplify] Preserve just poison tests, move

---
 .../InstSimplify/fold-intrinsics.ll           | 33 -------------------
 .../InstSimplify/get_active_lane_mask.ll      | 25 ++++++++++++++
 2 files changed, 25 insertions(+), 33 deletions(-)

diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index 0cc179e773abd..ef97d42834ac8 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -670,36 +670,3 @@ define void @umul_extractvalue_vec(ptr %P, <4 x i32> %x) {
 
   ret void
 }
-
-define <16 x i1> @active_lane_mask_fixed() {
-; CHECK-LABEL: @active_lane_mask_fixed(
-; CHECK-NEXT:    [[MASK2:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
-; CHECK-NEXT:    [[MASK3:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
-; CHECK-NEXT:    [[ADD1:%.*]] = add <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, [[MASK2]]
-; CHECK-NEXT:    [[RES:%.*]] = add <16 x i1> [[ADD1]], [[MASK3]]
-; CHECK-NEXT:    ret <16 x i1> [[RES]]
-;
-  %mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 2, i64 6)
-  %mask1 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 6)
-  %mask2 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
-  %mask3 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
-  %add = add <16 x i1> %mask, %mask1
-  %add1 = add <16 x i1> %add, %mask2
-  %res = add <16 x i1> %add1, %mask3
-  ret <16 x i1> %res
-}
-
-define <vscale x 16 x i1> @active_lane_mask_scalable() {
-; CHECK-LABEL: @active_lane_mask_scalable(
-; CHECK-NEXT:    [[MASK2:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
-; CHECK-NEXT:    [[MASK3:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
-; CHECK-NEXT:    [[RES:%.*]] = add <vscale x 16 x i1> [[MASK2]], [[MASK3]]
-; CHECK-NEXT:    ret <vscale x 16 x i1> [[RES]]
-;
-  %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 6)
-  %mask2 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
-  %mask3 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
-  %add = add <vscale x 16 x i1> %mask, %mask2
-  %res = add <vscale x 16 x i1> %add, %mask3
-  ret <vscale x 16 x i1> %res
-}
diff --git a/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll b/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll
index 180012a4e8211..ecb8219169e53 100644
--- a/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll
+++ b/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll
@@ -66,3 +66,28 @@ define <vscale x 4 x i1> @foo_vscale_max_nxv4i1_2_4_1_16() vscale_range(2,4) {
   ret <vscale x 4 x i1> %mask
 }
 
+define <16 x i1> @active_lane_mask_fixed_poison() {
+; CHECK-LABEL: define <16 x i1> @active_lane_mask_fixed_poison() {
+; CHECK-NEXT:    [[MASK:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
+; CHECK-NEXT:    [[MASK1:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
+; CHECK-NEXT:    [[RES:%.*]] = add <16 x i1> [[MASK]], [[MASK1]]
+; CHECK-NEXT:    ret <16 x i1> [[RES]]
+;
+  %mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
+  %mask1 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
+  %res = add <16 x i1> %mask, %mask1
+  ret <16 x i1> %res
+}
+
+define <vscale x 16 x i1> @active_lane_mask_scalable_poison() {
+; CHECK-LABEL: define <vscale x 16 x i1> @active_lane_mask_scalable_poison() {
+; CHECK-NEXT:    [[MASK:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
+; CHECK-NEXT:    [[MASK1:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
+; CHECK-NEXT:    [[RES:%.*]] = add <vscale x 16 x i1> [[MASK]], [[MASK1]]
+; CHECK-NEXT:    ret <vscale x 16 x i1> [[RES]]
+;
+  %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
+  %mask1 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
+  %res = add <vscale x 16 x i1> %mask, %mask1
+  ret <vscale x 16 x i1> %res
+}

>From 922234e749e7a4ac3fb4fc0312dd13adb0f26236 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 11 Jun 2026 18:40:13 +0100
Subject: [PATCH 5/5] [ConstFold] Fold into poison now

---
 llvm/lib/Analysis/ConstantFolding.cpp         | 43 +++++++++++--------
 .../ConstProp/active-lane-mask.ll             |  4 +-
 .../InstSimplify/get_active_lane_mask.ll      | 10 +----
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 5259c6b035188..40772bd183eb2 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -4341,23 +4341,24 @@ static Constant *ConstantFoldFixedVectorCall(
     return nullptr;
   }
   case Intrinsic::get_active_lane_mask: {
-    auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);
-    auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);
-    if (Op0 && Op1) {
-      unsigned Lanes = FVTy->getNumElements();
-      uint64_t Base = Op0->getZExtValue();
-      uint64_t Limit = Op1->getZExtValue();
-
-      SmallVector<Constant *, 16> NCs;
-      for (unsigned i = 0; i < Lanes; i++) {
-        if (Base + i < Limit)
-          NCs.push_back(ConstantInt::getTrue(Ty));
-        else
-          NCs.push_back(ConstantInt::getFalse(Ty));
-      }
-      return ConstantVector::get(NCs);
+    const APInt *Op0, *Op1;
+    if (!getConstIntOrUndef(Operands[0], Op0) ||
+        !getConstIntOrUndef(Operands[1], Op1))
+      return nullptr;
+    if (!Op0 || !Op1)
+      return PoisonValue::get(FVTy);
+    unsigned Lanes = FVTy->getNumElements();
+    uint64_t Base = Op0->getZExtValue();
+    uint64_t Limit = Op1->getZExtValue();
+
+    SmallVector<Constant *, 16> NCs;
+    for (unsigned i = 0; i < Lanes; i++) {
+      if (Base + i < Limit)
+        NCs.push_back(ConstantInt::getTrue(Ty));
+      else
+        NCs.push_back(ConstantInt::getFalse(Ty));
     }
-    return nullptr;
+    return ConstantVector::get(NCs);
   }
   case Intrinsic::vector_extract: {
     auto *Idx = dyn_cast<ConstantInt>(Operands[1]);
@@ -4500,9 +4501,13 @@ static Constant *ConstantFoldScalableVectorCall(
     return ConstantInt::getFalse(SVTy);
   }
   case Intrinsic::get_active_lane_mask: {
-    auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);
-    auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);
-    if (Op0 && Op1 && Op0->getValue().uge(Op1->getValue()))
+    const APInt *Op0, *Op1;
+    if (!getConstIntOrUndef(Operands[0], Op0) ||
+        !getConstIntOrUndef(Operands[1], Op1))
+      return nullptr;
+    if (!Op0 || !Op1)
+      return PoisonValue::get(SVTy);
+    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 e9d9ac040ea1d..e272b3f0682ef 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/active-lane-mask.ll
@@ -297,9 +297,7 @@ entry:
 define <4 x float> @poisonc(<4 x float> %a, i32 %n) {
 ; CHECK-LABEL: @poisonc(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VAR27:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 poison, i32 1024)
-; CHECK-NEXT:    [[VAR33:%.*]] = select <4 x i1> [[VAR27]], <4 x float> [[A:%.*]], <4 x float> zeroinitializer
-; CHECK-NEXT:    ret <4 x float> [[VAR33]]
+; CHECK-NEXT:    ret <4 x float> poison
 ;
 entry:
   %new0 = shl i1 0, 1
diff --git a/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll b/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll
index ecb8219169e53..ddeb17b4f07aa 100644
--- a/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll
+++ b/llvm/test/Transforms/InstSimplify/get_active_lane_mask.ll
@@ -68,10 +68,7 @@ define <vscale x 4 x i1> @foo_vscale_max_nxv4i1_2_4_1_16() vscale_range(2,4) {
 
 define <16 x i1> @active_lane_mask_fixed_poison() {
 ; CHECK-LABEL: define <16 x i1> @active_lane_mask_fixed_poison() {
-; CHECK-NEXT:    [[MASK:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
-; CHECK-NEXT:    [[MASK1:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
-; CHECK-NEXT:    [[RES:%.*]] = add <16 x i1> [[MASK]], [[MASK1]]
-; CHECK-NEXT:    ret <16 x i1> [[RES]]
+; CHECK-NEXT:    ret <16 x i1> poison
 ;
   %mask = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 26, i64 poison)
   %mask1 = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 poison, i64 6)
@@ -81,10 +78,7 @@ define <16 x i1> @active_lane_mask_fixed_poison() {
 
 define <vscale x 16 x i1> @active_lane_mask_scalable_poison() {
 ; CHECK-LABEL: define <vscale x 16 x i1> @active_lane_mask_scalable_poison() {
-; CHECK-NEXT:    [[MASK:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
-; CHECK-NEXT:    [[MASK1:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)
-; CHECK-NEXT:    [[RES:%.*]] = add <vscale x 16 x i1> [[MASK]], [[MASK1]]
-; CHECK-NEXT:    ret <vscale x 16 x i1> [[RES]]
+; CHECK-NEXT:    ret <vscale x 16 x i1> poison
 ;
   %mask = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 26, i64 poison)
   %mask1 = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 poison, i64 6)



More information about the llvm-commits mailing list