================
@@ -5205,55 +5205,75 @@ AArch64TargetLowering::LowerVectorFP_TO_INT_SAT(SDValue 
Op,
     return SDValue();
 
   EVT SrcElementVT = SrcVT.getVectorElementType();
+  if (SrcElementVT != MVT::f64 && SrcElementVT != MVT::f32 &&
+      SrcElementVT != MVT::f16 && SrcElementVT != MVT::bf16)
+    return SDValue();
+
+  // Returns true if the operation can be matched by an isel pattern directly.
+  auto CanHandleNatively = [&DstVT, &SatWidth](EVT SrcVT) -> bool {
+    return SrcVT.getScalarSizeInBits() == DstVT.getScalarSizeInBits() &&
+           SrcVT.getScalarSizeInBits() == SatWidth;
+  };
+
+  // Returns true if the operation is best expanded.
+  auto Expand = [&DstVT, &SatWidth, &CanHandleNatively](EVT SrcVT) -> bool {
+    return !CanHandleNatively(SrcVT) &&
+           (SrcVT.getScalarSizeInBits() < SatWidth ||
+            // NEON has no vector MIN/MAX for i64, so it's simpler to scalarize
+            // (at least until sqxtn is selected).
+            SrcVT.getVectorElementType() == MVT::f64);
+  };
+
+  // Try to promote the operation to a wider type if SrcVT < DstVT,
+  // or if type is bf16 or if the target has no +fullfp16.
+  EVT PromVT = SrcVT;
+  switch (SrcVT.getVectorElementType().getSimpleVT().SimpleTy) {
+  case MVT::f16:
+  case MVT::bf16:
+    if (DstVT.getScalarSizeInBits() == 32 || !Subtarget->hasFullFP16()) {
+      PromVT = MVT::getVectorVT(MVT::f32, SrcVT.getVectorElementCount());
+      break;
+    }
+    [[fallthrough]];
+  case MVT::f32:
+    // Promote to f64
+    if (DstVT.getScalarSizeInBits() == 64) {
+      PromVT = MVT::getVectorVT(MVT::f64, SrcVT.getVectorElementCount());
+      break;
+    }
+    [[fallthrough]];
+  default:
+    break;
+  }
 
-  // In the absence of FP16 support, promote f16 to f32 and saturate the 
result.
   SDLoc DL(Op);
-  if ((SrcElementVT == MVT::f16 &&
-       (!Subtarget->hasFullFP16() || DstElementWidth > 16)) ||
-      SrcElementVT == MVT::bf16) {
-    MVT F32VT = MVT::getVectorVT(MVT::f32, SrcVT.getVectorNumElements());
-    SrcVal = DAG.getNode(ISD::FP_EXTEND, DL, F32VT, SrcVal);
-    // If we are extending to a v8f32, split into two v4f32 to produce legal
-    // types.
-    if (F32VT.getSizeInBits() > 128) {
-      SDValue SrcVal2;
-      std::tie(SrcVal, SrcVal2) = DAG.SplitVector(SrcVal, DL);
-      EVT IntVT = SrcVal.getValueType().changeVectorElementTypeToInteger();
-      SDValue Lo =
-          DAG.getNode(Op.getOpcode(), DL, IntVT, SrcVal, Op.getOperand(1));
-      SDValue Hi =
-          DAG.getNode(Op.getOpcode(), DL, IntVT, SrcVal2, Op.getOperand(1));
-      EVT HalfDstVT = DstVT.getHalfNumVectorElementsVT(*DAG.getContext());
-      Lo = DAG.getNode(ISD::TRUNCATE, DL, HalfDstVT, Lo);
-      Hi = DAG.getNode(ISD::TRUNCATE, DL, HalfDstVT, Hi);
-      return DAG.getNode(ISD::CONCAT_VECTORS, DL, DstVT, Lo, Hi);
-    }
-    SrcVT = F32VT;
----------------
gbossu wrote:

Now that `SrcVT`, `DstVT` and `SatVT` have a single point of definition, I 
think it's worth making them `const` to ensure it stays this way. It's so much 
easier to understand what the function does now that variables aren't 
re-defined.

https://github.com/llvm/llvm-project/pull/207199
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to