summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-02-17 22:19:50 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-02-17 22:19:50 +0000
commit7fae42eb278796797ed724a45c7dcca0258bfcd2 (patch)
treebb035a96cb0835c288db0ea694756c6db9c9a35b /llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parent8da142bff1c5a6b7832e6e4a4c01d80ce68cd789 (diff)
downloadbcm5719-llvm-7fae42eb278796797ed724a45c7dcca0258bfcd2.tar.gz
bcm5719-llvm-7fae42eb278796797ed724a45c7dcca0258bfcd2.zip
[SelectionDAG] ComputeNumSignBits - add support for SMIN+SMAX clamp patterns
If we have a clamp pattern, SMIN(SMAX(X, LO),HI) or SMAX(SMIN(X, HI),LO) then we can deduce that the number of signbits will be at least the minimum of the LO and HI constants. I haven't bothered with the UMIN/UMAX equivalent as (1) we don't have any current use cases and (2) I wonder if we'd be better off immediately falling back for ComputeKnownBits for UMIN/UMAX which already has optimization patterns useful for unsigned cases. Differential Revision: https://reviews.llvm.org/D43338 llvm-svn: 325450
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index fde6a52c9e3..313233068b5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3206,7 +3206,32 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
return std::min(Tmp, Tmp2);
case ISD::SMIN:
- case ISD::SMAX:
+ case ISD::SMAX: {
+ // If we have a clamp pattern, we know that the number of sign bits will be
+ // the minimum of the clamp min/max range.
+ bool IsMax = (Opcode == ISD::SMAX);
+ ConstantSDNode *CstLow = nullptr, *CstHigh = nullptr;
+ if (CstLow = isConstOrDemandedConstSplat(Op.getOperand(1), DemandedElts))
+ if (Op.getOperand(0).getOpcode() == (IsMax ? ISD::SMIN : ISD::SMAX))
+ CstHigh = isConstOrDemandedConstSplat(Op.getOperand(0).getOperand(1),
+ DemandedElts);
+ if (CstLow && CstHigh) {
+ if (!IsMax)
+ std::swap(CstLow, CstHigh);
+ if (CstLow->getAPIntValue().sle(CstHigh->getAPIntValue())) {
+ Tmp = CstLow->getAPIntValue().getNumSignBits();
+ Tmp2 = CstHigh->getAPIntValue().getNumSignBits();
+ return std::min(Tmp, Tmp2);
+ }
+ }
+
+ // Fallback - just get the minimum number of sign bits of the operands.
+ Tmp = ComputeNumSignBits(Op.getOperand(0), Depth + 1);
+ if (Tmp == 1)
+ return 1; // Early out.
+ Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth + 1);
+ return std::min(Tmp, Tmp2);
+ }
case ISD::UMIN:
case ISD::UMAX:
Tmp = ComputeNumSignBits(Op.getOperand(0), Depth + 1);
OpenPOWER on IntegriCloud