[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 05:56:33 PDT 2026
https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/234487
>From 4a4ccd6406a8a449e892bce6abb524b02818eccd 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