@@ -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,106 @@ 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
+ if (MI.getFlag (MachineInstr::MIFlag::IsExact))
5292
+ return false ;
5293
+ auto &SDiv = cast<GenericMachineInstr>(MI);
5294
+ Register RHS = SDiv.getReg (2 );
5295
+ auto MatchPow2 = [&](const Constant *C) {
5296
+ if (auto *CI = dyn_cast<ConstantInt>(C))
5297
+ return CI->getValue ().isPowerOf2 () || CI->getValue ().isNegatedPowerOf2 ();
5298
+ return false ;
5299
+ };
5300
+ return matchUnaryPredicate (MRI, RHS, MatchPow2, /* AllowUndefs */ false );
5301
+ }
5302
+
5303
+ void CombinerHelper::applySDivByPow2 (MachineInstr &MI) {
5304
+ assert (MI.getOpcode () == TargetOpcode::G_SDIV && " Expected SDIV" );
5305
+ auto &SDiv = cast<GenericMachineInstr>(MI);
5306
+ Register Dst = SDiv.getReg (0 );
5307
+ Register LHS = SDiv.getReg (1 );
5308
+ Register RHS = SDiv.getReg (2 );
5309
+ LLT Ty = MRI.getType (Dst);
5310
+ LLT ShiftAmtTy = getTargetLowering ().getPreferredShiftAmountTy (Ty);
5311
+
5312
+ Builder.setInstrAndDebugLoc (MI);
5313
+
5314
+ auto RHSC = getIConstantVRegValWithLookThrough (RHS, MRI);
5315
+ assert (RHSC.has_value () && " RHS must be a constant" );
5316
+ auto RHSCV = RHSC->Value ;
5317
+ auto Zero = Builder.buildConstant (Ty, 0 );
5318
+
5319
+ // Special case: (sdiv X, 1) -> X
5320
+ if (RHSCV.isOne ()) {
5321
+ replaceSingleDefInstWithReg (MI, LHS);
5322
+ return ;
5323
+ }
5324
+ // Special Case: (sdiv X, -1) -> 0-X
5325
+ if (RHSCV.isAllOnes ()) {
5326
+ auto Sub = Builder.buildSub (Ty, Zero, LHS);
5327
+ replaceSingleDefInstWithReg (MI, Sub->getOperand (0 ).getReg ());
5328
+ return ;
5329
+ }
5330
+
5331
+ unsigned Bitwidth = Ty.getScalarSizeInBits ();
5332
+ unsigned TrailingZeros = RHSCV.countTrailingZeros ();
5333
+ auto C1 = Builder.buildConstant (ShiftAmtTy, TrailingZeros);
5334
+ auto Inexact = Builder.buildConstant (ShiftAmtTy, Bitwidth - TrailingZeros);
5335
+ auto Sign = Builder.buildAShr (
5336
+ Ty, LHS, Builder.buildConstant (ShiftAmtTy, Bitwidth - 1 ));
5337
+ // Add (LHS < 0) ? abs2 - 1 : 0;
5338
+ auto Srl = Builder.buildShl (Ty, Sign, Inexact);
5339
+ auto Add = Builder.buildAdd (Ty, LHS, Srl);
5340
+ auto Sra = Builder.buildAShr (Ty, Add, C1);
5341
+
5342
+ // If dividing by a positive value, we're done. Otherwise, the result must
5343
+ // be negated.
5344
+ auto Res = RHSCV.isNegative () ? Builder.buildSub (Ty, Zero, Sra) : Sra;
5345
+ replaceSingleDefInstWithReg (MI, Res->getOperand (0 ).getReg ());
5346
+ }
5347
+
5348
+ bool CombinerHelper::matchUDivByPow2 (MachineInstr &MI) {
5349
+ assert (MI.getOpcode () == TargetOpcode::G_UDIV && " Expected UDIV" );
5350
+ if (MI.getFlag (MachineInstr::MIFlag::IsExact))
5351
+ return false ;
5352
+ auto &UDiv = cast<GenericMachineInstr>(MI);
5353
+ Register RHS = UDiv.getReg (2 );
5354
+ auto MatchPow2 = [&](const Constant *C) {
5355
+ if (auto *CI = dyn_cast<ConstantInt>(C))
5356
+ return CI->getValue ().isPowerOf2 ();
5357
+ return false ;
5358
+ };
5359
+ return matchUnaryPredicate (MRI, RHS, MatchPow2, /* AllowUndefs */ false );
5360
+ }
5361
+
5362
+ void CombinerHelper::applyUDivByPow2 (MachineInstr &MI) {
5363
+ assert (MI.getOpcode () == TargetOpcode::G_UDIV && " Expected SDIV" );
5364
+ auto &UDiv = cast<GenericMachineInstr>(MI);
5365
+ Register Dst = UDiv.getReg (0 );
5366
+ Register LHS = UDiv.getReg (1 );
5367
+ Register RHS = UDiv.getReg (2 );
5368
+ LLT Ty = MRI.getType (Dst);
5369
+ LLT ShiftAmtTy = getTargetLowering ().getPreferredShiftAmountTy (Ty);
5370
+
5371
+ Builder.setInstrAndDebugLoc (MI);
5372
+
5373
+ auto RHSC = getIConstantVRegValWithLookThrough (RHS, MRI);
5374
+ assert (RHSC.has_value () && " RHS must be a constant" );
5375
+ auto RHSCV = RHSC->Value ;
5376
+
5377
+ // Special case: (udiv X, 1) -> X
5378
+ if (RHSCV.isOne ()) {
5379
+ replaceSingleDefInstWithReg (MI, LHS);
5380
+ return ;
5381
+ }
5382
+
5383
+ unsigned TrailingZeros = RHSCV.countTrailingZeros ();
5384
+ auto C1 = Builder.buildConstant (ShiftAmtTy, TrailingZeros);
5385
+ auto Res = Builder.buildLShr (Ty, LHS, C1);
5386
+ replaceSingleDefInstWithReg (MI, Res->getOperand (0 ).getReg ());
5387
+ }
5388
+
5289
5389
bool CombinerHelper::matchUMulHToLShr (MachineInstr &MI) {
5290
5390
assert (MI.getOpcode () == TargetOpcode::G_UMULH);
5291
5391
Register RHS = MI.getOperand (2 ).getReg ();
0 commit comments