@@ -298,39 +298,33 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
298
298
// (X / Y) * Y = X - (X % Y)
299
299
// (X / Y) * -Y = (X % Y) - X
300
300
{
301
- Value *Op1C = Op1;
302
- BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0);
303
- if (!BO ||
304
- (BO->getOpcode () != Instruction::UDiv &&
305
- BO->getOpcode () != Instruction::SDiv)) {
306
- Op1C = Op0;
307
- BO = dyn_cast<BinaryOperator>(Op1);
301
+ Value *Y = Op1;
302
+ BinaryOperator *Div = dyn_cast<BinaryOperator>(Op0);
303
+ if (!Div || (Div->getOpcode () != Instruction::UDiv &&
304
+ Div->getOpcode () != Instruction::SDiv)) {
305
+ Y = Op0;
306
+ Div = dyn_cast<BinaryOperator>(Op1);
308
307
}
309
- Value *Neg = dyn_castNegVal (Op1C );
310
- if (BO && BO ->hasOneUse () &&
311
- (BO ->getOperand (1 ) == Op1C || BO ->getOperand (1 ) == Neg) &&
312
- (BO ->getOpcode () == Instruction::UDiv ||
313
- BO ->getOpcode () == Instruction::SDiv)) {
314
- Value *Op0BO = BO ->getOperand (0 ), *Op1BO = BO ->getOperand (1 );
308
+ Value *Neg = dyn_castNegVal (Y );
309
+ if (Div && Div ->hasOneUse () &&
310
+ (Div ->getOperand (1 ) == Y || Div ->getOperand (1 ) == Neg) &&
311
+ (Div ->getOpcode () == Instruction::UDiv ||
312
+ Div ->getOpcode () == Instruction::SDiv)) {
313
+ Value *X = Div ->getOperand (0 ), *DivOp1 = Div ->getOperand (1 );
315
314
316
315
// If the division is exact, X % Y is zero, so we end up with X or -X.
317
- if (PossiblyExactOperator *SDiv = dyn_cast<PossiblyExactOperator>(BO))
318
- if (SDiv->isExact ()) {
319
- if (Op1BO == Op1C)
320
- return replaceInstUsesWith (I, Op0BO);
321
- return BinaryOperator::CreateNeg (Op0BO);
322
- }
323
-
324
- Value *Rem;
325
- if (BO->getOpcode () == Instruction::UDiv)
326
- Rem = Builder->CreateURem (Op0BO, Op1BO);
327
- else
328
- Rem = Builder->CreateSRem (Op0BO, Op1BO);
329
- Rem->takeName (BO);
316
+ if (Div->isExact ()) {
317
+ if (DivOp1 == Y)
318
+ return replaceInstUsesWith (I, X);
319
+ return BinaryOperator::CreateNeg (X);
320
+ }
330
321
331
- if (Op1BO == Op1C)
332
- return BinaryOperator::CreateSub (Op0BO, Rem);
333
- return BinaryOperator::CreateSub (Rem, Op0BO);
322
+ auto RemOpc = Div->getOpcode () == Instruction::UDiv ? Instruction::URem
323
+ : Instruction::SRem;
324
+ Value *Rem = Builder->CreateBinOp (RemOpc, X, DivOp1);
325
+ if (DivOp1 == Y)
326
+ return BinaryOperator::CreateSub (X, Rem);
327
+ return BinaryOperator::CreateSub (Rem, X);
334
328
}
335
329
}
336
330
0 commit comments