[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