[llvm] [X86] Prefer SIMD min/max/abs for scalars when staying in XMM domain (PR #210654)

Evgenii Kudriashov via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 00:38:40 PDT 2026


================
@@ -54617,6 +54617,83 @@ static SDValue narrowBitOpRMW(StoreSDNode *St, const SDLoc &DL,
   return NewStore;
 }
 
+/// Fold store(abs/min/max(load…)) of scalar i16/i32/i64 into SIMD
+/// PABS/PMIN/PMAX to keep memory-bound sort2/abs in the XMM domain.
+static SDValue combineScalarMinMaxAbsStore(StoreSDNode *St, const SDLoc &DL,
+                                           SelectionDAG &DAG,
+                                           const X86Subtarget &Subtarget) {
+  if (!ISD::isNormalStore(St))
+    return SDValue();
+
+  SDValue StoredVal = St->getValue();
+  unsigned Opc = StoredVal.getOpcode();
+  bool IsAbs = Opc == ISD::ABS;
+  if ((!IsAbs && !ISD::isMinMaxOpcode(Opc)) || !StoredVal.hasOneUse())
+    return SDValue();
+
+  EVT VT = StoredVal.getValueType();
+  const Function &F = DAG.getMachineFunction().getFunction();
+  if (F.hasFnAttribute(Attribute::NoImplicitFloat) ||
+      Subtarget.useSoftFloat() || F.hasOptSize())
+    return SDValue();
+
+  // i32: SSE4.1 (min/max) / SSSE3 (abs). i64: AVX512F+VLX (no VLX widens to
+  // zmm + vzeroupper). i16: AVX512FP16 (needs VMOVW for mem->XMM).
+  auto getVecVT = [&]() -> std::optional<MVT> {
+    if (VT == MVT::i32 && (IsAbs ? Subtarget.hasSSSE3() : Subtarget.hasSSE41()))
+      return MVT::v4i32;
+    if (VT == MVT::i64 && Subtarget.hasAVX512() && Subtarget.hasVLX())
+      return MVT::v2i64;
+    if (VT == MVT::i16 && Subtarget.hasFP16())
+      return MVT::v8i16;
+    return std::nullopt;
----------------
e-kud wrote:

@Shaurya2k06 can't FP16 be moved to `isOperationLegal` logic as well or why do we still need a check?

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


More information about the llvm-commits mailing list