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

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Oct 21 22:00:53 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-webassembly

Author: Luke Lau (lukel97)

<details>
<summary>Changes</summary>

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>

---
Full diff: https://github.com/llvm/llvm-project/pull/234487.diff


2 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+4-2) 
- (added) llvm/test/CodeGen/WebAssembly/mask-beforefirst.ll (+47) 


``````````diff
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
+}

``````````

</details>


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


More information about the llvm-branch-commits mailing list