[llvm] [WebAssembly] Fix chunk order when reconstructing illegal bitmasks (PR #226824)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 11:56:56 PDT 2026


https://github.com/ParkHanbum created https://github.com/llvm/llvm-project/pull/226824

Shift each chunk bitmask to its original lane offset before combining it.
This preserves the correct lane-to-bit mapping for widened illegal vector
bitcasts.

Fixes https://github.com/llvm/llvm-project/issues/226741

>From 4ccf360203823ae20b8c5ff50e983aec216af645 Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Mon, 28 Sep 2026 03:55:10 +0900
Subject: [PATCH] [WebAssembly] Fix chunk order when reconstructing illegal
 bitmasks

Shift each chunk bitmask to its original lane offset before combining it.
This preserves the correct lane-to-bit mapping for widened illegal vector
bitcasts.

Fixes #226741
---
 .../WebAssembly/WebAssemblyISelLowering.cpp   |  18 +-
 llvm/test/CodeGen/WebAssembly/simd-bitmask.ll | 291 ++++++++++--------
 .../WebAssembly/simd-illegal-bitmask.ll       |  73 ++---
 3 files changed, 217 insertions(+), 165 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 1ecd232782679..6b79ab0a4296d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -3458,17 +3458,23 @@ static SDValue performBitcastCombine(SDNode *N,
       SDValue ExtendedConcatOperandBitmask =
           DAG.getZExtOrTrunc(ConcatOperandBitmask, DL, ReturnVT);
 
-      // Shift the previously reconstructed bits to make room for this chunk.
+      // Shift each chunk's mask to its original lane position before merging it
+      // into the result:
+      //   Result bit index = I * ConcatOperandNumElts + local lane index
+      //
+      // Example: four chunks, each containing 8 mask bits:
+      //   result = M0 | (M1 << 8) | (M2 << 16) | (M3 << 24)
+      //
+      SDValue PositionedChunkBitmask = ExtendedConcatOperandBitmask;
       if (I != 0) {
-        ReconstructedBitmask = DAG.getNode(
-            ISD::SHL, DL, ReturnVT, ReconstructedBitmask,
-            DAG.getShiftAmountConstant(ConcatOperandNumElts, ReturnVT, DL));
+        PositionedChunkBitmask = DAG.getNode(
+            ISD::SHL, DL, ReturnVT, ExtendedConcatOperandBitmask,
+            DAG.getShiftAmountConstant(I * ConcatOperandNumElts, ReturnVT, DL));
       }
 
-      // Merge disjoint partial bitmasks with OR.
       ReconstructedBitmask =
           DAG.getNode(ISD::OR, DL, ReturnVT, ReconstructedBitmask,
-                      ExtendedConcatOperandBitmask);
+                      PositionedChunkBitmask);
     }
 
     return ReconstructedBitmask;
diff --git a/llvm/test/CodeGen/WebAssembly/simd-bitmask.ll b/llvm/test/CodeGen/WebAssembly/simd-bitmask.ll
index 42cdce5833d12..6bca708b6bb4f 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-bitmask.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-bitmask.ll
@@ -182,12 +182,12 @@ define i32 @bitmask_v32i8(<32 x i8> %v) {
 ; CHECK-NEXT:    local.tee 2
 ; CHECK-NEXT:    i8x16.eq
 ; CHECK-NEXT:    i8x16.bitmask
-; CHECK-NEXT:    i32.const 16
-; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 2
 ; CHECK-NEXT:    i8x16.eq
 ; CHECK-NEXT:    i8x16.bitmask
+; CHECK-NEXT:    i32.const 16
+; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <32 x i8> %v, zeroinitializer
@@ -269,10 +269,10 @@ define i32 @manual_bitmask_v32i8(<32 x i8> %v) {
 ; CHECK-NEXT:  # %bb.0:
 ; CHECK-NEXT:    local.get 0
 ; CHECK-NEXT:    i8x16.bitmask
-; CHECK-NEXT:    i32.const 16
-; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    i8x16.bitmask
+; CHECK-NEXT:    i32.const 16
+; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    # fallthrough-return
   %1 = icmp slt <32 x i8> %v, zeroinitializer
@@ -286,23 +286,24 @@ define i64 @manual_bitmask_v64i8(<64 x i8> %v) {
 ; CHECK-NEXT:  # %bb.0:
 ; CHECK-NEXT:    local.get 0
 ; CHECK-NEXT:    i8x16.bitmask
-; CHECK-NEXT:    i32.const 16
-; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i64.extend_i32_u
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    i8x16.bitmask
-; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 32
+; CHECK-NEXT:    i64.const 16
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 2
 ; CHECK-NEXT:    i8x16.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 16
+; CHECK-NEXT:    i64.const 32
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 3
 ; CHECK-NEXT:    i8x16.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 48
+; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    # fallthrough-return
   %1 = icmp slt <64 x i8> %v, zeroinitializer
@@ -320,26 +321,26 @@ define i32 @bitmask_v32i16(<32 x i16> %v) {
 ; CHECK-NEXT:    local.tee 4
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
-; CHECK-NEXT:    i32.const 24
-; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
-; CHECK-NEXT:    i32.const 16
+; CHECK-NEXT:    i32.const 8
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 2
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
-; CHECK-NEXT:    i32.const 8
+; CHECK-NEXT:    i32.const 16
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 3
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
+; CHECK-NEXT:    i32.const 24
+; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <32 x i16> %v, zeroinitializer
@@ -357,54 +358,54 @@ define i32 @bitmask_v32i32(<32 x i32> %v) {
 ; CHECK-NEXT:    local.tee 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.const 12
-; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.const 8
+; CHECK-NEXT:    i32.const 4
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 2
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 8
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 3
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 8
+; CHECK-NEXT:    i32.const 12
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 16
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 5
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 8
+; CHECK-NEXT:    i32.const 20
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 6
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 24
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 7
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
+; CHECK-NEXT:    i32.const 28
+; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <32 x i32> %v, zeroinitializer
@@ -422,110 +423,110 @@ define i32 @bitmask_v32i64(<32 x i64> %v) {
 ; CHECK-NEXT:    local.tee 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 6
-; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 2
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 2
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 4
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 3
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 6
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 8
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 5
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 10
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 6
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 12
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 7
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 14
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 16
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 9
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 18
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 10
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 20
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 11
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 22
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 12
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 24
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 13
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.or
-; CHECK-NEXT:    i32.const 4
+; CHECK-NEXT:    i32.const 26
 ; CHECK-NEXT:    i32.shl
+; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 14
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
-; CHECK-NEXT:    i32.const 2
+; CHECK-NEXT:    i32.const 28
 ; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    local.get 15
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
+; CHECK-NEXT:    i32.const 30
+; CHECK-NEXT:    i32.shl
 ; CHECK-NEXT:    i32.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <32 x i64> %v, zeroinitializer
@@ -544,14 +545,12 @@ define i64 @bitmask_v64i16(<64 x i16> %v) {
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 24
-; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 16
+; CHECK-NEXT:    i64.const 8
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 2
@@ -559,7 +558,7 @@ define i64 @bitmask_v64i16(<64 x i16> %v) {
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 16
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 3
@@ -567,15 +566,15 @@ define i64 @bitmask_v64i16(<64 x i16> %v) {
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 16
+; CHECK-NEXT:    i64.const 24
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 32
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 5
@@ -583,15 +582,15 @@ define i64 @bitmask_v64i16(<64 x i16> %v) {
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 16
+; CHECK-NEXT:    i64.const 40
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 6
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 48
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 7
@@ -599,6 +598,8 @@ define i64 @bitmask_v64i16(<64 x i16> %v) {
 ; CHECK-NEXT:    i16x8.eq
 ; CHECK-NEXT:    i16x8.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 56
+; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <64 x i16> %v, zeroinitializer
@@ -617,14 +618,12 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 12
-; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 4
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 2
@@ -632,7 +631,7 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 8
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 3
@@ -640,15 +639,15 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 12
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 16
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 5
@@ -656,15 +655,15 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 20
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 6
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 24
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 7
@@ -672,15 +671,15 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 28
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 32
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 9
@@ -688,15 +687,15 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 36
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 10
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 40
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 11
@@ -704,15 +703,15 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 44
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 12
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 48
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 13
@@ -720,15 +719,15 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 8
+; CHECK-NEXT:    i64.const 52
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 14
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 56
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 15
@@ -736,6 +735,8 @@ define i64 @bitmask_v64i32(<64 x i32> %v) {
 ; CHECK-NEXT:    i32x4.eq
 ; CHECK-NEXT:    i32x4.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 60
+; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <64 x i32> %v, zeroinitializer
@@ -754,14 +755,12 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 6
-; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 2
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 2
@@ -769,7 +768,7 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 4
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 3
@@ -777,15 +776,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 6
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 4
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 8
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 5
@@ -793,15 +792,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 10
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 6
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 12
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 7
@@ -809,15 +808,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 14
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 8
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 16
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 9
@@ -825,15 +824,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 18
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 10
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 20
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 11
@@ -841,15 +840,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 22
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 12
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 24
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 13
@@ -857,15 +856,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 26
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 14
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 28
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 15
@@ -873,15 +872,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 30
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 16
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 32
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 17
@@ -889,15 +888,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 34
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 18
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 36
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 19
@@ -905,15 +904,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 38
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 20
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 40
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 21
@@ -921,15 +920,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 42
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 22
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 44
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 23
@@ -937,15 +936,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 46
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 24
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 48
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 25
@@ -953,15 +952,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 50
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 26
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 52
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 27
@@ -969,15 +968,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 54
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 28
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 56
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 29
@@ -985,15 +984,15 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.or
-; CHECK-NEXT:    i64.const 4
+; CHECK-NEXT:    i64.const 58
 ; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 30
 ; CHECK-NEXT:    local.get 32
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
-; CHECK-NEXT:    i64.const 2
+; CHECK-NEXT:    i64.const 60
 ; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    local.get 31
@@ -1001,9 +1000,55 @@ define i64 @bitmask_v64i64(<64 x i64> %v) {
 ; CHECK-NEXT:    i64x2.eq
 ; CHECK-NEXT:    i64x2.bitmask
 ; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 62
+; CHECK-NEXT:    i64.shl
 ; CHECK-NEXT:    i64.or
 ; CHECK-NEXT:    # fallthrough-return
   %cmp = icmp eq <64 x i64> %v, zeroinitializer
   %bitmask = bitcast <64 x i1> %cmp to i64
   ret i64 %bitmask
 }
+
+; GH226741: each chunk's mask must retain its original lane positions.
+; Expected: M0 | (M1 << 16) | (M2 << 32) | (M3 << 48).
+; With only lane 0 equal to zero, the result must be 1, not 1 << 48.
+define i64 @bitmask_v64i8(<64 x i8> %v) {
+; CHECK-LABEL: bitmask_v64i8:
+; CHECK:         .functype bitmask_v64i8 (v128, v128, v128, v128) -> (i64)
+; CHECK-NEXT:    .local v128
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+; CHECK-NEXT:    local.tee 4
+; CHECK-NEXT:    i8x16.eq
+; CHECK-NEXT:    i8x16.bitmask
+; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    local.get 1
+; CHECK-NEXT:    local.get 4
+; CHECK-NEXT:    i8x16.eq
+; CHECK-NEXT:    i8x16.bitmask
+; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 16
+; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
+; CHECK-NEXT:    local.get 2
+; CHECK-NEXT:    local.get 4
+; CHECK-NEXT:    i8x16.eq
+; CHECK-NEXT:    i8x16.bitmask
+; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 32
+; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
+; CHECK-NEXT:    local.get 3
+; CHECK-NEXT:    local.get 4
+; CHECK-NEXT:    i8x16.eq
+; CHECK-NEXT:    i8x16.bitmask
+; CHECK-NEXT:    i64.extend_i32_u
+; CHECK-NEXT:    i64.const 48
+; CHECK-NEXT:    i64.shl
+; CHECK-NEXT:    i64.or
+; CHECK-NEXT:    # fallthrough-return
+  %cmp = icmp eq <64 x i8> %v, zeroinitializer
+  %bitmask = bitcast <64 x i1> %cmp to i64
+  ret i64 %bitmask
+}
diff --git a/llvm/test/CodeGen/WebAssembly/simd-illegal-bitmask.ll b/llvm/test/CodeGen/WebAssembly/simd-illegal-bitmask.ll
index 314b3247ee06b..9675a32cff49d 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-illegal-bitmask.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-illegal-bitmask.ll
@@ -24,13 +24,13 @@ define i32 @optimize_illegal_bitcast_v32i8(<32 x i8> %x) {
 ; CHECK-NEXT:  # %bb.0:
 ; CHECK-NEXT:    v128.const $push8=, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
 ; CHECK-NEXT:    local.tee $push7=, $2=, $pop8
-; CHECK-NEXT:    i8x16.eq $push0=, $0, $pop7
+; CHECK-NEXT:    i8x16.eq $push4=, $0, $pop7
+; CHECK-NEXT:    i8x16.bitmask $push5=, $pop4
+; CHECK-NEXT:    i8x16.eq $push0=, $1, $2
 ; CHECK-NEXT:    i8x16.bitmask $push1=, $pop0
 ; CHECK-NEXT:    i32.const $push2=, 16
 ; CHECK-NEXT:    i32.shl $push3=, $pop1, $pop2
-; CHECK-NEXT:    i8x16.eq $push4=, $1, $2
-; CHECK-NEXT:    i8x16.bitmask $push5=, $pop4
-; CHECK-NEXT:    i32.or $push6=, $pop3, $pop5
+; CHECK-NEXT:    i32.or $push6=, $pop5, $pop3
 ; CHECK-NEXT:    return $pop6
     %z = icmp eq <32 x i8> %x, splat (i8 32)
     %res = bitcast <32 x i1> %z to i32
@@ -42,15 +42,15 @@ define i32 @optimize_illegal_bitcast_v32i8_const_step_vec(<32 x i8> %x) {
 ; CHECK-LABEL: optimize_illegal_bitcast_v32i8_const_step_vec:
 ; CHECK:         .functype optimize_illegal_bitcast_v32i8_const_step_vec (v128, v128) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    v128.const $push0=, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
-; CHECK-NEXT:    i8x16.eq $push1=, $0, $pop0
+; CHECK-NEXT:    v128.const $push5=, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
+; CHECK-NEXT:    i8x16.eq $push6=, $0, $pop5
+; CHECK-NEXT:    i8x16.bitmask $push7=, $pop6
+; CHECK-NEXT:    v128.const $push0=, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
+; CHECK-NEXT:    i8x16.eq $push1=, $1, $pop0
 ; CHECK-NEXT:    i8x16.bitmask $push2=, $pop1
 ; CHECK-NEXT:    i32.const $push3=, 16
 ; CHECK-NEXT:    i32.shl $push4=, $pop2, $pop3
-; CHECK-NEXT:    v128.const $push5=, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
-; CHECK-NEXT:    i8x16.eq $push6=, $1, $pop5
-; CHECK-NEXT:    i8x16.bitmask $push7=, $pop6
-; CHECK-NEXT:    i32.or $push8=, $pop4, $pop7
+; CHECK-NEXT:    i32.or $push8=, $pop7, $pop4
 ; CHECK-NEXT:    return $pop8
     %const_step_vec =  add <32 x i8> <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8,
                               i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15, i8 16,
@@ -66,13 +66,13 @@ define i32 @optimize_illegal_bitcast_v32i8_non_const_vec(<32 x i8> %x, <32 x i8>
 ; CHECK-LABEL: optimize_illegal_bitcast_v32i8_non_const_vec:
 ; CHECK:         .functype optimize_illegal_bitcast_v32i8_non_const_vec (v128, v128, v128, v128) -> (i32)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    i8x16.eq $push0=, $0, $2
+; CHECK-NEXT:    i8x16.eq $push4=, $0, $2
+; CHECK-NEXT:    i8x16.bitmask $push5=, $pop4
+; CHECK-NEXT:    i8x16.eq $push0=, $1, $3
 ; CHECK-NEXT:    i8x16.bitmask $push1=, $pop0
 ; CHECK-NEXT:    i32.const $push2=, 16
 ; CHECK-NEXT:    i32.shl $push3=, $pop1, $pop2
-; CHECK-NEXT:    i8x16.eq $push4=, $1, $3
-; CHECK-NEXT:    i8x16.bitmask $push5=, $pop4
-; CHECK-NEXT:    i32.or $push6=, $pop3, $pop5
+; CHECK-NEXT:    i32.or $push6=, $pop5, $pop3
 ; CHECK-NEXT:    return $pop6
     %z = icmp eq <32 x i8> %x, %y
     %res = bitcast <32 x i1> %z to i32
@@ -86,29 +86,30 @@ define i64 @optimize_illegal_bitcast_v64i8(<64 x i8> %x) {
 ; CHECK-LABEL: optimize_illegal_bitcast_v64i8:
 ; CHECK:         .functype optimize_illegal_bitcast_v64i8 (v128, v128, v128, v128) -> (i64)
 ; CHECK-NEXT:  # %bb.0:
-; CHECK-NEXT:    v128.const $push21=, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-; CHECK-NEXT:    local.tee $push20=, $4=, $pop21
-; CHECK-NEXT:    i8x16.eq $push0=, $0, $pop20
-; CHECK-NEXT:    i8x16.bitmask $push1=, $pop0
-; CHECK-NEXT:    i32.const $push2=, 16
-; CHECK-NEXT:    i32.shl $push3=, $pop1, $pop2
-; CHECK-NEXT:    i8x16.eq $push4=, $1, $4
-; CHECK-NEXT:    i8x16.bitmask $push5=, $pop4
-; CHECK-NEXT:    i32.or $push6=, $pop3, $pop5
+; CHECK-NEXT:    v128.const $push22=, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+; CHECK-NEXT:    local.tee $push21=, $4=, $pop22
+; CHECK-NEXT:    i8x16.eq $push5=, $0, $pop21
+; CHECK-NEXT:    i8x16.bitmask $push6=, $pop5
 ; CHECK-NEXT:    i64.extend_i32_u $push7=, $pop6
-; CHECK-NEXT:    i64.const $push8=, 32
-; CHECK-NEXT:    i64.shl $push9=, $pop7, $pop8
-; CHECK-NEXT:    i8x16.eq $push10=, $2, $4
-; CHECK-NEXT:    i8x16.bitmask $push11=, $pop10
-; CHECK-NEXT:    i64.extend_i32_u $push12=, $pop11
-; CHECK-NEXT:    i64.const $push13=, 16
-; CHECK-NEXT:    i64.shl $push14=, $pop12, $pop13
-; CHECK-NEXT:    i64.or $push15=, $pop9, $pop14
-; CHECK-NEXT:    i8x16.eq $push16=, $3, $4
-; CHECK-NEXT:    i8x16.bitmask $push17=, $pop16
-; CHECK-NEXT:    i64.extend_i32_u $push18=, $pop17
-; CHECK-NEXT:    i64.or $push19=, $pop15, $pop18
-; CHECK-NEXT:    return $pop19
+; CHECK-NEXT:    i8x16.eq $push0=, $1, $4
+; CHECK-NEXT:    i8x16.bitmask $push1=, $pop0
+; CHECK-NEXT:    i64.extend_i32_u $push2=, $pop1
+; CHECK-NEXT:    i64.const $push3=, 16
+; CHECK-NEXT:    i64.shl $push4=, $pop2, $pop3
+; CHECK-NEXT:    i64.or $push8=, $pop7, $pop4
+; CHECK-NEXT:    i8x16.eq $push9=, $2, $4
+; CHECK-NEXT:    i8x16.bitmask $push10=, $pop9
+; CHECK-NEXT:    i64.extend_i32_u $push11=, $pop10
+; CHECK-NEXT:    i64.const $push12=, 32
+; CHECK-NEXT:    i64.shl $push13=, $pop11, $pop12
+; CHECK-NEXT:    i64.or $push14=, $pop8, $pop13
+; CHECK-NEXT:    i8x16.eq $push15=, $3, $4
+; CHECK-NEXT:    i8x16.bitmask $push16=, $pop15
+; CHECK-NEXT:    i64.extend_i32_u $push17=, $pop16
+; CHECK-NEXT:    i64.const $push18=, 48
+; CHECK-NEXT:    i64.shl $push19=, $pop17, $pop18
+; CHECK-NEXT:    i64.or $push20=, $pop14, $pop19
+; CHECK-NEXT:    return $pop20
     %z = icmp eq <64 x i8> %x, splat (i8 64)
     %res = bitcast <64 x i1> %z to i64
     ret i64 %res



More information about the llvm-commits mailing list