aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp160
1 files changed, 93 insertions, 67 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index a6b471ea22b7..66389a57f780 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1362,6 +1362,29 @@ bool TargetLowering::SimplifyDemandedBits(
}
}
+ // AND(INSERT_SUBVECTOR(C,X,I),M) -> INSERT_SUBVECTOR(AND(C,M),X,I)
+ // iff 'C' is Undef/Constant and AND(X,M) == X (for DemandedBits).
+ if (Op0.getOpcode() == ISD::INSERT_SUBVECTOR &&
+ (Op0.getOperand(0).isUndef() ||
+ ISD::isBuildVectorOfConstantSDNodes(Op0.getOperand(0).getNode())) &&
+ Op0->hasOneUse()) {
+ unsigned NumSubElts =
+ Op0.getOperand(1).getValueType().getVectorNumElements();
+ unsigned SubIdx = Op0.getConstantOperandVal(2);
+ APInt DemandedSub =
+ APInt::getBitsSet(NumElts, SubIdx, SubIdx + NumSubElts);
+ KnownBits KnownSubMask =
+ TLO.DAG.computeKnownBits(Op1, DemandedSub & DemandedElts, Depth + 1);
+ if (DemandedBits.isSubsetOf(KnownSubMask.One)) {
+ SDValue NewAnd =
+ TLO.DAG.getNode(ISD::AND, dl, VT, Op0.getOperand(0), Op1);
+ SDValue NewInsert =
+ TLO.DAG.getNode(ISD::INSERT_SUBVECTOR, dl, VT, NewAnd,
+ Op0.getOperand(1), Op0.getOperand(2));
+ return TLO.CombineTo(Op, NewInsert);
+ }
+ }
+
if (SimplifyDemandedBits(Op1, DemandedBits, DemandedElts, Known, TLO,
Depth + 1))
return true;
@@ -1371,20 +1394,6 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
assert(!Known2.hasConflict() && "Bits known to be one AND zero?");
- // Attempt to avoid multi-use ops if we don't need anything from them.
- if (!DemandedBits.isAllOnes() || !DemandedElts.isAllOnes()) {
- SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
- Op0, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
- SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits(
- Op1, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
- if (DemandedOp0 || DemandedOp1) {
- Op0 = DemandedOp0 ? DemandedOp0 : Op0;
- Op1 = DemandedOp1 ? DemandedOp1 : Op1;
- SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Op1);
- return TLO.CombineTo(Op, NewOp);
- }
- }
-
// If all of the demanded bits are known one on one side, return the other.
// These bits cannot contribute to the result of the 'and'.
if (DemandedBits.isSubsetOf(Known2.Zero | Known.One))
@@ -1402,6 +1411,20 @@ bool TargetLowering::SimplifyDemandedBits(
if (ShrinkDemandedOp(Op, BitWidth, DemandedBits, TLO))
return true;
+ // Attempt to avoid multi-use ops if we don't need anything from them.
+ if (!DemandedBits.isAllOnes() || !DemandedElts.isAllOnes()) {
+ SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
+ Op0, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
+ SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits(
+ Op1, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
+ if (DemandedOp0 || DemandedOp1) {
+ Op0 = DemandedOp0 ? DemandedOp0 : Op0;
+ Op1 = DemandedOp1 ? DemandedOp1 : Op1;
+ SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Op1);
+ return TLO.CombineTo(Op, NewOp);
+ }
+ }
+
Known &= Known2;
break;
}
@@ -1418,6 +1441,19 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
assert(!Known2.hasConflict() && "Bits known to be one AND zero?");
+ // If all of the demanded bits are known zero on one side, return the other.
+ // These bits cannot contribute to the result of the 'or'.
+ if (DemandedBits.isSubsetOf(Known2.One | Known.Zero))
+ return TLO.CombineTo(Op, Op0);
+ if (DemandedBits.isSubsetOf(Known.One | Known2.Zero))
+ return TLO.CombineTo(Op, Op1);
+ // If the RHS is a constant, see if we can simplify it.
+ if (ShrinkDemandedConstant(Op, DemandedBits, DemandedElts, TLO))
+ return true;
+ // If the operation can be done in a smaller type, do so.
+ if (ShrinkDemandedOp(Op, BitWidth, DemandedBits, TLO))
+ return true;
+
// Attempt to avoid multi-use ops if we don't need anything from them.
if (!DemandedBits.isAllOnes() || !DemandedElts.isAllOnes()) {
SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
@@ -1432,19 +1468,6 @@ bool TargetLowering::SimplifyDemandedBits(
}
}
- // If all of the demanded bits are known zero on one side, return the other.
- // These bits cannot contribute to the result of the 'or'.
- if (DemandedBits.isSubsetOf(Known2.One | Known.Zero))
- return TLO.CombineTo(Op, Op0);
- if (DemandedBits.isSubsetOf(Known.One | Known2.Zero))
- return TLO.CombineTo(Op, Op1);
- // If the RHS is a constant, see if we can simplify it.
- if (ShrinkDemandedConstant(Op, DemandedBits, DemandedElts, TLO))
- return true;
- // If the operation can be done in a smaller type, do so.
- if (ShrinkDemandedOp(Op, BitWidth, DemandedBits, TLO))
- return true;
-
Known |= Known2;
break;
}
@@ -1461,20 +1484,6 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
assert(!Known2.hasConflict() && "Bits known to be one AND zero?");
- // Attempt to avoid multi-use ops if we don't need anything from them.
- if (!DemandedBits.isAllOnes() || !DemandedElts.isAllOnes()) {
- SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
- Op0, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
- SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits(
- Op1, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
- if (DemandedOp0 || DemandedOp1) {
- Op0 = DemandedOp0 ? DemandedOp0 : Op0;
- Op1 = DemandedOp1 ? DemandedOp1 : Op1;
- SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Op1);
- return TLO.CombineTo(Op, NewOp);
- }
- }
-
// If all of the demanded bits are known zero on one side, return the other.
// These bits cannot contribute to the result of the 'xor'.
if (DemandedBits.isSubsetOf(Known.Zero))
@@ -1519,6 +1528,20 @@ bool TargetLowering::SimplifyDemandedBits(
if (ShrinkDemandedConstant(Op, DemandedBits, DemandedElts, TLO))
return true;
+ // Attempt to avoid multi-use ops if we don't need anything from them.
+ if (!DemandedBits.isAllOnes() || !DemandedElts.isAllOnes()) {
+ SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
+ Op0, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
+ SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits(
+ Op1, DemandedBits, DemandedElts, TLO.DAG, Depth + 1);
+ if (DemandedOp0 || DemandedOp1) {
+ Op0 = DemandedOp0 ? DemandedOp0 : Op0;
+ Op1 = DemandedOp1 ? DemandedOp1 : Op1;
+ SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Op1);
+ return TLO.CombineTo(Op, NewOp);
+ }
+ }
+
Known ^= Known2;
break;
}
@@ -1972,9 +1995,9 @@ bool TargetLowering::SimplifyDemandedBits(
KnownBits Known1 = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1);
Known = KnownBits::umin(Known0, Known1);
if (Optional<bool> IsULE = KnownBits::ule(Known0, Known1))
- return TLO.CombineTo(Op, IsULE.getValue() ? Op0 : Op1);
+ return TLO.CombineTo(Op, IsULE.value() ? Op0 : Op1);
if (Optional<bool> IsULT = KnownBits::ult(Known0, Known1))
- return TLO.CombineTo(Op, IsULT.getValue() ? Op0 : Op1);
+ return TLO.CombineTo(Op, IsULT.value() ? Op0 : Op1);
break;
}
case ISD::UMAX: {
@@ -1985,9 +2008,9 @@ bool TargetLowering::SimplifyDemandedBits(
KnownBits Known1 = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1);
Known = KnownBits::umax(Known0, Known1);
if (Optional<bool> IsUGE = KnownBits::uge(Known0, Known1))
- return TLO.CombineTo(Op, IsUGE.getValue() ? Op0 : Op1);
+ return TLO.CombineTo(Op, IsUGE.value() ? Op0 : Op1);
if (Optional<bool> IsUGT = KnownBits::ugt(Known0, Known1))
- return TLO.CombineTo(Op, IsUGT.getValue() ? Op0 : Op1);
+ return TLO.CombineTo(Op, IsUGT.value() ? Op0 : Op1);
break;
}
case ISD::BITREVERSE: {
@@ -2486,9 +2509,7 @@ bool TargetLowering::SimplifyDemandedBits(
// won't wrap after simplification.
Flags.setNoSignedWrap(false);
Flags.setNoUnsignedWrap(false);
- SDValue NewOp =
- TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Op1, Flags);
- return TLO.CombineTo(Op, NewOp);
+ Op->setFlags(Flags);
}
return true;
}
@@ -3031,15 +3052,15 @@ bool TargetLowering::SimplifyDemandedVectorElts(
break;
}
case ISD::VSELECT: {
+ SDValue Sel = Op.getOperand(0);
+ SDValue LHS = Op.getOperand(1);
+ SDValue RHS = Op.getOperand(2);
+
// Try to transform the select condition based on the current demanded
// elements.
- // TODO: If a condition element is undef, we can choose from one arm of the
- // select (and if one arm is undef, then we can propagate that to the
- // result).
- // TODO - add support for constant vselect masks (see IR version of this).
- APInt UnusedUndef, UnusedZero;
- if (SimplifyDemandedVectorElts(Op.getOperand(0), DemandedElts, UnusedUndef,
- UnusedZero, TLO, Depth + 1))
+ APInt UndefSel, UndefZero;
+ if (SimplifyDemandedVectorElts(Sel, DemandedElts, UndefSel, UndefZero, TLO,
+ Depth + 1))
return true;
// See if we can simplify either vselect operand.
@@ -3047,15 +3068,24 @@ bool TargetLowering::SimplifyDemandedVectorElts(
APInt DemandedRHS(DemandedElts);
APInt UndefLHS, ZeroLHS;
APInt UndefRHS, ZeroRHS;
- if (SimplifyDemandedVectorElts(Op.getOperand(1), DemandedLHS, UndefLHS,
- ZeroLHS, TLO, Depth + 1))
+ if (SimplifyDemandedVectorElts(LHS, DemandedLHS, UndefLHS, ZeroLHS, TLO,
+ Depth + 1))
return true;
- if (SimplifyDemandedVectorElts(Op.getOperand(2), DemandedRHS, UndefRHS,
- ZeroRHS, TLO, Depth + 1))
+ if (SimplifyDemandedVectorElts(RHS, DemandedRHS, UndefRHS, ZeroRHS, TLO,
+ Depth + 1))
return true;
KnownUndef = UndefLHS & UndefRHS;
KnownZero = ZeroLHS & ZeroRHS;
+
+ // If we know that the selected element is always zero, we don't need the
+ // select value element.
+ APInt DemandedSel = DemandedElts & ~KnownZero;
+ if (DemandedSel != DemandedElts)
+ if (SimplifyDemandedVectorElts(Sel, DemandedSel, UndefSel, UndefZero, TLO,
+ Depth + 1))
+ return true;
+
break;
}
case ISD::VECTOR_SHUFFLE: {
@@ -5239,17 +5269,13 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
case 32:
case 64:
case 128:
- OpInfo.ConstraintVT =
- MVT::getVT(IntegerType::get(OpTy->getContext(), BitSize), true);
+ OpTy = IntegerType::get(OpTy->getContext(), BitSize);
break;
}
- } else if (PointerType *PT = dyn_cast<PointerType>(OpTy)) {
- unsigned PtrSize = DL.getPointerSizeInBits(PT->getAddressSpace());
- OpInfo.ConstraintVT = MVT::getIntegerVT(PtrSize);
- } else {
- OpInfo.ConstraintVT = MVT::getVT(OpTy, true);
}
+ EVT VT = getAsmOperandValueType(DL, OpTy, true);
+ OpInfo.ConstraintVT = VT.isSimple() ? VT.getSimpleVT() : MVT::Other;
ArgNo++;
}
}
@@ -7833,7 +7859,7 @@ SDValue TargetLowering::expandCTLZ(SDNode *Node, SelectionDAG &DAG) const {
// return popcount(~x);
//
// Ref: "Hacker's Delight" by Henry Warren
- for (unsigned i = 0; (1U << i) <= (NumBitsPerElt / 2); ++i) {
+ for (unsigned i = 0; (1U << i) < NumBitsPerElt; ++i) {
SDValue Tmp = DAG.getConstant(1ULL << i, dl, ShVT);
Op = DAG.getNode(ISD::OR, dl, VT, Op,
DAG.getNode(ISD::SRL, dl, VT, Op, Tmp));