[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