[llvm] 08c1150 - [DAG] Add computeOverflowForSignedSub/computeOverflowForUnsignedSub/computeOverflowForSub
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Sat May 6 07:55:19 PDT 2023
Author: Simon Pilgrim
Date: 2023-05-06T15:55:04+01:00
New Revision: 08c1150d4c3545949d7c98efaee52d06549d2552
URL: https://github.com/llvm/llvm-project/commit/08c1150d4c3545949d7c98efaee52d06549d2552
DIFF: https://github.com/llvm/llvm-project/commit/08c1150d4c3545949d7c98efaee52d06549d2552.diff
LOG: [DAG] Add computeOverflowForSignedSub/computeOverflowForUnsignedSub/computeOverflowForSub
Match the addition variants (although computeOverflowForUnsignedSub is really just a placeholder), and use this in DAGCombiner::visitSUBO
Added:
Modified:
llvm/include/llvm/CodeGen/SelectionDAG.h
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/test/CodeGen/X86/xaluo.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index e6da69479059..0c19fe18ed79 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1997,6 +1997,19 @@ class SelectionDAG {
: computeOverflowForUnsignedAdd(N0, N1);
}
+ /// Determine if the result of the signed sub of 2 nodes can overflow.
+ OverflowKind computeOverflowForSignedSub(SDValue N0, SDValue N1) const;
+
+ /// Determine if the result of the unsigned sub of 2 nodes can overflow.
+ OverflowKind computeOverflowForUnsignedSub(SDValue N0, SDValue N1) const;
+
+ /// Determine if the result of the sub of 2 nodes can overflow.
+ OverflowKind computeOverflowForSub(bool IsSigned, SDValue N0,
+ SDValue N1) const {
+ return IsSigned ? computeOverflowForSignedSub(N0, N1)
+ : computeOverflowForUnsignedSub(N0, N1);
+ }
+
/// Test if the given value is known to have exactly one bit set. This
diff ers
/// from computeKnownBits in that it doesn't necessarily determine which bit
/// is set.
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a72ff2484cbc..3adc9910c382 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4135,6 +4135,11 @@ SDValue DAGCombiner::visitSUBO(SDNode *N) {
if (isNullOrNullSplat(N1))
return CombineTo(N, N0, DAG.getConstant(0, DL, CarryVT));
+ // If it cannot overflow, transform into an sub.
+ if (DAG.computeOverflowForSub(IsSigned, N0, N1) == SelectionDAG::OFK_Never)
+ return CombineTo(N, DAG.getNode(ISD::SUB, DL, VT, N0, N1),
+ DAG.getConstant(0, DL, CarryVT));
+
// Canonicalize (usubo -1, x) -> ~x, i.e. (xor x, -1) + no borrow
if (!IsSigned && isAllOnesOrAllOnesSplat(N0))
return CombineTo(N, DAG.getNode(ISD::XOR, DL, VT, N1, N0),
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9cbf55f95dff..a78b7971d327 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3954,6 +3954,7 @@ SelectionDAG::computeOverflowForSignedAdd(SDValue N0, SDValue N1) const {
if (ComputeNumSignBits(N0) > 1 && ComputeNumSignBits(N1) > 1)
return OFK_Never;
+ // TODO: Add ConstantRange::signedAddMayOverflow handling.
return OFK_Sometime;
}
@@ -3985,6 +3986,32 @@ SelectionDAG::computeOverflowForUnsignedAdd(SDValue N0, SDValue N1) const {
return OFK_Never;
}
+ // TODO: Add ConstantRange::unsignedAddMayOverflow handling.
+ return OFK_Sometime;
+}
+
+SelectionDAG::OverflowKind
+SelectionDAG::computeOverflowForSignedSub(SDValue N0, SDValue N1) const {
+ // X - 0 never overflow
+ if (isNullConstant(N1))
+ return OFK_Never;
+
+ // If both operands each have at least two sign bits, the subtraction
+ // cannot overflow.
+ if (ComputeNumSignBits(N0) > 1 && ComputeNumSignBits(N1) > 1)
+ return OFK_Never;
+
+ // TODO: Add ConstantRange::signedSubMayOverflow handling.
+ return OFK_Sometime;
+}
+
+SelectionDAG::OverflowKind
+SelectionDAG::computeOverflowForUnsignedSub(SDValue N0, SDValue N1) const {
+ // X - 0 never overflow
+ if (isNullConstant(N1))
+ return OFK_Never;
+
+ // TODO: Add ConstantRange::unsignedSubMayOverflow handling.
return OFK_Sometime;
}
diff --git a/llvm/test/CodeGen/X86/xaluo.ll b/llvm/test/CodeGen/X86/xaluo.ll
index 508f065fb821..5796e485f631 100644
--- a/llvm/test/CodeGen/X86/xaluo.ll
+++ b/llvm/test/CodeGen/X86/xaluo.ll
@@ -978,14 +978,13 @@ define {i64, i1} @saddoovf(i64 %a, i64 %b) {
ret {i64, i1} %t
}
-; FIXME: Failure to recognise sub can't overflow
define {i64, i1} @ssuboovf(i64 %a, i64 %b) {
; CHECK-LABEL: ssuboovf:
; CHECK: ## %bb.0:
; CHECK-NEXT: movzwl %di, %eax
; CHECK-NEXT: shrq $22, %rsi
; CHECK-NEXT: subq %rsi, %rax
-; CHECK-NEXT: seto %dl
+; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: retq
%1 = and i64 %a, 65535
%2 = lshr i64 %b, 22
More information about the llvm-commits
mailing list