@@ -375,24 +375,28 @@ struct LinearExpression {
375
375
APInt Scale;
376
376
APInt Offset;
377
377
378
+ // / True if all operations in this expression are NUW.
379
+ bool IsNUW;
378
380
// / True if all operations in this expression are NSW.
379
381
bool IsNSW;
380
382
381
383
LinearExpression (const CastedValue &Val, const APInt &Scale,
382
- const APInt &Offset, bool IsNSW)
383
- : Val(Val), Scale(Scale), Offset(Offset), IsNSW(IsNSW) {}
384
+ const APInt &Offset, bool IsNUW, bool IsNSW)
385
+ : Val(Val), Scale(Scale), Offset(Offset), IsNUW(IsNUW), IsNSW(IsNSW) {}
384
386
385
- LinearExpression (const CastedValue &Val) : Val(Val), IsNSW(true ) {
387
+ LinearExpression (const CastedValue &Val)
388
+ : Val(Val), IsNUW(true ), IsNSW(true ) {
386
389
unsigned BitWidth = Val.getBitWidth ();
387
390
Scale = APInt (BitWidth, 1 );
388
391
Offset = APInt (BitWidth, 0 );
389
392
}
390
393
391
- LinearExpression mul (const APInt &Other, bool MulIsNSW) const {
394
+ LinearExpression mul (const APInt &Other, bool MulIsNUW, bool MulIsNSW) const {
392
395
// The check for zero offset is necessary, because generally
393
396
// (X +nsw Y) *nsw Z does not imply (X *nsw Z) +nsw (Y *nsw Z).
394
397
bool NSW = IsNSW && (Other.isOne () || (MulIsNSW && Offset.isZero ()));
395
- return LinearExpression (Val, Scale * Other, Offset * Other, NSW);
398
+ bool NUW = IsNUW && (Other.isOne () || MulIsNUW);
399
+ return LinearExpression (Val, Scale * Other, Offset * Other, NUW, NSW);
396
400
}
397
401
};
398
402
}
@@ -408,7 +412,7 @@ static LinearExpression GetLinearExpression(
408
412
409
413
if (const ConstantInt *Const = dyn_cast<ConstantInt>(Val.V ))
410
414
return LinearExpression (Val, APInt (Val.getBitWidth (), 0 ),
411
- Val.evaluateWith (Const->getValue ()), true );
415
+ Val.evaluateWith (Const->getValue ()), true , true );
412
416
413
417
if (const BinaryOperator *BOp = dyn_cast<BinaryOperator>(Val.V )) {
414
418
if (ConstantInt *RHSC = dyn_cast<ConstantInt>(BOp->getOperand (1 ))) {
@@ -444,20 +448,22 @@ static LinearExpression GetLinearExpression(
444
448
E = GetLinearExpression (Val.withValue (BOp->getOperand (0 ), false ), DL,
445
449
Depth + 1 , AC, DT);
446
450
E.Offset += RHS;
451
+ E.IsNUW &= NUW;
447
452
E.IsNSW &= NSW;
448
453
break ;
449
454
}
450
455
case Instruction::Sub: {
451
456
E = GetLinearExpression (Val.withValue (BOp->getOperand (0 ), false ), DL,
452
457
Depth + 1 , AC, DT);
453
458
E.Offset -= RHS;
459
+ E.IsNUW = false ; // sub nuw x, y is not add nuw x, -y.
454
460
E.IsNSW &= NSW;
455
461
break ;
456
462
}
457
463
case Instruction::Mul:
458
464
E = GetLinearExpression (Val.withValue (BOp->getOperand (0 ), false ), DL,
459
465
Depth + 1 , AC, DT)
460
- .mul (RHS, NSW);
466
+ .mul (RHS, NUW, NSW);
461
467
break ;
462
468
case Instruction::Shl:
463
469
// We're trying to linearize an expression of the kind:
@@ -472,6 +478,7 @@ static LinearExpression GetLinearExpression(
472
478
Depth + 1 , AC, DT);
473
479
E.Offset <<= RHS.getLimitedValue ();
474
480
E.Scale <<= RHS.getLimitedValue ();
481
+ E.IsNUW &= NUW;
475
482
E.IsNSW &= NSW;
476
483
break ;
477
484
}
@@ -697,7 +704,8 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
697
704
// If the integer type is smaller than the index size, it is implicitly
698
705
// sign extended or truncated to index size.
699
706
bool NUSW = GEPOp->hasNoUnsignedSignedWrap ();
700
- bool NonNeg = NUSW && GEPOp->hasNoUnsignedWrap ();
707
+ bool NUW = GEPOp->hasNoUnsignedWrap ();
708
+ bool NonNeg = NUSW && NUW;
701
709
unsigned Width = Index->getType ()->getIntegerBitWidth ();
702
710
unsigned SExtBits = IndexSize > Width ? IndexSize - Width : 0 ;
703
711
unsigned TruncBits = IndexSize < Width ? Width - IndexSize : 0 ;
@@ -706,9 +714,11 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
706
714
707
715
// Scale by the type size.
708
716
unsigned TypeSize = AllocTypeSize.getFixedValue ();
709
- LE = LE.mul (APInt (IndexSize, TypeSize), NUSW);
717
+ LE = LE.mul (APInt (IndexSize, TypeSize), NUW, NUSW);
710
718
Decomposed.Offset += LE.Offset .sext (MaxIndexSize);
711
719
APInt Scale = LE.Scale .sext (MaxIndexSize);
720
+ if (!LE.IsNUW )
721
+ Decomposed.NWFlags = Decomposed.NWFlags .withoutNoUnsignedWrap ();
712
722
713
723
// If we already had an occurrence of this index variable, merge this
714
724
// scale into it. For example, we want to handle:
@@ -719,7 +729,8 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
719
729
areBothVScale (Decomposed.VarIndices [i].Val .V , LE.Val .V )) &&
720
730
Decomposed.VarIndices [i].Val .hasSameCastsAs (LE.Val )) {
721
731
Scale += Decomposed.VarIndices [i].Scale ;
722
- LE.IsNSW = false ; // We cannot guarantee nsw for the merge.
732
+ // We cannot guarantee no-wrap for the merge.
733
+ LE.IsNSW = LE.IsNUW = false ;
723
734
Decomposed.VarIndices .erase (Decomposed.VarIndices .begin () + i);
724
735
break ;
725
736
}
0 commit comments