[llvm] [WebAssembly] Fix chunk order when reconstructing illegal bitmasks (PR #226824)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 27 23:55:46 PDT 2026
https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/226824
>From a99aaef59804216b15530014abf8af8625009c4e 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 | 21 +-
llvm/test/CodeGen/WebAssembly/simd-bitmask.ll | 291 ++++++++++--------
.../WebAssembly/simd-illegal-bitmask.ll | 73 ++---
3 files changed, 218 insertions(+), 167 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 1ecd232782679..f4375f489f9b1 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -3458,17 +3458,22 @@ 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);
+ ReconstructedBitmask = DAG.getNode(
+ ISD::OR, DL, ReturnVT, ReconstructedBitmask, 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