[llvm] 0813837 - [WebAssembly][DAGCombine] Avoid scalarizing v8i8 to v8f16 conversions (#213636)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 21:05:49 PDT 2026


Author: Anutosh Bhat
Date: 2026-08-12T04:05:44Z
New Revision: 0813837aca85ce6c6c508cacd5a59db2f59284f2

URL: https://github.com/llvm/llvm-project/commit/0813837aca85ce6c6c508cacd5a59db2f59284f2
DIFF: https://github.com/llvm/llvm-project/commit/0813837aca85ce6c6c508cacd5a59db2f59284f2.diff

LOG: [WebAssembly][DAGCombine] Avoid scalarizing v8i8 to v8f16 conversions (#213636)

WebAssembly FP16 can convert `v8i16` to `v8f16`, but direct `v8i8` to
`v8f16` conversions were scalarized during SelectionDAG type
legalization.

This results in lane extractions, scalar conversions, calls to
`__truncsfhf2`, and reconstruction of the result vector.

We should extend `v8i8` to `v8i16` in `performVectorExtendToFPCombine`
before type legalization. This allows the existing WebAssembly combines
to select:

- `i16x8.extend_low_i8x16_{s,u}`
- `f16x8.convert_i16x8_s`

Added: 
    

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/test/CodeGen/WebAssembly/simd-extending-convert.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 8c14ffced3425..bd8c9169eabba 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -3014,8 +3014,8 @@ performVECTOR_SHUFFLECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
 /// split up into scalar instructions during legalization, and the vector
 /// extending instructions are selected in performVectorExtendCombine below.
 static SDValue
-performVectorExtendToFPCombine(SDNode *N,
-                               TargetLowering::DAGCombinerInfo &DCI) {
+performVectorExtendToFPCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
+                               const WebAssemblySubtarget *Subtarget) {
   auto &DAG = DCI.DAG;
   assert(N->getOpcode() == ISD::UINT_TO_FP ||
          N->getOpcode() == ISD::SINT_TO_FP);
@@ -3027,6 +3027,8 @@ performVectorExtendToFPCombine(SDNode *N,
     ExtVT = MVT::v4i32;
   else if (ResVT == MVT::v2f64 && (InVT == MVT::v2i16 || InVT == MVT::v2i8))
     ExtVT = MVT::v2i32;
+  else if (Subtarget->hasFP16() && ResVT == MVT::v8f16 && InVT == MVT::v8i8)
+    ExtVT = MVT::v8i16;
   else
     return SDValue();
 
@@ -4041,11 +4043,11 @@ WebAssemblyTargetLowering::PerformDAGCombine(SDNode *N,
   case ISD::ZERO_EXTEND:
     return performVectorExtendCombine(N, DCI);
   case ISD::UINT_TO_FP:
-    if (auto ExtCombine = performVectorExtendToFPCombine(N, DCI))
+    if (auto ExtCombine = performVectorExtendToFPCombine(N, DCI, Subtarget))
       return ExtCombine;
     return performVectorNonNegToFPCombine(N, DCI);
   case ISD::SINT_TO_FP:
-    return performVectorExtendToFPCombine(N, DCI);
+    return performVectorExtendToFPCombine(N, DCI, Subtarget);
   case ISD::FP_TO_SINT_SAT:
   case ISD::FP_TO_UINT_SAT:
   case ISD::FP_ROUND:

diff  --git a/llvm/test/CodeGen/WebAssembly/simd-extending-convert.ll b/llvm/test/CodeGen/WebAssembly/simd-extending-convert.ll
index eb39f90e68701..c51b3385ab134 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-extending-convert.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-extending-convert.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mattr=+simd128 | FileCheck %s
+; RUN: llc < %s -mattr=+simd128,+fp16 | FileCheck %s --check-prefixes=CHECK,FP16
 
 ; TODO: These tests should check that floating point conversions select
 ; extending instructions where possible
@@ -142,3 +143,27 @@ define <2 x double> @extend_to_double_low_i16x4_u(<4 x i16> %x) {
   %extended = uitofp <2 x i16> %low to <2 x double>
   ret <2 x double> %extended
 }
+
+define <8 x half> @extend_to_half_low_i8x16_u(<8 x i8> %x) {
+; FP16-LABEL: extend_to_half_low_i8x16_u:
+; FP16:         .functype extend_to_half_low_i8x16_u (v128) -> (v128)
+; FP16-NEXT:  # %bb.0:
+; FP16-NEXT:    local.get 0
+; FP16-NEXT:    i16x8.extend_low_i8x16_u
+; FP16-NEXT:    f16x8.convert_i16x8_s
+; FP16-NEXT:    # fallthrough-return
+  %extended = uitofp <8 x i8> %x to <8 x half>
+  ret <8 x half> %extended
+}
+
+define <8 x half> @extend_to_half_low_i8x16_s(<8 x i8> %x) {
+; FP16-LABEL: extend_to_half_low_i8x16_s:
+; FP16:         .functype extend_to_half_low_i8x16_s (v128) -> (v128)
+; FP16-NEXT:  # %bb.0:
+; FP16-NEXT:    local.get 0
+; FP16-NEXT:    i16x8.extend_low_i8x16_s
+; FP16-NEXT:    f16x8.convert_i16x8_s
+; FP16-NEXT:    # fallthrough-return
+  %extended = sitofp <8 x i8> %x to <8 x half>
+  ret <8 x half> %extended
+}


        


More information about the llvm-commits mailing list