[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
Wed Oct 21 23:14:25 PDT 2026


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

>From 8e0f5ae95d29e79cd97b774d8fd6a433d43e9f44 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