@@ -1490,7 +1490,7 @@ void CombinerHelper::applyOptBrCondByInvertingCond(MachineInstr &MI,
1490
1490
Observer.changedInstr (*BrCond);
1491
1491
}
1492
1492
1493
-
1493
+
1494
1494
bool CombinerHelper::tryEmitMemcpyInline (MachineInstr &MI) {
1495
1495
MachineIRBuilder HelperBuilder (MI);
1496
1496
GISelObserverWrapper DummyObserver;
@@ -5286,6 +5286,62 @@ MachineInstr *CombinerHelper::buildSDivUsingMul(MachineInstr &MI) {
5286
5286
return MIB.buildMul (Ty, Res, Factor);
5287
5287
}
5288
5288
5289
+ bool CombinerHelper::matchSDivByPow2 (MachineInstr &MI) {
5290
+ assert (MI.getOpcode () == TargetOpcode::G_SDIV && " Expected SDIV" );
5291
+ auto &SDiv = cast<GenericMachineInstr>(MI);
5292
+ Register RHS = SDiv.getReg (2 );
5293
+ auto MatchPow2 = [&](const Constant *C) {
5294
+ if (auto *CI = dyn_cast<ConstantInt>(C))
5295
+ return CI->getValue ().isPowerOf2 () || CI->getValue ().isNegatedPowerOf2 ();
5296
+ return false ;
5297
+ };
5298
+ return matchUnaryPredicate (MRI, RHS, MatchPow2, /* AllowUndefs */ false );
5299
+ }
5300
+
5301
+ void CombinerHelper::applySDivByPow2 (MachineInstr &MI) {
5302
+ assert (MI.getOpcode () == TargetOpcode::G_SDIV && " Expected SDIV" );
5303
+ auto &SDiv = cast<GenericMachineInstr>(MI);
5304
+ Register Dst = SDiv.getReg (0 );
5305
+ Register LHS = SDiv.getReg (1 );
5306
+ Register RHS = SDiv.getReg (2 );
5307
+ LLT Ty = MRI.getType (Dst);
5308
+ LLT ShiftAmtTy = getTargetLowering ().getPreferredShiftAmountTy (Ty);
5309
+ LLT CVT = LLT::scalar (1 );
5310
+
5311
+ Builder.setInstrAndDebugLoc (MI);
5312
+
5313
+ unsigned Bitwidth = Ty.getScalarSizeInBits ();
5314
+ auto Bits = Builder.buildConstant (ShiftAmtTy, Bitwidth);
5315
+ auto C1 = Builder.buildCTTZ (Ty, RHS);
5316
+ C1 = Builder.buildZExtOrTrunc (ShiftAmtTy, C1);
5317
+ auto Inexact = Builder.buildSub (ShiftAmtTy, Bits, C1);
5318
+ // TODO: Need to check whether Inexact is constant
5319
+ auto Sign = Builder.buildAShr (
5320
+ Ty, LHS, Builder.buildConstant (ShiftAmtTy, Bitwidth - 1 ));
5321
+ // Add (LHS < 0) ? abs2 - 1 : 0;
5322
+ auto Srl = Builder.buildShl (Ty, Sign, Inexact);
5323
+ auto Add = Builder.buildAdd (Ty, LHS, Srl);
5324
+ auto Sra = Builder.buildAShr (Ty, Add, C1);
5325
+ // Special case: (sdiv X, 1) -> X
5326
+ // Special Case: (sdiv X, -1) -> 0-X
5327
+ auto One = Builder.buildConstant (Ty, 1 );
5328
+ auto AllOnes = Builder.buildConstant (Ty, APInt::getAllOnes (Bitwidth));
5329
+ auto IsOne = Builder.buildICmp (CmpInst::Predicate::ICMP_EQ, CVT, RHS, One);
5330
+ auto IsAllOnes =
5331
+ Builder.buildICmp (CmpInst::Predicate::ICMP_EQ, CVT, RHS, AllOnes);
5332
+ auto IsOneOrAllOnes = Builder.buildOr (CVT, IsOne, IsAllOnes);
5333
+ Sra = Builder.buildSelect (Ty, IsOneOrAllOnes, LHS, Sra);
5334
+
5335
+ // If dividing by a positive value, we're done. Otherwise, the result must
5336
+ // be negated.
5337
+ auto Zero = Builder.buildConstant (Ty, 0 );
5338
+ auto Sub = Builder.buildSub (Ty, Zero, Sra);
5339
+ auto IsNeg = Builder.buildICmp (CmpInst::Predicate::ICMP_SLT, CVT, RHS, Zero);
5340
+ auto Res = Builder.buildSelect (Ty, IsNeg, Sub, Sra);
5341
+
5342
+ replaceSingleDefInstWithReg (MI, Res->getOperand (0 ).getReg ());
5343
+ }
5344
+
5289
5345
bool CombinerHelper::matchUMulHToLShr (MachineInstr &MI) {
5290
5346
assert (MI.getOpcode () == TargetOpcode::G_UMULH);
5291
5347
Register RHS = MI.getOperand (2 ).getReg ();
0 commit comments