From 2de4c92778cc3ec342fa6ea01e1b8456fc33091d Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Tue, 5 Aug 2025 11:01:22 +0000 Subject: [PATCH] [LLVM][LangRef] Remove "n > 0" restriction from get.active.lanes.mask. The specification for get.active.lanes.mask says a limit value of zero results in poison. This seems like an artificial restriction and means you cannot use the intrinsic to create minimal loops of the form: foo(int count, ....) { int i = 0; while (mask = get.active.lane.mask(i, count)) { ; do work i += count_bits(mask); } } I cannot see any code that generates poison in this case, in fact ConstantFoldFixedVectorCall returns the logical result (i.e. an all false vector). There are also cases like `can_overflow_i64_induction_var` in sve-tail-folding-overflow-checks.ll that look broken by the current definition? for the case when "%N <= vscale * 4". For these reasons I'm asking if we can simply remove the restriction? --- llvm/docs/LangRef.rst | 3 +- llvm/lib/Analysis/Lint.cpp | 7 ---- .../Analysis/Lint/get-active-lane-mask.ll | 39 ------------------- 3 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 llvm/test/Analysis/Lint/get-active-lane-mask.ll diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index d8cd3b894cda4..77b10b3c22ef4 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -24014,8 +24014,7 @@ indexed by ``i``, and ``%base``, ``%n`` are the two arguments to ``llvm.get.active.lane.mask.*``, ``%icmp`` is an integer compare and ``ult`` the unsigned less-than comparison operator. Overflow cannot occur in ``(%base + i)`` and its comparison against ``%n`` as it is performed in integer -numbers and not in machine numbers. If ``%n`` is ``0``, then the result is a -poison value. The above is equivalent to: +numbers and not in machine numbers. The above is equivalent to: :: diff --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp index 1168005f48c0e..32a4264c0343c 100644 --- a/llvm/lib/Analysis/Lint.cpp +++ b/llvm/lib/Analysis/Lint.cpp @@ -374,13 +374,6 @@ void Lint::visitCallBase(CallBase &I) { visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), std::nullopt, nullptr, MemRef::Read | MemRef::Write); break; - case Intrinsic::get_active_lane_mask: - if (auto *TripCount = dyn_cast(I.getArgOperand(1))) - Check(!TripCount->isZero(), - "get_active_lane_mask: operand #2 " - "must be greater than 0", - &I); - break; } } diff --git a/llvm/test/Analysis/Lint/get-active-lane-mask.ll b/llvm/test/Analysis/Lint/get-active-lane-mask.ll deleted file mode 100644 index e9b161846e8bd..0000000000000 --- a/llvm/test/Analysis/Lint/get-active-lane-mask.ll +++ /dev/null @@ -1,39 +0,0 @@ -; RUN: opt -passes=lint -disable-output < %s 2>&1 | FileCheck %s - -define <4 x i1> @t1(i32 %IV) { -; -; CHECK: get_active_lane_mask: operand #2 must be greater than 0 -; CHECK-NEXT: %res = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %IV, i32 0) -; - %res = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %IV, i32 0) - ret <4 x i1> %res -} - -define <4 x i1> @t2(i32 %IV) { -; -; CHECK-NOT: get_active_lane_mask -; CHECK-NOT: call <4 x i1> @llvm.get.active.lane.mask -; - %res = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %IV, i32 1) - ret <4 x i1> %res -} - -define <4 x i1> @t3(i32 %IV) { -; -; CHECK-NOT: get_active_lane_mask -; CHECK-NOT: call <4 x i1> @llvm.get.active.lane.mask -; - %res = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %IV, i32 -1) - ret <4 x i1> %res -} - -define <4 x i1> @t4(i32 %IV, i32 %TC) { -; -; CHECK-NOT: get_active_lane_mask -; CHECK-NOT: call <4 x i1> @llvm.get.active.lane.mask -; - %res = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %IV, i32 %TC) - ret <4 x i1> %res -} - -declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32, i32)