[PATCH] D159406: [SelectionDAG] Generalise SelectionDAG::computeOverflowKind to support other opcodes

Mohamed Atef via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 2 15:00:19 PDT 2023


elhewaty created this revision.
elhewaty added a reviewer: RKSimon.
Herald added a subscriber: hiraditya.
Herald added a project: All.
elhewaty requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Support signed multiplication
Support unsigned multiplication


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159406

Files:
  llvm/include/llvm/CodeGen/SelectionDAG.h
  llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4036,6 +4036,43 @@
   llvm_unreachable("Unknown OverflowResult");
 }
 
+SelectionDAG::OverflowKind
+SelectionDAG::computeOverflowForUnsignedMul(SDValue N0, SDValue N1) const {
+  // X * 0 and X * 1 never overflow.
+  if (isNullConstant(N1) || isOneConstant(N1))
+    return OFK_Never;
+  KnownBits N0Known = computeKnownBits(N0);
+  KnownBits N1Known = computeKnownBits(N1);
+  ConstantRange N0Range = ConstantRange::fromKnownBits(N0Known, false);
+  ConstantRange N1Range = ConstantRange::fromKnownBits(N1Known, false);
+  return mapOverflowResult(N0Range.unsignedMulMayOverflow(N1Range));
+}
+
+SelectionDAG::OverflowKind
+SelectionDAG::computeOverflowForSignedMul(SDValue N0, SDValue N1) const {
+  // X * 0 and X * 1 never overflow.
+  if (isNullConstant(N1) || isOneConstant(N1))
+    return OFK_Never;
+  // Get the size of the result.
+  unsigned BitWidth = N0.getScalarValueSizeInBits();
+  // Sum of the leading zeros.
+  unsigned SignBits = ComputeNumSignBits(N0) + ComputeNumSignBits(N1);
+  // If we have enough leading zeros, then there's no overflow. 
+  if (SignBits > BitWidth + 1)
+    return OFK_Never;
+  if (SignBits == BitWidth + 1) {
+    // The overflow occurs when the true multiplication of the
+    // the operands is the minimum negative number.
+    KnownBits N0Known = computeKnownBits(N0);
+    KnownBits N1Known = computeKnownBits(N1);
+    // If one of the operands is non-negative, then there's no
+    // overflow.
+    if (N0Known.isNonNegative() || N1Known.isNonNegative())
+      return OFK_Never;
+  }
+  return OFK_Sometime;
+}
+
 SelectionDAG::OverflowKind
 SelectionDAG::computeOverflowForSignedAdd(SDValue N0, SDValue N1) const {
   // X + 0 never overflow
Index: llvm/include/llvm/CodeGen/SelectionDAG.h
===================================================================
--- llvm/include/llvm/CodeGen/SelectionDAG.h
+++ llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -2029,6 +2029,24 @@
     OFK_Always,
   };
 
+  /// Determine if the result of the signed mul of 2 nodes can overflow.
+  OverflowKind computeOverflowForSignedMul(SDValue N0, SDValue N1) const;
+
+  /// Determine if the result of the unsigned mul of 2 nodes can overflow.
+  OverflowKind computeOverflowForUnsignedMul(SDValue N0, SDValue N1) const;
+
+  /// Determine if the result of the mul of 2 nodes can overflow.
+  OverflowKind computeOverflowForMul(bool IsSigned, SDValue N0,
+                                     SDValue N1) const {
+    return IsSigned ? computeOverflowForSignedMul(N0, N1)
+                    : computeOverflowForUnsignedMul(N0, N1);
+  }
+
+  /// Determine if the result of the mul of 2 nodes can never overflow.
+  bool willNotOverflowMul(bool IsSigned, SDValue N0, SDValue N1) const {
+    return computeOverflowForMul(IsSigned, N0, N1) == OFK_Never;
+  }
+
   /// Determine if the result of the signed addition of 2 nodes can overflow.
   OverflowKind computeOverflowForSignedAdd(SDValue N0, SDValue N1) const;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159406.555603.patch
Type: text/x-patch
Size: 3181 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230902/598ed85c/attachment.bin>


More information about the llvm-commits mailing list