@@ -10350,6 +10350,60 @@ SDValue RISCVTargetLowering::joinRegisterPartsIntoValue(
10350
10350
return SDValue ();
10351
10351
}
10352
10352
10353
+ SDValue
10354
+ RISCVTargetLowering::BuildSDIVPow2 (SDNode *N, const APInt &Divisor,
10355
+ SelectionDAG &DAG,
10356
+ SmallVectorImpl<SDNode *> &Created) const {
10357
+ AttributeList Attr = DAG.getMachineFunction ().getFunction ().getAttributes ();
10358
+ if (isIntDivCheap (N->getValueType (0 ), Attr))
10359
+ return SDValue (N, 0 ); // Lower SDIV as SDIV
10360
+
10361
+ assert ((Divisor.isPowerOf2 () || Divisor.isNegatedPowerOf2 ()) &&
10362
+ " Unexpected divisor!" );
10363
+
10364
+ // Conditional move is needed, so do the transformation iff Zbt is enabled.
10365
+ if (!Subtarget.hasStdExtZbt ())
10366
+ return SDValue ();
10367
+
10368
+ // When |Divisor| >= 2 ^ 12, it isn't profitable to do such transformation.
10369
+ // Besides, more critical path instructions will be generated when dividing
10370
+ // by 2. So we keep using the original DAGs for these cases.
10371
+ unsigned Lg2 = Divisor.countTrailingZeros ();
10372
+ if (Lg2 == 1 || Lg2 >= 12 )
10373
+ return SDValue ();
10374
+
10375
+ // fold (sdiv X, pow2)
10376
+ EVT VT = N->getValueType (0 );
10377
+ if (VT != MVT::i32 && !(Subtarget.is64Bit () && VT == MVT::i64 ))
10378
+ return SDValue ();
10379
+
10380
+ SDLoc DL (N);
10381
+ SDValue N0 = N->getOperand (0 );
10382
+ SDValue Zero = DAG.getConstant (0 , DL, VT);
10383
+ SDValue Pow2MinusOne = DAG.getConstant ((1ULL << Lg2) - 1 , DL, VT);
10384
+
10385
+ // Add (N0 < 0) ? Pow2 - 1 : 0;
10386
+ SDValue Cmp = DAG.getSetCC (DL, VT, N0, Zero, ISD::SETLT);
10387
+ SDValue Add = DAG.getNode (ISD::ADD, DL, VT, N0, Pow2MinusOne);
10388
+ SDValue Sel = DAG.getNode (ISD::SELECT, DL, VT, Cmp, Add, N0);
10389
+
10390
+ Created.push_back (Cmp.getNode ());
10391
+ Created.push_back (Add.getNode ());
10392
+ Created.push_back (Sel.getNode ());
10393
+
10394
+ // Divide by pow2.
10395
+ SDValue SRA =
10396
+ DAG.getNode (ISD::SRA, DL, VT, Sel, DAG.getConstant (Lg2, DL, VT));
10397
+
10398
+ // If we're dividing by a positive value, we're done. Otherwise, we must
10399
+ // negate the result.
10400
+ if (Divisor.isNonNegative ())
10401
+ return SRA;
10402
+
10403
+ Created.push_back (SRA.getNode ());
10404
+ return DAG.getNode (ISD::SUB, DL, VT, DAG.getConstant (0 , DL, VT), SRA);
10405
+ }
10406
+
10353
10407
#define GET_REGISTER_MATCHER
10354
10408
#include " RISCVGenAsmMatcher.inc"
10355
10409
0 commit comments