@@ -127,6 +127,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
127127
128128 setOperationAction (ISD::BR_JT, MVT::Other, Expand);
129129 setOperationAction (ISD::BR_CC, GRLenVT, Expand);
130+ setOperationAction (ISD::BRCOND, MVT::Other, Custom);
130131 setOperationAction (ISD::SELECT_CC, GRLenVT, Expand);
131132 setOperationAction (ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
132133 setOperationAction ({ISD::SMUL_LOHI, ISD::UMUL_LOHI}, GRLenVT, Expand);
@@ -516,6 +517,8 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
516517 return lowerPREFETCH (Op, DAG);
517518 case ISD::SELECT:
518519 return lowerSELECT (Op, DAG);
520+ case ISD::BRCOND:
521+ return lowerBRCOND (Op, DAG);
519522 case ISD::FP_TO_FP16:
520523 return lowerFP_TO_FP16 (Op, DAG);
521524 case ISD::FP16_TO_FP:
@@ -913,6 +916,35 @@ SDValue LoongArchTargetLowering::lowerSELECT(SDValue Op,
913916 return DAG.getNode (LoongArchISD::SELECT_CC, DL, VT, Ops);
914917}
915918
919+ SDValue LoongArchTargetLowering::lowerBRCOND (SDValue Op,
920+ SelectionDAG &DAG) const {
921+ SDValue CondV = Op.getOperand (1 );
922+ SDLoc DL (Op);
923+ MVT GRLenVT = Subtarget.getGRLenVT ();
924+
925+ if (CondV.getOpcode () == ISD::SETCC) {
926+ if (CondV.getOperand (0 ).getValueType () == GRLenVT) {
927+ SDValue LHS = CondV.getOperand (0 );
928+ SDValue RHS = CondV.getOperand (1 );
929+ ISD::CondCode CCVal = cast<CondCodeSDNode>(CondV.getOperand (2 ))->get ();
930+
931+ translateSetCCForBranch (DL, LHS, RHS, CCVal, DAG);
932+
933+ SDValue TargetCC = DAG.getCondCode (CCVal);
934+ return DAG.getNode (LoongArchISD::BR_CC, DL, Op.getValueType (),
935+ Op.getOperand (0 ), LHS, RHS, TargetCC,
936+ Op.getOperand (2 ));
937+ } else if (CondV.getOperand (0 ).getValueType ().isFloatingPoint ()) {
938+ return DAG.getNode (LoongArchISD::BRCOND, DL, Op.getValueType (),
939+ Op.getOperand (0 ), CondV, Op.getOperand (2 ));
940+ }
941+ }
942+
943+ return DAG.getNode (LoongArchISD::BR_CC, DL, Op.getValueType (),
944+ Op.getOperand (0 ), CondV, DAG.getConstant (0 , DL, GRLenVT),
945+ DAG.getCondCode (ISD::SETNE), Op.getOperand (2 ));
946+ }
947+
916948SDValue
917949LoongArchTargetLowering::lowerSCALAR_TO_VECTOR (SDValue Op,
918950 SelectionDAG &DAG) const {
@@ -5224,6 +5256,71 @@ static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG,
52245256 Src.getOperand (0 ));
52255257}
52265258
5259+ // Perform combines for BR_CC conditions.
5260+ static bool combine_CC (SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
5261+ SelectionDAG &DAG, const LoongArchSubtarget &Subtarget) {
5262+ ISD::CondCode CCVal = cast<CondCodeSDNode>(CC)->get ();
5263+
5264+ // As far as arithmetic right shift always saves the sign,
5265+ // shift can be omitted.
5266+ // Fold setlt (sra X, N), 0 -> setlt X, 0 and
5267+ // setge (sra X, N), 0 -> setge X, 0
5268+ if (isNullConstant (RHS) && (CCVal == ISD::SETGE || CCVal == ISD::SETLT) &&
5269+ LHS.getOpcode () == ISD::SRA) {
5270+ LHS = LHS.getOperand (0 );
5271+ return true ;
5272+ }
5273+
5274+ if (!ISD::isIntEqualitySetCC (CCVal))
5275+ return false ;
5276+
5277+ // Fold ((setlt X, Y), 0, ne) -> (X, Y, lt)
5278+ // Sometimes the setcc is introduced after br_cc/select_cc has been formed.
5279+ if (LHS.getOpcode () == ISD::SETCC && isNullConstant (RHS) &&
5280+ LHS.getOperand (0 ).getValueType () == Subtarget.getGRLenVT ()) {
5281+ // If we're looking for eq 0 instead of ne 0, we need to invert the
5282+ // condition.
5283+ bool Invert = CCVal == ISD::SETEQ;
5284+ CCVal = cast<CondCodeSDNode>(LHS.getOperand (2 ))->get ();
5285+ if (Invert)
5286+ CCVal = ISD::getSetCCInverse (CCVal, LHS.getValueType ());
5287+
5288+ RHS = LHS.getOperand (1 );
5289+ LHS = LHS.getOperand (0 );
5290+ translateSetCCForBranch (DL, LHS, RHS, CCVal, DAG);
5291+
5292+ CC = DAG.getCondCode (CCVal);
5293+ return true ;
5294+ }
5295+
5296+ // (X, 1, setne) -> (X, 0, seteq) if we can prove X is 0/1.
5297+ // This can occur when legalizing some floating point comparisons.
5298+ APInt Mask = APInt::getBitsSetFrom (LHS.getValueSizeInBits (), 1 );
5299+ if (isOneConstant (RHS) && DAG.MaskedValueIsZero (LHS, Mask)) {
5300+ CCVal = ISD::getSetCCInverse (CCVal, LHS.getValueType ());
5301+ CC = DAG.getCondCode (CCVal);
5302+ RHS = DAG.getConstant (0 , DL, LHS.getValueType ());
5303+ return true ;
5304+ }
5305+
5306+ return false ;
5307+ }
5308+
5309+ static SDValue performBR_CCCombine (SDNode *N, SelectionDAG &DAG,
5310+ TargetLowering::DAGCombinerInfo &DCI,
5311+ const LoongArchSubtarget &Subtarget) {
5312+ SDValue LHS = N->getOperand (1 );
5313+ SDValue RHS = N->getOperand (2 );
5314+ SDValue CC = N->getOperand (3 );
5315+ SDLoc DL (N);
5316+
5317+ if (combine_CC (LHS, RHS, CC, DL, DAG, Subtarget))
5318+ return DAG.getNode (LoongArchISD::BR_CC, DL, N->getValueType (0 ),
5319+ N->getOperand (0 ), LHS, RHS, CC, N->getOperand (4 ));
5320+
5321+ return SDValue ();
5322+ }
5323+
52275324template <unsigned N>
52285325static SDValue legalizeIntrinsicImmArg (SDNode *Node, unsigned ImmOp,
52295326 SelectionDAG &DAG,
@@ -5916,6 +6013,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
59166013 return performBITCASTCombine (N, DAG, DCI, Subtarget);
59176014 case LoongArchISD::BITREV_W:
59186015 return performBITREV_WCombine (N, DAG, DCI, Subtarget);
6016+ case LoongArchISD::BR_CC:
6017+ return performBR_CCCombine (N, DAG, DCI, Subtarget);
59196018 case ISD::INTRINSIC_WO_CHAIN:
59206019 return performINTRINSIC_WO_CHAINCombine (N, DAG, DCI, Subtarget);
59216020 case LoongArchISD::MOVGR2FR_W_LA64:
@@ -6645,6 +6744,8 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
66456744 NODE_NAME_CASE (TAIL_MEDIUM)
66466745 NODE_NAME_CASE (TAIL_LARGE)
66476746 NODE_NAME_CASE (SELECT_CC)
6747+ NODE_NAME_CASE (BR_CC)
6748+ NODE_NAME_CASE (BRCOND)
66486749 NODE_NAME_CASE (SLL_W)
66496750 NODE_NAME_CASE (SRA_W)
66506751 NODE_NAME_CASE (SRL_W)
0 commit comments