@@ -287,6 +287,79 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
287
287
return BO;
288
288
}
289
289
290
+ // / FactorOutConstant - Test if S is divisible by Factor, using signed
291
+ // / division. If so, update S with Factor divided out and return true.
292
+ // / S need not be evenly divisible if a reasonable remainder can be
293
+ // / computed.
294
+ static bool FactorOutConstant (const SCEV *&S, const SCEV *&Remainder,
295
+ const SCEV *Factor, ScalarEvolution &SE,
296
+ const DataLayout &DL) {
297
+ // Everything is divisible by one.
298
+ if (Factor->isOne ())
299
+ return true ;
300
+
301
+ // x/x == 1.
302
+ if (S == Factor) {
303
+ S = SE.getConstant (S->getType (), 1 );
304
+ return true ;
305
+ }
306
+
307
+ // For a Constant, check for a multiple of the given factor.
308
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
309
+ // 0/x == 0.
310
+ if (C->isZero ())
311
+ return true ;
312
+ // Check for divisibility.
313
+ if (const SCEVConstant *FC = dyn_cast<SCEVConstant>(Factor)) {
314
+ ConstantInt *CI =
315
+ ConstantInt::get (SE.getContext (), C->getAPInt ().sdiv (FC->getAPInt ()));
316
+ // If the quotient is zero and the remainder is non-zero, reject
317
+ // the value at this scale. It will be considered for subsequent
318
+ // smaller scales.
319
+ if (!CI->isZero ()) {
320
+ const SCEV *Div = SE.getConstant (CI);
321
+ S = Div;
322
+ Remainder = SE.getAddExpr (
323
+ Remainder, SE.getConstant (C->getAPInt ().srem (FC->getAPInt ())));
324
+ return true ;
325
+ }
326
+ }
327
+ }
328
+
329
+ // In a Mul, check if there is a constant operand which is a multiple
330
+ // of the given factor.
331
+ if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S)) {
332
+ // Size is known, check if there is a constant operand which is a multiple
333
+ // of the given factor. If so, we can factor it.
334
+ if (const SCEVConstant *FC = dyn_cast<SCEVConstant>(Factor))
335
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand (0 )))
336
+ if (!C->getAPInt ().srem (FC->getAPInt ())) {
337
+ SmallVector<const SCEV *, 4 > NewMulOps (M->operands ());
338
+ NewMulOps[0 ] = SE.getConstant (C->getAPInt ().sdiv (FC->getAPInt ()));
339
+ S = SE.getMulExpr (NewMulOps);
340
+ return true ;
341
+ }
342
+ }
343
+
344
+ // In an AddRec, check if both start and step are divisible.
345
+ if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(S)) {
346
+ const SCEV *Step = A->getStepRecurrence (SE);
347
+ const SCEV *StepRem = SE.getConstant (Step->getType (), 0 );
348
+ if (!FactorOutConstant (Step, StepRem, Factor, SE, DL))
349
+ return false ;
350
+ if (!StepRem->isZero ())
351
+ return false ;
352
+ const SCEV *Start = A->getStart ();
353
+ if (!FactorOutConstant (Start, Remainder, Factor, SE, DL))
354
+ return false ;
355
+ S = SE.getAddRecExpr (Start, Step, A->getLoop (),
356
+ A->getNoWrapFlags (SCEV::FlagNW));
357
+ return true ;
358
+ }
359
+
360
+ return false ;
361
+ }
362
+
290
363
// / SimplifyAddOperands - Sort and simplify a list of add operands. NumAddRecs
291
364
// / is the number of SCEVAddRecExprs present, which are kept at the end of
292
365
// / the list.
0 commit comments