[llvm] [WebAssembly] Fold extended vector shifts by constant to extmul (PR #184007)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 04:27:22 PST 2026
================
@@ -2797,9 +2797,81 @@ static SDValue unrollVectorShift(SDValue Op, SelectionDAG &DAG) {
return DAG.getBuildVector(Op.getValueType(), DL, UnrolledOps);
}
+/// Convert a vector shift of an extended value into a multiplication of
+/// extended values. By converting the shift amount to a multiplier (1 << C)
+/// and wrapping it in a matching extend node, we enable the instruction
+/// selector to match the pattern to WebAssembly extended multiplication
+/// instructions (e.g., i32x4.extmul_low_i16x8_s). Inactive lanes in the
+/// multiplier vector are populated with undefs.
+///
+/// Example transformation:
+/// Before:
+/// t1: v8i16 = ...
+/// t2: v4i32 = WebAssemblyISD::EXTEND_LOW_S t1
+/// t3: v4i32 = BUILD_VECTOR Constant:i32<12>, Constant:i32<0>, ...
+/// t4: v4i32 = shl t2, t3
+///
+/// After:
+/// t1: v8i16 = ...
+/// t2: v4i32 = WebAssemblyISD::EXTEND_LOW_S t1
+/// t3: v8i16 = BUILD_VECTOR Constant:i16<4096>, Constant:i16<1>, undef, ...
+/// t4: v4i32 = WebAssemblyISD::EXTEND_LOW_S t3 t5: v4i32 = mul t2, t4
+static SDValue foldShiftByConstantToExtMul(SDValue Op, SelectionDAG &DAG) {
+ if (Op.getOpcode() != ISD::SHL || !Op.getValueType().isVector())
+ return SDValue();
+
+ SDValue RHS = Op.getOperand(1);
+ if (RHS.getOpcode() != ISD::BUILD_VECTOR)
----------------
ParkHanbum wrote:
In debugging messages, it is the shape of BUILD_VECTOR even at the earliest stage.
---- Branch Probability Info : combine_with_constant ----
Computing probabilities for
FastISel is disabled
********** ISelDAGToDAG **********
********** Function: combine_with_constant
=== combine_with_constant
Creating constant: t1: i32 = TargetConstant<0>
Creating new node: t2: v8i16 = WebAssemblyISD::ARGUMENT TargetConstant:i32<0>
Creating new node: t3: v8i32 = sign_extend t2
Creating constant: t4: i32 = Constant<4096>
Creating constant: t5: i32 = Constant<1>
Creating new node: t6: v8i32 = BUILD_VECTOR Constant:i32<4096>, Constant:i32<1>, Constant:i32<4096>, Constant:i32<1>, Constant:i32<4096>, Constant:i32<1>, Constant:i32<4096>, Constant:i32<1>
Creating new node: t7: v8i32 = mul nsw t3, t6
Creating new node: t8: v8i32 = poison
I think this is where the constant node is used.
Vector/type-legalized selection DAG: %bb.0 'combine_with_constant:'
SelectionDAG has 28 nodes:
t2: v8i16 = WebAssemblyISD::ARGUMENT TargetConstant:i32<0>
t58: v4i32 = WebAssemblyISD::EXTEND_LOW_S t2
t59: v4i32 = WebAssemblyISD::EXTEND_HIGH_S t2
t60: i32 = extract_vector_elt t58, Constant:i32<0>
t61: i32 = shl t60, Constant:i32<12>
t63: i32 = extract_vector_elt t58, Constant:i32<1>
t65: i32 = extract_vector_elt t58, Constant:i32<2>
t66: i32 = shl t65, Constant:i32<12>
https://github.com/llvm/llvm-project/pull/184007
More information about the llvm-commits
mailing list