[llvm-branch-commits] [llvm] [SelectionDAG] 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 22:00:16 PDT 2026
https://github.com/lukel97 created https://github.com/llvm/llvm-project/pull/234487
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.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
>From 48802042171edab15146991381019b7ef454c6fa 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