aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp109
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp16
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp12
3 files changed, 88 insertions, 49 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 0e8e4c9..fed5e72 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -609,6 +609,8 @@ namespace {
SDValue foldABSToABD(SDNode *N, const SDLoc &DL);
SDValue foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
SDValue False, ISD::CondCode CC, const SDLoc &DL);
+ SDValue foldSelectToUMin(SDValue LHS, SDValue RHS, SDValue True,
+ SDValue False, ISD::CondCode CC, const SDLoc &DL);
SDValue unfoldMaskedMerge(SDNode *N);
SDValue unfoldExtremeBitClearingToShifts(SDNode *N);
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
@@ -859,7 +861,7 @@ namespace {
auto LK = TLI.getTypeConversion(*DAG.getContext(), VT);
return (LK.first == TargetLoweringBase::TypeLegal ||
LK.first == TargetLoweringBase::TypePromoteInteger) &&
- TLI.isOperationLegal(ISD::UMIN, LK.second);
+ TLI.isOperationLegalOrCustom(ISD::UMIN, LK.second);
}
public:
@@ -4093,6 +4095,26 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
return N0;
}
+ // (sub x, ([v]select (ult x, y), 0, y)) -> (umin x, (sub x, y))
+ // (sub x, ([v]select (uge x, y), y, 0)) -> (umin x, (sub x, y))
+ if (N1.hasOneUse() && hasUMin(VT)) {
+ SDValue Y;
+ if (sd_match(N1, m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETULT)),
+ m_Zero(), m_Deferred(Y))) ||
+ sd_match(N1, m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETUGE)),
+ m_Deferred(Y), m_Zero())) ||
+ sd_match(N1, m_VSelect(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETULT)),
+ m_Zero(), m_Deferred(Y))) ||
+ sd_match(N1, m_VSelect(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETUGE)),
+ m_Deferred(Y), m_Zero())))
+ return DAG.getNode(ISD::UMIN, DL, VT, N0,
+ DAG.getNode(ISD::SUB, DL, VT, N0, Y));
+ }
+
if (SDValue NewSel = foldBinOpIntoSelect(N))
return NewSel;
@@ -4442,20 +4464,6 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
sd_match(N1, m_UMaxLike(m_Specific(A), m_Specific(B))))
return DAG.getNegative(DAG.getNode(ISD::ABDU, DL, VT, A, B), DL, VT);
- // (sub x, (select (ult x, y), 0, y)) -> (umin x, (sub x, y))
- // (sub x, (select (uge x, y), y, 0)) -> (umin x, (sub x, y))
- if (hasUMin(VT)) {
- SDValue Y;
- if (sd_match(N1, m_OneUse(m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
- m_SpecificCondCode(ISD::SETULT)),
- m_Zero(), m_Deferred(Y)))) ||
- sd_match(N1, m_OneUse(m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
- m_SpecificCondCode(ISD::SETUGE)),
- m_Deferred(Y), m_Zero()))))
- return DAG.getNode(ISD::UMIN, DL, VT, N0,
- DAG.getNode(ISD::SUB, DL, VT, N0, Y));
- }
-
return SDValue();
}
@@ -7633,7 +7641,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
if (SDValue(GN0, 0).hasOneUse() &&
isConstantSplatVectorMaskForType(N1.getNode(), ScalarVT) &&
- TLI.isVectorLoadExtDesirable(SDValue(SDValue(GN0, 0)))) {
+ TLI.isVectorLoadExtDesirable(SDValue(N, 0))) {
SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
@@ -12173,6 +12181,30 @@ SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
return SDValue();
}
+// ([v]select (ugt x, C), (add x, ~C), x) -> (umin (add x, ~C), x)
+// ([v]select (ult x, C), x, (add x, -C)) -> (umin x, (add x, -C))
+SDValue DAGCombiner::foldSelectToUMin(SDValue LHS, SDValue RHS, SDValue True,
+ SDValue False, ISD::CondCode CC,
+ const SDLoc &DL) {
+ APInt C;
+ EVT VT = True.getValueType();
+ if (sd_match(RHS, m_ConstInt(C)) && hasUMin(VT)) {
+ if (CC == ISD::SETUGT && LHS == False &&
+ sd_match(True, m_Add(m_Specific(False), m_SpecificInt(~C)))) {
+ SDValue AddC = DAG.getConstant(~C, DL, VT);
+ SDValue Add = DAG.getNode(ISD::ADD, DL, VT, False, AddC);
+ return DAG.getNode(ISD::UMIN, DL, VT, Add, False);
+ }
+ if (CC == ISD::SETULT && LHS == True &&
+ sd_match(False, m_Add(m_Specific(True), m_SpecificInt(-C)))) {
+ SDValue AddC = DAG.getConstant(-C, DL, VT);
+ SDValue Add = DAG.getNode(ISD::ADD, DL, VT, True, AddC);
+ return DAG.getNode(ISD::UMIN, DL, VT, True, Add);
+ }
+ }
+ return SDValue();
+}
+
SDValue DAGCombiner::visitSELECT(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -12358,24 +12390,8 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
// (select (ugt x, C), (add x, ~C), x) -> (umin (add x, ~C), x)
// (select (ult x, C), x, (add x, -C)) -> (umin x, (add x, -C))
- APInt C;
- if (sd_match(Cond1, m_ConstInt(C)) && hasUMin(VT)) {
- if (CC == ISD::SETUGT && Cond0 == N2 &&
- sd_match(N1, m_Add(m_Specific(N2), m_SpecificInt(~C)))) {
- // The resulting code relies on an unsigned wrap in ADD.
- // Recreating ADD to drop possible nuw/nsw flags.
- SDValue AddC = DAG.getConstant(~C, DL, VT);
- SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N2, AddC);
- return DAG.getNode(ISD::UMIN, DL, VT, Add, N2);
- }
- if (CC == ISD::SETULT && Cond0 == N1 &&
- sd_match(N2, m_Add(m_Specific(N1), m_SpecificInt(-C)))) {
- // Ditto.
- SDValue AddC = DAG.getConstant(-C, DL, VT);
- SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N1, AddC);
- return DAG.getNode(ISD::UMIN, DL, VT, N1, Add);
- }
- }
+ if (SDValue UMin = foldSelectToUMin(Cond0, Cond1, N1, N2, CC, DL))
+ return UMin;
}
if (!VT.isVector())
@@ -13412,6 +13428,11 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
}
}
}
+
+ // (vselect (ugt x, C), (add x, ~C), x) -> (umin (add x, ~C), x)
+ // (vselect (ult x, C), x, (add x, -C)) -> (umin x, (add x, -C))
+ if (SDValue UMin = foldSelectToUMin(LHS, RHS, N1, N2, CC, DL))
+ return UMin;
}
if (SimplifySelectOps(N, N1, N2))
@@ -15724,7 +15745,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
// fold (sext_inreg (masked_gather x)) -> (sext_masked_gather x)
if (auto *GN0 = dyn_cast<MaskedGatherSDNode>(N0)) {
if (SDValue(GN0, 0).hasOneUse() && ExtVT == GN0->getMemoryVT() &&
- TLI.isVectorLoadExtDesirable(SDValue(SDValue(GN0, 0)))) {
+ TLI.isVectorLoadExtDesirable(SDValue(N, 0))) {
SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
@@ -16751,12 +16772,8 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
if (DAG.isGuaranteedNotToBeUndefOrPoison(Op, /*PoisonOnly*/ false,
/*Depth*/ 1))
continue;
- bool HadMaybePoisonOperands = !MaybePoisonOperands.empty();
- bool IsNewMaybePoisonOperand = MaybePoisonOperands.insert(Op).second;
- if (IsNewMaybePoisonOperand)
+ if (MaybePoisonOperands.insert(Op).second)
MaybePoisonOperandNumbers.push_back(OpNo);
- if (!HadMaybePoisonOperands)
- continue;
}
// NOTE: the whole op may be not guaranteed to not be undef or poison because
// it could create undef or poison due to it's poison-generating flags.
@@ -18706,6 +18723,12 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
if (SDValue FTrunc = foldFPToIntToFP(N, DL, DAG, TLI))
return FTrunc;
+ // fold (sint_to_fp (trunc nsw x)) -> (sint_to_fp x)
+ if (N0.getOpcode() == ISD::TRUNCATE && N0->getFlags().hasNoSignedWrap() &&
+ TLI.isTypeDesirableForOp(ISD::SINT_TO_FP,
+ N0.getOperand(0).getValueType()))
+ return DAG.getNode(ISD::SINT_TO_FP, DL, VT, N0.getOperand(0));
+
return SDValue();
}
@@ -18743,6 +18766,12 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
if (SDValue FTrunc = foldFPToIntToFP(N, DL, DAG, TLI))
return FTrunc;
+ // fold (uint_to_fp (trunc nuw x)) -> (uint_to_fp x)
+ if (N0.getOpcode() == ISD::TRUNCATE && N0->getFlags().hasNoUnsignedWrap() &&
+ TLI.isTypeDesirableForOp(ISD::UINT_TO_FP,
+ N0.getOperand(0).getValueType()))
+ return DAG.getNode(ISD::UINT_TO_FP, DL, VT, N0.getOperand(0));
+
return SDValue();
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 70a39ea..2458115 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5544,6 +5544,8 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::USUBSAT:
case ISD::MULHU:
case ISD::MULHS:
+ case ISD::ABDU:
+ case ISD::ABDS:
case ISD::SMIN:
case ISD::SMAX:
case ISD::UMIN:
@@ -5569,6 +5571,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::BUILD_VECTOR:
case ISD::BUILD_PAIR:
case ISD::SPLAT_VECTOR:
+ case ISD::FABS:
return false;
case ISD::ABS:
@@ -6750,7 +6753,9 @@ SDValue SelectionDAG::FoldSymbolOffset(unsigned Opcode, EVT VT,
return SDValue();
int64_t Offset = C2->getSExtValue();
switch (Opcode) {
- case ISD::ADD: break;
+ case ISD::ADD:
+ case ISD::PTRADD:
+ break;
case ISD::SUB: Offset = -uint64_t(Offset); break;
default: return SDValue();
}
@@ -13872,6 +13877,8 @@ void SelectionDAG::copyExtraInfo(SDNode *From, SDNode *To) {
return;
}
+ const SDNode *EntrySDN = getEntryNode().getNode();
+
// We need to copy NodeExtraInfo to all _new_ nodes that are being introduced
// through the replacement of From with To. Otherwise, replacements of a node
// (From) with more complex nodes (To and its operands) may result in lost
@@ -13903,9 +13910,14 @@ void SelectionDAG::copyExtraInfo(SDNode *From, SDNode *To) {
return true;
if (!Visited.insert(N).second)
return true;
- if (getEntryNode().getNode() == N)
+ if (EntrySDN == N)
return false;
for (const SDValue &Op : N->op_values()) {
+ if (N == To && Op.getNode() == EntrySDN) {
+ // Special case: New node's operand is the entry node; just need to
+ // copy extra info to new node.
+ break;
+ }
if (!Self(Self, Op.getNode()))
return false;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 74c14ed..01e5312 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -845,16 +846,13 @@ static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &DL,
static void failForInvalidBundles(const CallBase &I, StringRef Name,
ArrayRef<uint32_t> AllowedBundles) {
if (I.hasOperandBundlesOtherThan(AllowedBundles)) {
+ ListSeparator LS;
std::string Error;
+ raw_string_ostream OS(Error);
for (unsigned i = 0, e = I.getNumOperandBundles(); i != e; ++i) {
OperandBundleUse U = I.getOperandBundleAt(i);
- bool First = true;
- if (is_contained(AllowedBundles, U.getTagID()))
- continue;
- if (!First)
- Error += ", ";
- First = false;
- Error += U.getTagName();
+ if (!is_contained(AllowedBundles, U.getTagID()))
+ OS << LS << U.getTagName();
}
reportFatalUsageError(
Twine("cannot lower ", Name)