[llvm] [X86] Resolve FIXME: Accept live flag if no overflow occurs. (PR #86836)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 27 10:16:14 PDT 2024
https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/86836
None
>From 47bf47f18b1338d273e937d8eda01fca9de380cd Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Wed, 27 Mar 2024 13:10:24 -0400
Subject: [PATCH] [X86] Resolve FIXME: Accept live flag if no oveflow occurs.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 8 ++-
llvm/lib/Target/X86/X86ISelLowering.cpp | 50 ++++++++++++++-----
2 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e8d1ac1d3a9167..5f0cc76d260184 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4129,8 +4129,12 @@ 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;
+ // Fallback to ConstantRange::signedAddMayOverflow handling.
+ KnownBits N0Known = computeKnownBits(N0);
+ KnownBits N1Known = computeKnownBits(N1);
+ ConstantRange N0Range = ConstantRange::fromKnownBits(N0Known, true);
+ ConstantRange N1Range = ConstantRange::fromKnownBits(N1Known, true);
+ return mapOverflowResult(N0Range.signedAddMayOverflow(N1Range));
}
SelectionDAG::OverflowKind
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9d98d31b31df0b..26e450607efbe1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -54522,14 +54522,27 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
}
// Fold ADC(C1,C2,Carry) -> ADC(0,C1+C2,Carry)
- // iff the flag result is dead.
- // TODO: Allow flag result if C1+C2 doesn't signed/unsigned overflow.
- if (LHSC && RHSC && !LHSC->isZero() && !N->hasAnyUseOfValue(1)) {
- SDLoc DL(N);
- APInt Sum = LHSC->getAPIntValue() + RHSC->getAPIntValue();
- return DAG.getNode(X86ISD::ADC, DL, N->getVTList(),
- DAG.getConstant(0, DL, LHS.getValueType()),
- DAG.getConstant(Sum, DL, LHS.getValueType()), CarryIn);
+ // if the flag result is dead, or if C1+C2 doesn't signed/unsigned overflow.
+ if (LHSC && RHSC && !LHSC->isZero()) {
+ // Calculate the sum and check for overflow.
+ bool Overflow;
+
+ // Check for signed overflow first. Because it is more involved, let sadd_ov
+ // do the work
+ APInt Sum = LHSC->getAPIntValue().sadd_ov(RHSC->getAPIntValue(), Overflow);
+
+ // Manually check for unsigned overflow. Luckily, this is relatively easy:
+ // just check for wrap-around
+ Overflow |= Sum.ult(RHSC->getAPIntValue());
+
+ // Only apply the optimization if there is no overflow or the flag result is
+ // not used.
+ if (!Overflow || !N->hasAnyUseOfValue(1)) {
+ SDLoc DL(N);
+ return DAG.getNode(X86ISD::ADC, DL, N->getVTList(),
+ DAG.getConstant(0, DL, LHS.getValueType()),
+ DAG.getConstant(Sum, DL, LHS.getValueType()), CarryIn);
+ }
}
if (SDValue Flags = combineCarryThroughADD(CarryIn, DAG)) {
@@ -54539,11 +54552,22 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
}
// Fold ADC(ADD(X,Y),0,Carry) -> ADC(X,Y,Carry)
- // iff the flag result is dead.
- if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero() &&
- !N->hasAnyUseOfValue(1))
- return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(), LHS.getOperand(0),
- LHS.getOperand(1), CarryIn);
+ // iff the flag result is dead or known to be 0 anyway.
+
+ if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero()) {
+ SelectionDAG::OverflowKind UnsignedOverflow =
+ DAG.computeOverflowForUnsignedAdd(LHS.getOperand(0), LHS.getOperand(1));
+ SelectionDAG::OverflowKind SignedOverflow =
+ DAG.computeOverflowForSignedAdd(LHS.getOperand(0), LHS.getOperand(1));
+ if (!N->hasAnyUseOfValue(1) || (DAG.computeOverflowForSignedAdd(
+ LHS.getOperand(0), LHS.getOperand(1)) ==
+ SelectionDAG::OverflowKind::OFK_Never &&
+ DAG.computeOverflowForUnsignedAdd(
+ LHS.getOperand(0), LHS.getOperand(1)) ==
+ SelectionDAG::OverflowKind::OFK_Never))
+ return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(),
+ LHS.getOperand(0), LHS.getOperand(1), CarryIn);
+ }
return SDValue();
}
More information about the llvm-commits
mailing list