[llvm-branch-commits] [llvm] [DAG] Fix get_active_lane_mask expansion on 32-bit targets (PR #234487)

Luke Lau via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Oct 23 01:56:16 PDT 2026


https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/234487

>From f721733618a89a15b1f9d8935ecdd20d53a7cbb5 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 22 Oct 2026 11:59:43 +0800
Subject: [PATCH] [SelectionDAG] Fix get_active_lane_mask expansion on 32-bit
 targets

On e.g. wasm32, OpVT can be 32 bits whilst the StepVector type can be v2i64. When this happens DAG.getConstant asserts because maxUIntN doesn't fit into the 32 bits. Fix this by clamping it to OpVT's max size.
---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  6 ++-
 .../CodeGen/WebAssembly/mask-beforefirst.ll   | 47 +++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/WebAssembly/mask-beforefirst.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 27b22285354788..cbda4fdaae57bf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11522,8 +11522,10 @@ SDValue TargetLowering::expandGetActiveLaneMask(SDNode *N,
   assert(StepVector && "Step vector needs splitting");
 
   // Rebase and saturate the termination value.
-  SDValue Max = DAG.getConstant(maxUIntN(StepVector.getScalarValueSizeInBits()),
-                                DL, OpVT);
+  SDValue Max =
+      DAG.getConstant(maxUIntN(std::min(StepVector.getScalarValueSizeInBits(),
+                                        OpVT.getScalarSizeInBits())),
+                      DL, OpVT);
   End = DAG.getNode(ISD::USUBSAT, DL, OpVT, End, Start);
   End = DAG.getNode(ISD::UMIN, DL, OpVT, End, Max);
   End = DAG.getZExtOrTrunc(End, DL, StepVector.getValueType().getScalarType());
diff --git a/llvm/test/CodeGen/WebAssembly/mask-beforefirst.ll b/llvm/test/CodeGen/WebAssembly/mask-beforefirst.ll
new file mode 100644
index 00000000000000..25db1e5f0dca71
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/mask-beforefirst.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=wasm32 -mattr=+simd128 | FileCheck %s
+
+define <2 x i64> @v2i1(<2 x i64> %a0, <2 x i64> %a1) {
+; CHECK-LABEL: v2i1:
+; CHECK:         .functype v2i1 (v128, v128) -> (v128)
+; CHECK-NEXT:    .local v128, i64, i64, i32
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    local.get 1
+; CHECK-NEXT:    i64.const -1
+; CHECK-NEXT:    i64.const 0
+; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    local.get 1
+; CHECK-NEXT:    i64x2.gt_s
+; CHECK-NEXT:    v128.const 2, 1
+; CHECK-NEXT:    v128.and
+; CHECK-NEXT:    local.tee 2
+; CHECK-NEXT:    i64x2.extract_lane 0
+; CHECK-NEXT:    local.tee 3
+; CHECK-NEXT:    local.get 2
+; CHECK-NEXT:    i64x2.extract_lane 1
+; CHECK-NEXT:    local.tee 4
+; CHECK-NEXT:    local.get 3
+; CHECK-NEXT:    local.get 4
+; CHECK-NEXT:    i64.gt_u
+; CHECK-NEXT:    i64.select
+; CHECK-NEXT:    i64.sub
+; CHECK-NEXT:    i32.wrap_i64
+; CHECK-NEXT:    local.tee 5
+; CHECK-NEXT:    i64.select
+; CHECK-NEXT:    i64x2.splat
+; CHECK-NEXT:    i64.const -1
+; CHECK-NEXT:    i64.const 0
+; CHECK-NEXT:    local.get 5
+; CHECK-NEXT:    i32.const 1
+; CHECK-NEXT:    i32.gt_u
+; CHECK-NEXT:    i64.select
+; CHECK-NEXT:    i64x2.replace_lane 1
+; CHECK-NEXT:    v128.bitselect
+; CHECK-NEXT:    # fallthrough-return
+  %m = icmp sgt <2 x i64> %a0, %a1
+  %x = call <2 x i1> @llvm.mask.beforefirst(<2 x i1> %m)
+  %r = select <2 x i1> %x, <2 x i64> %a0, <2 x i64> %a1
+  ret <2 x i64> %r
+}



More information about the llvm-branch-commits mailing list