[llvm] 693d767 - [WebAssembly] More codegen for f64x2.convert_low_i32x4_{s, u}
Thomas Lively via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 20 12:37:23 PDT 2021
Author: Thomas Lively
Date: 2021-04-20T12:37:13-07:00
New Revision: 693d767c60933c41abb8663e8b347c2d91240645
URL: https://github.com/llvm/llvm-project/commit/693d767c60933c41abb8663e8b347c2d91240645
DIFF: https://github.com/llvm/llvm-project/commit/693d767c60933c41abb8663e8b347c2d91240645.diff
LOG: [WebAssembly] More codegen for f64x2.convert_low_i32x4_{s,u}
af7925b4dd65 added a custom DAG combine for recognizing fp-to-ints of
extract_subvectors that could be lowered to f64x2.convert_low_i32x4_{s,u}
instructions. This commit extends the combines to recognize equivalent
extract_subvectors of fp-to-ints as well.
Differential Revision: https://reviews.llvm.org/D100790
Added:
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/test/CodeGen/WebAssembly/simd-conversions.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index f4e48883db5d..7054ed9d48c5 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -135,9 +135,10 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
setTargetDAGCombine(ISD::SIGN_EXTEND);
setTargetDAGCombine(ISD::ZERO_EXTEND);
- // Combine {s,u}int_to_fp of extract_vectors into conversion ops
+ // Combine int_to_fp of extract_vectors and vice versa into conversions ops
setTargetDAGCombine(ISD::SINT_TO_FP);
setTargetDAGCombine(ISD::UINT_TO_FP);
+ setTargetDAGCombine(ISD::EXTRACT_SUBVECTOR);
// Combine concat of {s,u}int_to_fp_sat to i32x4.trunc_sat_f64x2_zero_{s,u}
setTargetDAGCombine(ISD::CONCAT_VECTORS);
@@ -2062,36 +2063,65 @@ static SDValue
performVectorConvertLowCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI) {
auto &DAG = DCI.DAG;
- assert(N->getOpcode() == ISD::SINT_TO_FP ||
- N->getOpcode() == ISD::UINT_TO_FP);
- // Combine ({s,u}int_to_fp (extract_subvector ... 0)) to an
- // f64x2.convert_low_i32x4_{s,u} SDNode.
- auto Extract = N->getOperand(0);
- if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
- return SDValue();
- auto Source = Extract.getOperand(0);
- if (Source.getValueType() != MVT::v4i32)
- return SDValue();
- auto *IndexNode = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
- if (IndexNode == nullptr)
- return SDValue();
- auto Index = IndexNode->getZExtValue();
-
- // The types must be correct.
EVT ResVT = N->getValueType(0);
- if (ResVT != MVT::v2f64 || Extract.getValueType() != MVT::v2i32)
+ if (ResVT != MVT::v2f64)
return SDValue();
- // The extracted vector must be the low half.
- if (Index != 0)
- return SDValue();
+ if (N->getOpcode() == ISD::SINT_TO_FP || N->getOpcode() == ISD::UINT_TO_FP) {
+ // Combine this:
+ //
+ // (v2f64 ({s,u}int_to_fp
+ // (v2i32 (extract_subvector (v4i32 $x), 0))))
+ //
+ // into (f64x2.convert_low_i32x4_{s,u} $x).
+ auto Extract = N->getOperand(0);
+ if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
+ return SDValue();
+ if (Extract.getValueType() != MVT::v2i32)
+ return SDValue();
+ auto Source = Extract.getOperand(0);
+ if (Source.getValueType() != MVT::v4i32)
+ return SDValue();
+ auto *IndexNode = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
+ if (IndexNode == nullptr || IndexNode->getZExtValue() != 0)
+ return SDValue();
+
+ unsigned Op = N->getOpcode() == ISD::SINT_TO_FP
+ ? WebAssemblyISD::CONVERT_LOW_S
+ : WebAssemblyISD::CONVERT_LOW_U;
+
+ return DAG.getNode(Op, SDLoc(N), ResVT, Source);
+
+ } else if (N->getOpcode() == ISD::EXTRACT_SUBVECTOR) {
+ // Combine this:
+ //
+ // (v2f64 (extract_subvector
+ // (v4f64 ({s,u}int_to_fp (v4i32 $x))), 0))
+ //
+ // into (f64x2.convert_low_i32x4_{s,u} $x).
+ auto IntToFP = N->getOperand(0);
+ if (IntToFP.getOpcode() != ISD::SINT_TO_FP &&
+ IntToFP.getOpcode() != ISD::UINT_TO_FP)
+ return SDValue();
+ if (IntToFP.getValueType() != MVT::v4f64)
+ return SDValue();
+ auto Source = IntToFP.getOperand(0);
+ if (Source.getValueType() != MVT::v4i32)
+ return SDValue();
+ auto IndexNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ if (IndexNode == nullptr || IndexNode->getZExtValue() != 0)
+ return SDValue();
- unsigned Op = N->getOpcode() == ISD::SINT_TO_FP
- ? WebAssemblyISD::CONVERT_LOW_S
- : WebAssemblyISD::CONVERT_LOW_U;
+ unsigned Op = IntToFP->getOpcode() == ISD::SINT_TO_FP
+ ? WebAssemblyISD::CONVERT_LOW_S
+ : WebAssemblyISD::CONVERT_LOW_U;
- return DAG.getNode(Op, SDLoc(N), ResVT, Source);
+ return DAG.getNode(Op, SDLoc(N), ResVT, Source);
+
+ } else {
+ llvm_unreachable("unexpected opcode");
+ }
}
static SDValue
@@ -2150,6 +2180,7 @@ WebAssemblyTargetLowering::PerformDAGCombine(SDNode *N,
return performVectorExtendCombine(N, DCI);
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP:
+ case ISD::EXTRACT_SUBVECTOR:
return performVectorConvertLowCombine(N, DCI);
case ISD::CONCAT_VECTORS:
return performVectorTruncSatLowCombine(N, DCI);
diff --git a/llvm/test/CodeGen/WebAssembly/simd-conversions.ll b/llvm/test/CodeGen/WebAssembly/simd-conversions.ll
index 431d55922040..94832a42d18e 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-conversions.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-conversions.ll
@@ -103,3 +103,26 @@ define <2 x double> @convert_low_u_v2f64(<4 x i32> %x) {
%a = uitofp <2 x i32> %v to <2 x double>
ret <2 x double> %a
}
+
+
+; CHECK-LABEL: convert_low_s_v2f64_2:
+; NO-SIMD128-NOT: f64x2
+; SIMD128-NEXT: .functype convert_low_s_v2f64_2 (v128) -> (v128){{$}}
+; SIMD128-NEXT: f64x2.convert_low_i32x4_s $push[[R:[0-9]+]]=, $0
+; SIMD128-NEXT: return $pop[[R]]
+define <2 x double> @convert_low_s_v2f64_2(<4 x i32> %x) {
+ %v = sitofp <4 x i32> %x to <4 x double>
+ %a = shufflevector <4 x double> %v, <4 x double> undef, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %a
+}
+
+; CHECK-LABEL: convert_low_u_v2f64_2:
+; NO-SIMD128-NOT: f64x2
+; SIMD128-NEXT: .functype convert_low_u_v2f64_2 (v128) -> (v128){{$}}
+; SIMD128-NEXT: f64x2.convert_low_i32x4_u $push[[R:[0-9]+]]=, $0
+; SIMD128-NEXT: return $pop[[R]]
+define <2 x double> @convert_low_u_v2f64_2(<4 x i32> %x) {
+ %v = uitofp <4 x i32> %x to <4 x double>
+ %a = shufflevector <4 x double> %v, <4 x double> undef, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %a
+}
More information about the llvm-commits
mailing list