diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 160 |
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)); |