@@ -564,6 +564,61 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits,
564
564
AssumeSingleUse);
565
565
}
566
566
567
+ // TODO: Can we merge SelectionDAG::GetDemandedBits into this?
568
+ // TODO: Under what circumstances can we create nodes? BITCAST? Constant?
569
+ SDValue TargetLowering::SimplifyMultipleUseDemandedBits (
570
+ SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
571
+ SelectionDAG &DAG, unsigned Depth) const {
572
+ KnownBits LHSKnown, RHSKnown;
573
+ switch (Op.getOpcode ()) {
574
+ case ISD::AND: {
575
+ LHSKnown = DAG.computeKnownBits (Op.getOperand (0 ), DemandedElts, Depth + 1 );
576
+ RHSKnown = DAG.computeKnownBits (Op.getOperand (1 ), DemandedElts, Depth + 1 );
577
+
578
+ // If all of the demanded bits are known 1 on one side, return the other.
579
+ // These bits cannot contribute to the result of the 'and' in this
580
+ // context.
581
+ if (DemandedBits.isSubsetOf (LHSKnown.Zero | RHSKnown.One ))
582
+ return Op.getOperand (0 );
583
+ if (DemandedBits.isSubsetOf (RHSKnown.Zero | LHSKnown.One ))
584
+ return Op.getOperand (1 );
585
+ break ;
586
+ }
587
+ case ISD::OR: {
588
+ LHSKnown = DAG.computeKnownBits (Op.getOperand (0 ), DemandedElts, Depth + 1 );
589
+ RHSKnown = DAG.computeKnownBits (Op.getOperand (1 ), DemandedElts, Depth + 1 );
590
+
591
+ // If all of the demanded bits are known zero on one side, return the
592
+ // other. These bits cannot contribute to the result of the 'or' in this
593
+ // context.
594
+ if (DemandedBits.isSubsetOf (LHSKnown.One | RHSKnown.Zero ))
595
+ return Op.getOperand (0 );
596
+ if (DemandedBits.isSubsetOf (RHSKnown.One | LHSKnown.Zero ))
597
+ return Op.getOperand (1 );
598
+ break ;
599
+ }
600
+ case ISD::XOR: {
601
+ LHSKnown = DAG.computeKnownBits (Op.getOperand (0 ), DemandedElts, Depth + 1 );
602
+ RHSKnown = DAG.computeKnownBits (Op.getOperand (1 ), DemandedElts, Depth + 1 );
603
+
604
+ // If all of the demanded bits are known zero on one side, return the
605
+ // other.
606
+ if (DemandedBits.isSubsetOf (RHSKnown.Zero ))
607
+ return Op.getOperand (0 );
608
+ if (DemandedBits.isSubsetOf (LHSKnown.Zero ))
609
+ return Op.getOperand (1 );
610
+ break ;
611
+ }
612
+ default :
613
+ if (Op.getOpcode () >= ISD::BUILTIN_OP_END)
614
+ if (SDValue V = SimplifyMultipleUseDemandedBitsForTargetNode (
615
+ Op, DemandedBits, DemandedElts, DAG, Depth))
616
+ return V;
617
+ break ;
618
+ }
619
+ return SDValue ();
620
+ }
621
+
567
622
// / Look at Op. At this point, we know that only the OriginalDemandedBits of the
568
623
// / result of Op are ever used downstream. If we can use this information to
569
624
// / simplify Op, create a new simplified DAG node and return true, returning the
@@ -834,6 +889,20 @@ bool TargetLowering::SimplifyDemandedBits(
834
889
return true ;
835
890
assert (!Known2.hasConflict () && " Bits known to be one AND zero?" );
836
891
892
+ // Attempt to avoid multi-use ops if we don't need anything from them.
893
+ if (!DemandedBits.isAllOnesValue () || !DemandedElts.isAllOnesValue ()) {
894
+ SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits (
895
+ Op0, DemandedBits, DemandedElts, TLO.DAG , Depth + 1 );
896
+ SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits (
897
+ Op1, DemandedBits, DemandedElts, TLO.DAG , Depth + 1 );
898
+ if (DemandedOp0 || DemandedOp1) {
899
+ Op0 = DemandedOp0 ? DemandedOp0 : Op0;
900
+ Op1 = DemandedOp1 ? DemandedOp1 : Op1;
901
+ SDValue NewOp = TLO.DAG .getNode (Op.getOpcode (), dl, VT, Op0, Op1);
902
+ return TLO.CombineTo (Op, NewOp);
903
+ }
904
+ }
905
+
837
906
// If all of the demanded bits are known one on one side, return the other.
838
907
// These bits cannot contribute to the result of the 'and'.
839
908
if (DemandedBits.isSubsetOf (Known2.Zero | Known.One ))
@@ -869,6 +938,20 @@ bool TargetLowering::SimplifyDemandedBits(
869
938
return true ;
870
939
assert (!Known2.hasConflict () && " Bits known to be one AND zero?" );
871
940
941
+ // Attempt to avoid multi-use ops if we don't need anything from them.
942
+ if (!DemandedBits.isAllOnesValue () || !DemandedElts.isAllOnesValue ()) {
943
+ SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits (
944
+ Op0, DemandedBits, DemandedElts, TLO.DAG , Depth + 1 );
945
+ SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits (
946
+ Op1, DemandedBits, DemandedElts, TLO.DAG , Depth + 1 );
947
+ if (DemandedOp0 || DemandedOp1) {
948
+ Op0 = DemandedOp0 ? DemandedOp0 : Op0;
949
+ Op1 = DemandedOp1 ? DemandedOp1 : Op1;
950
+ SDValue NewOp = TLO.DAG .getNode (Op.getOpcode (), dl, VT, Op0, Op1);
951
+ return TLO.CombineTo (Op, NewOp);
952
+ }
953
+ }
954
+
872
955
// If all of the demanded bits are known zero on one side, return the other.
873
956
// These bits cannot contribute to the result of the 'or'.
874
957
if (DemandedBits.isSubsetOf (Known2.One | Known.Zero ))
@@ -901,6 +984,20 @@ bool TargetLowering::SimplifyDemandedBits(
901
984
return true ;
902
985
assert (!Known2.hasConflict () && " Bits known to be one AND zero?" );
903
986
987
+ // Attempt to avoid multi-use ops if we don't need anything from them.
988
+ if (!DemandedBits.isAllOnesValue () || !DemandedElts.isAllOnesValue ()) {
989
+ SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits (
990
+ Op0, DemandedBits, DemandedElts, TLO.DAG , Depth + 1 );
991
+ SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits (
992
+ Op1, DemandedBits, DemandedElts, TLO.DAG , Depth + 1 );
993
+ if (DemandedOp0 || DemandedOp1) {
994
+ Op0 = DemandedOp0 ? DemandedOp0 : Op0;
995
+ Op1 = DemandedOp1 ? DemandedOp1 : Op1;
996
+ SDValue NewOp = TLO.DAG .getNode (Op.getOpcode (), dl, VT, Op0, Op1);
997
+ return TLO.CombineTo (Op, NewOp);
998
+ }
999
+ }
1000
+
904
1001
// If all of the demanded bits are known zero on one side, return the other.
905
1002
// These bits cannot contribute to the result of the 'xor'.
906
1003
if (DemandedBits.isSubsetOf (Known.Zero ))
@@ -1663,6 +1760,7 @@ bool TargetLowering::SimplifyDemandedBits(
1663
1760
// Add, Sub, and Mul don't demand any bits in positions beyond that
1664
1761
// of the highest bit demanded of them.
1665
1762
SDValue Op0 = Op.getOperand (0 ), Op1 = Op.getOperand (1 );
1763
+ SDNodeFlags Flags = Op.getNode ()->getFlags ();
1666
1764
unsigned DemandedBitsLZ = DemandedBits.countLeadingZeros ();
1667
1765
APInt LoMask = APInt::getLowBitsSet (BitWidth, BitWidth - DemandedBitsLZ);
1668
1766
if (SimplifyDemandedBits (Op0, LoMask, DemandedElts, Known2, TLO,
@@ -1671,7 +1769,6 @@ bool TargetLowering::SimplifyDemandedBits(
1671
1769
Depth + 1 ) ||
1672
1770
// See if the operation should be performed at a smaller bit width.
1673
1771
ShrinkDemandedOp (Op, BitWidth, DemandedBits, TLO)) {
1674
- SDNodeFlags Flags = Op.getNode ()->getFlags ();
1675
1772
if (Flags.hasNoSignedWrap () || Flags.hasNoUnsignedWrap ()) {
1676
1773
// Disable the nsw and nuw flags. We can no longer guarantee that we
1677
1774
// won't wrap after simplification.
@@ -1684,6 +1781,23 @@ bool TargetLowering::SimplifyDemandedBits(
1684
1781
return true ;
1685
1782
}
1686
1783
1784
+ // Attempt to avoid multi-use ops if we don't need anything from them.
1785
+ if (!LoMask.isAllOnesValue () || !DemandedElts.isAllOnesValue ()) {
1786
+ SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits (
1787
+ Op0, LoMask, DemandedElts, TLO.DAG , Depth + 1 );
1788
+ SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits (
1789
+ Op1, LoMask, DemandedElts, TLO.DAG , Depth + 1 );
1790
+ if (DemandedOp0 || DemandedOp1) {
1791
+ Flags.setNoSignedWrap (false );
1792
+ Flags.setNoUnsignedWrap (false );
1793
+ Op0 = DemandedOp0 ? DemandedOp0 : Op0;
1794
+ Op1 = DemandedOp1 ? DemandedOp1 : Op1;
1795
+ SDValue NewOp =
1796
+ TLO.DAG .getNode (Op.getOpcode (), dl, VT, Op0, Op1, Flags);
1797
+ return TLO.CombineTo (Op, NewOp);
1798
+ }
1799
+ }
1800
+
1687
1801
// If we have a constant operand, we may be able to turn it into -1 if we
1688
1802
// do not demand the high bits. This can make the constant smaller to
1689
1803
// encode, allow more general folding, or match specialized instruction
@@ -2357,6 +2471,19 @@ bool TargetLowering::SimplifyDemandedBitsForTargetNode(
2357
2471
return false ;
2358
2472
}
2359
2473
2474
+ SDValue TargetLowering::SimplifyMultipleUseDemandedBitsForTargetNode (
2475
+ SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
2476
+ SelectionDAG &DAG, unsigned Depth) const {
2477
+ assert (
2478
+ (Op.getOpcode () >= ISD::BUILTIN_OP_END ||
2479
+ Op.getOpcode () == ISD::INTRINSIC_WO_CHAIN ||
2480
+ Op.getOpcode () == ISD::INTRINSIC_W_CHAIN ||
2481
+ Op.getOpcode () == ISD::INTRINSIC_VOID) &&
2482
+ " Should use SimplifyMultipleUseDemandedBits if you don't know whether Op"
2483
+ " is a target node!" );
2484
+ return SDValue ();
2485
+ }
2486
+
2360
2487
const Constant *TargetLowering::getTargetConstantFromLoad (LoadSDNode*) const {
2361
2488
return nullptr ;
2362
2489
}
0 commit comments