[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