@@ -858,6 +858,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
858
858
// We can use any register for comparisons
859
859
setHasMultipleConditionRegisters ();
860
860
861
+ setTargetDAGCombine (ISD::ADD);
862
+ setTargetDAGCombine (ISD::SUB);
861
863
setTargetDAGCombine (ISD::AND);
862
864
setTargetDAGCombine (ISD::OR);
863
865
setTargetDAGCombine (ISD::XOR);
@@ -5769,26 +5771,37 @@ static SDValue combineGREVI_GORCI(SDNode *N, SelectionDAG &DAG) {
5769
5771
5770
5772
// Combine a constant select operand into its use:
5771
5773
//
5772
- // (and (select_cc lhs, rhs, cc, -1, c), x)
5773
- // -> (select_cc lhs, rhs, cc, x, (and, x, c)) [AllOnes=1]
5774
- // (or (select_cc lhs, rhs, cc, 0, c), x)
5775
- // -> (select_cc lhs, rhs, cc, x, (or, x, c)) [AllOnes=0]
5776
- // (xor (select_cc lhs, rhs, cc, 0, c), x)
5777
- // -> (select_cc lhs, rhs, cc, x, (xor, x, c)) [AllOnes=0]
5778
- static SDValue combineSelectCCAndUse (SDNode *N, SDValue Slct, SDValue OtherOp,
5779
- SelectionDAG &DAG, bool AllOnes) {
5774
+ // (and (select cond, -1, c), x)
5775
+ // -> (select cond, x, (and x, c)) [AllOnes=1]
5776
+ // (or (select cond, 0, c), x)
5777
+ // -> (select cond, x, (or x, c)) [AllOnes=0]
5778
+ // (xor (select cond, 0, c), x)
5779
+ // -> (select cond, x, (xor x, c)) [AllOnes=0]
5780
+ // (add (select cond, 0, c), x)
5781
+ // -> (select cond, x, (add x, c)) [AllOnes=0]
5782
+ // (sub x, (select cond, 0, c))
5783
+ // -> (select cond, x, (sub x, c)) [AllOnes=0]
5784
+ static SDValue combineSelectAndUse (SDNode *N, SDValue Slct, SDValue OtherOp,
5785
+ SelectionDAG &DAG, bool AllOnes) {
5780
5786
EVT VT = N->getValueType (0 );
5781
5787
5782
- if (Slct.getOpcode () != RISCVISD::SELECT_CC || !Slct.hasOneUse ())
5788
+ // Skip vectors.
5789
+ if (VT.isVector ())
5790
+ return SDValue ();
5791
+
5792
+ if ((Slct.getOpcode () != ISD::SELECT &&
5793
+ Slct.getOpcode () != RISCVISD::SELECT_CC) ||
5794
+ !Slct.hasOneUse ())
5783
5795
return SDValue ();
5784
5796
5785
5797
auto isZeroOrAllOnes = [](SDValue N, bool AllOnes) {
5786
5798
return AllOnes ? isAllOnesConstant (N) : isNullConstant (N);
5787
5799
};
5788
5800
5789
5801
bool SwapSelectOps;
5790
- SDValue TrueVal = Slct.getOperand (3 );
5791
- SDValue FalseVal = Slct.getOperand (4 );
5802
+ unsigned OpOffset = Slct.getOpcode () == RISCVISD::SELECT_CC ? 2 : 0 ;
5803
+ SDValue TrueVal = Slct.getOperand (1 + OpOffset);
5804
+ SDValue FalseVal = Slct.getOperand (2 + OpOffset);
5792
5805
SDValue NonConstantVal;
5793
5806
if (isZeroOrAllOnes (TrueVal, AllOnes)) {
5794
5807
SwapSelectOps = false ;
@@ -5802,40 +5815,53 @@ static SDValue combineSelectCCAndUse(SDNode *N, SDValue Slct, SDValue OtherOp,
5802
5815
// Slct is now know to be the desired identity constant when CC is true.
5803
5816
TrueVal = OtherOp;
5804
5817
FalseVal = DAG.getNode (N->getOpcode (), SDLoc (N), VT, OtherOp, NonConstantVal);
5805
- // Unless SwapSelectOps says CC should be false.
5818
+ // Unless SwapSelectOps says the condition should be false.
5806
5819
if (SwapSelectOps)
5807
5820
std::swap (TrueVal, FalseVal);
5808
5821
5809
- return DAG.getNode (RISCVISD::SELECT_CC, SDLoc (N), VT,
5810
- {Slct.getOperand (0 ), Slct.getOperand (1 ),
5811
- Slct.getOperand (2 ), TrueVal, FalseVal});
5822
+ if (Slct.getOpcode () == RISCVISD::SELECT_CC)
5823
+ return DAG.getNode (RISCVISD::SELECT_CC, SDLoc (N), VT,
5824
+ {Slct.getOperand (0 ), Slct.getOperand (1 ),
5825
+ Slct.getOperand (2 ), TrueVal, FalseVal});
5826
+
5827
+ return DAG.getNode (ISD::SELECT, SDLoc (N), VT,
5828
+ {Slct.getOperand (0 ), TrueVal, FalseVal});
5812
5829
}
5813
5830
5814
5831
// Attempt combineSelectAndUse on each operand of a commutative operator N.
5815
- static SDValue combineSelectCCAndUseCommutative (SDNode *N, SelectionDAG &DAG,
5816
- bool AllOnes) {
5832
+ static SDValue combineSelectAndUseCommutative (SDNode *N, SelectionDAG &DAG,
5833
+ bool AllOnes) {
5817
5834
SDValue N0 = N->getOperand (0 );
5818
5835
SDValue N1 = N->getOperand (1 );
5819
- if (SDValue Result = combineSelectCCAndUse (N, N0, N1, DAG, AllOnes))
5836
+ if (SDValue Result = combineSelectAndUse (N, N0, N1, DAG, AllOnes))
5820
5837
return Result;
5821
- if (SDValue Result = combineSelectCCAndUse (N, N1, N0, DAG, AllOnes))
5838
+ if (SDValue Result = combineSelectAndUse (N, N1, N0, DAG, AllOnes))
5822
5839
return Result;
5823
5840
return SDValue ();
5824
5841
}
5825
5842
5826
- static SDValue performANDCombine (SDNode *N,
5827
- TargetLowering::DAGCombinerInfo &DCI,
5828
- const RISCVSubtarget &Subtarget) {
5829
- SelectionDAG &DAG = DCI.DAG ;
5843
+ static SDValue performADDCombine (SDNode *N, SelectionDAG &DAG) {
5844
+ // fold (add (select lhs, rhs, cc, 0, y), x) ->
5845
+ // (select lhs, rhs, cc, x, (add x, y))
5846
+ return combineSelectAndUseCommutative (N, DAG, /* AllOnes*/ false );
5847
+ }
5830
5848
5831
- // fold (and (select_cc lhs, rhs, cc, -1, y), x) ->
5849
+ static SDValue performSUBCombine (SDNode *N, SelectionDAG &DAG) {
5850
+ // fold (sub x, (select lhs, rhs, cc, 0, y)) ->
5851
+ // (select lhs, rhs, cc, x, (sub x, y))
5852
+ SDValue N0 = N->getOperand (0 );
5853
+ SDValue N1 = N->getOperand (1 );
5854
+ return combineSelectAndUse (N, N1, N0, DAG, /* AllOnes*/ false );
5855
+ }
5856
+
5857
+ static SDValue performANDCombine (SDNode *N, SelectionDAG &DAG) {
5858
+ // fold (and (select lhs, rhs, cc, -1, y), x) ->
5832
5859
// (select lhs, rhs, cc, x, (and x, y))
5833
- return combineSelectCCAndUseCommutative (N, DAG, true );
5860
+ return combineSelectAndUseCommutative (N, DAG, /* AllOnes */ true );
5834
5861
}
5835
5862
5836
- static SDValue performORCombine (SDNode *N, TargetLowering::DAGCombinerInfo &DCI ,
5863
+ static SDValue performORCombine (SDNode *N, SelectionDAG &DAG ,
5837
5864
const RISCVSubtarget &Subtarget) {
5838
- SelectionDAG &DAG = DCI.DAG ;
5839
5865
if (Subtarget.hasStdExtZbp ()) {
5840
5866
if (auto GREV = combineORToGREV (SDValue (N, 0 ), DAG, Subtarget))
5841
5867
return GREV;
@@ -5845,19 +5871,15 @@ static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
5845
5871
return SHFL;
5846
5872
}
5847
5873
5848
- // fold (or (select_cc lhs, rhs, cc , 0, y), x) ->
5849
- // (select lhs, rhs, cc , x, (or x, y))
5850
- return combineSelectCCAndUseCommutative (N, DAG, false );
5874
+ // fold (or (select cond , 0, y), x) ->
5875
+ // (select cond , x, (or x, y))
5876
+ return combineSelectAndUseCommutative (N, DAG, /* AllOnes */ false );
5851
5877
}
5852
5878
5853
- static SDValue performXORCombine (SDNode *N,
5854
- TargetLowering::DAGCombinerInfo &DCI,
5855
- const RISCVSubtarget &Subtarget) {
5856
- SelectionDAG &DAG = DCI.DAG ;
5857
-
5858
- // fold (xor (select_cc lhs, rhs, cc, 0, y), x) ->
5859
- // (select lhs, rhs, cc, x, (xor x, y))
5860
- return combineSelectCCAndUseCommutative (N, DAG, false );
5879
+ static SDValue performXORCombine (SDNode *N, SelectionDAG &DAG) {
5880
+ // fold (xor (select cond, 0, y), x) ->
5881
+ // (select cond, x, (xor x, y))
5882
+ return combineSelectAndUseCommutative (N, DAG, /* AllOnes*/ false );
5861
5883
}
5862
5884
5863
5885
// Attempt to turn ANY_EXTEND into SIGN_EXTEND if the input to the ANY_EXTEND
@@ -6167,12 +6189,16 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
6167
6189
return DAG.getNode (ISD::AND, DL, VT, NewFMV,
6168
6190
DAG.getConstant (~SignBit, DL, VT));
6169
6191
}
6192
+ case ISD::ADD:
6193
+ return performADDCombine (N, DAG);
6194
+ case ISD::SUB:
6195
+ return performSUBCombine (N, DAG);
6170
6196
case ISD::AND:
6171
- return performANDCombine (N, DCI, Subtarget );
6197
+ return performANDCombine (N, DAG );
6172
6198
case ISD::OR:
6173
- return performORCombine (N, DCI , Subtarget);
6199
+ return performORCombine (N, DAG , Subtarget);
6174
6200
case ISD::XOR:
6175
- return performXORCombine (N, DCI, Subtarget );
6201
+ return performXORCombine (N, DAG );
6176
6202
case ISD::ANY_EXTEND:
6177
6203
return performANY_EXTENDCombine (N, DCI, Subtarget);
6178
6204
case ISD::ZERO_EXTEND:
0 commit comments