[llvm] 22f5353 - [WebAssembly] Combine shuffle and signed extend to extend_high (#179166)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 3 00:02:58 PST 2026


Author: hanbeom
Date: 2026-02-03T17:02:53+09:00
New Revision: 22f53531d7a944c95666de0eca5790ee4b0cf008

URL: https://github.com/llvm/llvm-project/commit/22f53531d7a944c95666de0eca5790ee4b0cf008
DIFF: https://github.com/llvm/llvm-project/commit/22f53531d7a944c95666de0eca5790ee4b0cf008.diff

LOG: [WebAssembly] Combine shuffle and signed extend to extend_high (#179166)

Fold shuffles and bitcasts feeding extend_low_s into extend_high_s.
This enables i32x4.dot_i16x8_s selection and removes redundant shuffles.

Fixed: https://github.com/llvm/llvm-project/issues/179145

Added: 
    

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index abd5b0c0ad9d6..2799b0ee0c804 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -2294,13 +2294,14 @@ WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
 
 static SDValue GetExtendHigh(SDValue Op, unsigned UserOpc, EVT VT,
                              SelectionDAG &DAG) {
-  if (Op.getOpcode() != ISD::VECTOR_SHUFFLE)
+  SDValue Source = peekThroughBitcasts(Op);
+  if (Source.getOpcode() != ISD::VECTOR_SHUFFLE)
     return SDValue();
 
   assert((UserOpc == WebAssemblyISD::EXTEND_LOW_U ||
           UserOpc == WebAssemblyISD::EXTEND_LOW_S) &&
          "expected extend_low");
-  auto *Shuffle = cast<ShuffleVectorSDNode>(Op.getNode());
+  auto *Shuffle = cast<ShuffleVectorSDNode>(Source.getNode());
 
   ArrayRef<int> Mask = Shuffle->getMask();
   // Look for a shuffle which moves from the high half to the low half.
@@ -2315,7 +2316,11 @@ static SDValue GetExtendHigh(SDValue Op, unsigned UserOpc, EVT VT,
   unsigned Opc = UserOpc == WebAssemblyISD::EXTEND_LOW_S
                      ? WebAssemblyISD::EXTEND_HIGH_S
                      : WebAssemblyISD::EXTEND_HIGH_U;
-  return DAG.getNode(Opc, DL, VT, Shuffle->getOperand(0));
+  SDValue ShuffleSrc = Shuffle->getOperand(0);
+  if (Op.getOpcode() == ISD::BITCAST)
+    ShuffleSrc = DAG.getBitcast(Op.getValueType(), ShuffleSrc);
+
+  return DAG.getNode(Opc, DL, VT, ShuffleSrc);
 }
 
 SDValue

diff  --git a/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll b/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll
index 3654aaec18600..d9e5aba6f9b94 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll
@@ -104,3 +104,40 @@ define <4 x i32> @dot_wrong_shuffle(<8 x i16> %a, <8 x i16> %b) {
   %res = add <4 x i32> %shuffle1, %shuffle2
   ret <4 x i32> %res
 }
+
+define dso_local <4 x i32> @dot_with_bitcast_both(<4 x i32> %a, <4 x i32> %b) unnamed_addr {
+; CHECK-LABEL: dot_with_bitcast_both:
+; CHECK:         .functype dot_with_bitcast_both (v128, v128) -> (v128)
+; CHECK-NEXT:  # %bb.0: # %start
+; CHECK-NEXT:    local.get 1
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    i32x4.dot_i16x8_s
+; CHECK-NEXT:    # fallthrough-return
+start:
+  %_4 = bitcast <4 x i32> %a to <8 x i16>
+  %_5 = bitcast <4 x i32> %b to <8 x i16>
+  %0 = sext <8 x i16> %_4 to <8 x i32>
+  %1 = sext <8 x i16> %_5 to <8 x i32>
+  %2 = mul nsw <8 x i32> %1, %0
+  %3 = shufflevector <8 x i32> %2, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+  %4 = shufflevector <8 x i32> %2, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+  %5 = add <4 x i32> %3, %4
+  ret <4 x i32> %5
+}
+
+define <4 x i32> @dot_with_bitcast_one(<4 x i32> %a) {
+; CHECK-LABEL: dot_with_bitcast_one:
+; CHECK:         .functype dot_with_bitcast_one (v128) -> (v128)
+; CHECK-NEXT:  # %bb.0: # %start
+; CHECK-NEXT:    local.get 0
+; CHECK-NEXT:    i32x4.extadd_pairwise_i16x8_s
+; CHECK-NEXT:    # fallthrough-return
+start:
+  %a1 = bitcast <4 x i32> %a to <8 x i16>
+  %0 = shufflevector <8 x i16> %a1, <8 x i16> %a1, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+  %1 = shufflevector <8 x i16> %a1, <8 x i16> %a1, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+  %2 = sext <4 x i16> %0 to <4 x i32>
+  %3 = sext <4 x i16> %1 to <4 x i32>
+  %4 = add nsw <4 x i32> %2, %3
+  ret <4 x i32> %4
+}


        


More information about the llvm-commits mailing list