[llvm] [NVPTX] Use cvt.sat to lower min/max clamping to i8 and i16 ranges (PR #143016)

Artem Belevich via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 5 12:21:47 PDT 2025


================
@@ -5667,6 +5677,49 @@ static SDValue combineADDRSPACECAST(SDNode *N,
   return SDValue();
 }
 
+static SDValue combineMINMAX(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
+
+  EVT VT = N->getValueType(0);
+  if (!(VT == MVT::i32 || VT == MVT::i64 || VT == MVT::i16))
+    return SDValue();
+
+  SDValue Val;
+  APInt Ceil, Floor;
+  if (!(sd_match(N, m_SMin(m_SMax(m_Value(Val), m_ConstInt(Floor)),
+                           m_ConstInt(Ceil))) ||
+        sd_match(N, m_SMax(m_SMin(m_Value(Val), m_ConstInt(Ceil)),
+                           m_ConstInt(Floor)))))
+    return SDValue();
+
+  const unsigned BitWidth = VT.getSizeInBits();
+  SDLoc DL(N);
+  auto MatchTuncSat = [&](MVT DestVT) {
+    const unsigned DestBitWidth = DestVT.getSizeInBits();
+    bool IsSigned;
+    if (Ceil == APInt::getSignedMaxValue(DestBitWidth).sext(BitWidth) &&
+        Floor == APInt::getSignedMinValue(DestBitWidth).sext(BitWidth))
+      IsSigned = true;
+    else if (Ceil == APInt::getMaxValue(DestBitWidth).zext(BitWidth) &&
+             Floor == APInt::getMinValue(BitWidth))
+      IsSigned = false;
+    else
+      return SDValue();
+
+    unsigned Opcode = IsSigned ? ISD::TRUNCATE_SSAT_S : ISD::TRUNCATE_SSAT_U;
+    SDValue Trunc = DCI.DAG.getNode(Opcode, DL, DestVT, Val);
+    return DCI.DAG.getExtOrTrunc(IsSigned, Trunc, DL, VT);
+  };
+
+  if (VT != MVT::i16)
----------------
Artem-B wrote:

I'd fold it into the MatchTruncSat  as `if (DestVT == VT) return SDNode; // can't use conversion on identical types`. Or just mention it in the comment here. Otherwise it's not clear what are the other possible types we may see here and why we exclude i16 from that set.



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


More information about the llvm-commits mailing list