[llvm] [WebAssembly] Fix the i32x4 case of simd splat shuffle cost (PR #191964)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 13 23:23:05 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly

@llvm/pr-subscribers-llvm-transforms

Author: Jasmine Tang (badumbatish)

<details>
<summary>Changes</summary>

Inspiration taken from llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp's AArch64TTIImpl::getVectorInstrCost

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


2 Files Affected:

- (modified) llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp (+7) 
- (modified) llvm/test/Transforms/SLPVectorizer/WebAssembly/simd-splat-shuffle-cost.ll (+11-17) 


``````````diff
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp
index 1bd3a6b950944..0b2f84d42cd2e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp
@@ -406,6 +406,13 @@ InstructionCost WebAssemblyTTIImpl::getInterleavedMemoryOpCost(
 InstructionCost WebAssemblyTTIImpl::getVectorInstrCost(
     unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
     const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
+  // Treat insert at lane 0 into a poison vector as having zero cost. The
+  // insert + broadcast shuffle pair will be lowered to a single splat
+  // instruction, so the insert is free.
+  if (Opcode == Instruction::InsertElement && Index == 0 && Op0 &&
+      isa<PoisonValue>(Op0))
+    return 0;
+
   InstructionCost Cost = BasicTTIImplBase::getVectorInstrCost(
       Opcode, Val, CostKind, Index, Op0, Op1, VIC);
 
diff --git a/llvm/test/Transforms/SLPVectorizer/WebAssembly/simd-splat-shuffle-cost.ll b/llvm/test/Transforms/SLPVectorizer/WebAssembly/simd-splat-shuffle-cost.ll
index c1ea504a0c140..fc3fc012fda88 100644
--- a/llvm/test/Transforms/SLPVectorizer/WebAssembly/simd-splat-shuffle-cost.ll
+++ b/llvm/test/Transforms/SLPVectorizer/WebAssembly/simd-splat-shuffle-cost.ll
@@ -132,13 +132,9 @@ entry:
 define void @splat_i32x4(i32 %v, ptr noalias %p) {
 ; SIMD128-LABEL: @splat_i32x4(
 ; SIMD128-NEXT:  entry:
-; SIMD128-NEXT:    store i32 [[V:%.*]], ptr [[P:%.*]], align 1
-; SIMD128-NEXT:    [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4
-; SIMD128-NEXT:    store i32 [[V]], ptr [[IDX1]], align 1
-; SIMD128-NEXT:    [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8
-; SIMD128-NEXT:    store i32 [[V]], ptr [[IDX2]], align 1
-; SIMD128-NEXT:    [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12
-; SIMD128-NEXT:    store i32 [[V]], ptr [[IDX3]], align 1
+; SIMD128-NEXT:    [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[V:%.*]], i32 0
+; SIMD128-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <4 x i32> zeroinitializer
+; SIMD128-NEXT:    store <4 x i32> [[TMP1]], ptr [[P:%.*]], align 1
 ; SIMD128-NEXT:    ret void
 ;
 ; NO-SIMD128-LABEL: @splat_i32x4(
@@ -189,13 +185,9 @@ entry:
 define void @splat_f32x4(float %v, ptr noalias %p) {
 ; SIMD128-LABEL: @splat_f32x4(
 ; SIMD128-NEXT:  entry:
-; SIMD128-NEXT:    store float [[V:%.*]], ptr [[P:%.*]], align 1
-; SIMD128-NEXT:    [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4
-; SIMD128-NEXT:    store float [[V]], ptr [[IDX1]], align 1
-; SIMD128-NEXT:    [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8
-; SIMD128-NEXT:    store float [[V]], ptr [[IDX2]], align 1
-; SIMD128-NEXT:    [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12
-; SIMD128-NEXT:    store float [[V]], ptr [[IDX3]], align 1
+; SIMD128-NEXT:    [[TMP0:%.*]] = insertelement <4 x float> poison, float [[V:%.*]], i32 0
+; SIMD128-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[TMP0]], <4 x float> poison, <4 x i32> zeroinitializer
+; SIMD128-NEXT:    store <4 x float> [[TMP1]], ptr [[P:%.*]], align 1
 ; SIMD128-NEXT:    ret void
 ;
 ; NO-SIMD128-LABEL: @splat_f32x4(
@@ -245,9 +237,11 @@ entry:
 define void @splat_i32x8(i32 %v, ptr noalias %p) {
 ; SIMD128-LABEL: @splat_i32x8(
 ; SIMD128-NEXT:  entry:
-; SIMD128-NEXT:    [[TMP0:%.*]] = insertelement <8 x i32> poison, i32 [[V:%.*]], i32 0
-; SIMD128-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i32> [[TMP0]], <8 x i32> poison, <8 x i32> zeroinitializer
-; SIMD128-NEXT:    store <8 x i32> [[TMP1]], ptr [[P:%.*]], align 1
+; SIMD128-NEXT:    [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[V:%.*]], i32 0
+; SIMD128-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <4 x i32> zeroinitializer
+; SIMD128-NEXT:    store <4 x i32> [[TMP1]], ptr [[P:%.*]], align 1
+; SIMD128-NEXT:    [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 16
+; SIMD128-NEXT:    store <4 x i32> [[TMP1]], ptr [[IDX4]], align 1
 ; SIMD128-NEXT:    ret void
 ;
 ; NO-SIMD128-LABEL: @splat_i32x8(

``````````

</details>


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


More information about the llvm-commits mailing list