@@ -5282,7 +5282,7 @@ static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG,
52825282 Src.getOperand (0 ));
52835283}
52845284
5285- // Perform combines for BR_CC conditions.
5285+ // Perform common combines for BR_CC and SELECT_CC conditions.
52865286static bool combine_CC (SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
52875287 SelectionDAG &DAG, const LoongArchSubtarget &Subtarget) {
52885288 ISD::CondCode CCVal = cast<CondCodeSDNode>(CC)->get ();
@@ -5319,6 +5319,29 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
53195319 return true ;
53205320 }
53215321
5322+ // Fold ((srl (and X, 1<<C), C), 0, eq/ne) -> ((shl X, GRLen-1-C), 0, ge/lt)
5323+ if (isNullConstant (RHS) && LHS.getOpcode () == ISD::SRL && LHS.hasOneUse () &&
5324+ LHS.getOperand (1 ).getOpcode () == ISD::Constant) {
5325+ SDValue LHS0 = LHS.getOperand (0 );
5326+ if (LHS0.getOpcode () == ISD::AND &&
5327+ LHS0.getOperand (1 ).getOpcode () == ISD::Constant) {
5328+ uint64_t Mask = LHS0.getConstantOperandVal (1 );
5329+ uint64_t ShAmt = LHS.getConstantOperandVal (1 );
5330+ if (isPowerOf2_64 (Mask) && Log2_64 (Mask) == ShAmt) {
5331+ CCVal = CCVal == ISD::SETEQ ? ISD::SETGE : ISD::SETLT;
5332+ CC = DAG.getCondCode (CCVal);
5333+
5334+ ShAmt = LHS.getValueSizeInBits () - 1 - ShAmt;
5335+ LHS = LHS0.getOperand (0 );
5336+ if (ShAmt != 0 )
5337+ LHS =
5338+ DAG.getNode (ISD::SHL, DL, LHS.getValueType (), LHS0.getOperand (0 ),
5339+ DAG.getConstant (ShAmt, DL, LHS.getValueType ()));
5340+ return true ;
5341+ }
5342+ }
5343+ }
5344+
53225345 // (X, 1, setne) -> (X, 0, seteq) if we can prove X is 0/1.
53235346 // This can occur when legalizing some floating point comparisons.
53245347 APInt Mask = APInt::getBitsSetFrom (LHS.getValueSizeInBits (), 1 );
@@ -5347,6 +5370,57 @@ static SDValue performBR_CCCombine(SDNode *N, SelectionDAG &DAG,
53475370 return SDValue ();
53485371}
53495372
5373+ static SDValue performSELECT_CCCombine (SDNode *N, SelectionDAG &DAG,
5374+ TargetLowering::DAGCombinerInfo &DCI,
5375+ const LoongArchSubtarget &Subtarget) {
5376+ // Transform
5377+ SDValue LHS = N->getOperand (0 );
5378+ SDValue RHS = N->getOperand (1 );
5379+ SDValue CC = N->getOperand (2 );
5380+ ISD::CondCode CCVal = cast<CondCodeSDNode>(CC)->get ();
5381+ SDValue TrueV = N->getOperand (3 );
5382+ SDValue FalseV = N->getOperand (4 );
5383+ SDLoc DL (N);
5384+ EVT VT = N->getValueType (0 );
5385+
5386+ // If the True and False values are the same, we don't need a select_cc.
5387+ if (TrueV == FalseV)
5388+ return TrueV;
5389+
5390+ // (select (x < 0), y, z) -> x >> (GRLEN - 1) & (y - z) + z
5391+ // (select (x >= 0), y, z) -> x >> (GRLEN - 1) & (z - y) + y
5392+ if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV) &&
5393+ isNullConstant (RHS) &&
5394+ (CCVal == ISD::CondCode::SETLT || CCVal == ISD::CondCode::SETGE)) {
5395+ if (CCVal == ISD::CondCode::SETGE)
5396+ std::swap (TrueV, FalseV);
5397+
5398+ int64_t TrueSImm = cast<ConstantSDNode>(TrueV)->getSExtValue ();
5399+ int64_t FalseSImm = cast<ConstantSDNode>(FalseV)->getSExtValue ();
5400+ // Only handle simm12, if it is not in this range, it can be considered as
5401+ // register.
5402+ if (isInt<12 >(TrueSImm) && isInt<12 >(FalseSImm) &&
5403+ isInt<12 >(TrueSImm - FalseSImm)) {
5404+ SDValue SRA =
5405+ DAG.getNode (ISD::SRA, DL, VT, LHS,
5406+ DAG.getConstant (Subtarget.getGRLen () - 1 , DL, VT));
5407+ SDValue AND =
5408+ DAG.getNode (ISD::AND, DL, VT, SRA,
5409+ DAG.getSignedConstant (TrueSImm - FalseSImm, DL, VT));
5410+ return DAG.getNode (ISD::ADD, DL, VT, AND, FalseV);
5411+ }
5412+
5413+ if (CCVal == ISD::CondCode::SETGE)
5414+ std::swap (TrueV, FalseV);
5415+ }
5416+
5417+ if (combine_CC (LHS, RHS, CC, DL, DAG, Subtarget))
5418+ return DAG.getNode (LoongArchISD::SELECT_CC, DL, N->getValueType (0 ),
5419+ {LHS, RHS, CC, TrueV, FalseV});
5420+
5421+ return SDValue ();
5422+ }
5423+
53505424template <unsigned N>
53515425static SDValue legalizeIntrinsicImmArg (SDNode *Node, unsigned ImmOp,
53525426 SelectionDAG &DAG,
@@ -6041,6 +6115,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
60416115 return performBITREV_WCombine (N, DAG, DCI, Subtarget);
60426116 case LoongArchISD::BR_CC:
60436117 return performBR_CCCombine (N, DAG, DCI, Subtarget);
6118+ case LoongArchISD::SELECT_CC:
6119+ return performSELECT_CCCombine (N, DAG, DCI, Subtarget);
60446120 case ISD::INTRINSIC_WO_CHAIN:
60456121 return performINTRINSIC_WO_CHAINCombine (N, DAG, DCI, Subtarget);
60466122 case LoongArchISD::MOVGR2FR_W_LA64:
0 commit comments