@@ -64,20 +64,6 @@ static cl::opt<bool> DumpReproducers(
64
64
static int64_t MaxConstraintValue = std::numeric_limits<int64_t >::max();
65
65
static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t >::min();
66
66
67
- // A helper to multiply 2 signed integers where overflowing is allowed.
68
- static int64_t multiplyWithOverflow (int64_t A, int64_t B) {
69
- int64_t Result;
70
- MulOverflow (A, B, Result);
71
- return Result;
72
- }
73
-
74
- // A helper to add 2 signed integers where overflowing is allowed.
75
- static int64_t addWithOverflow (int64_t A, int64_t B) {
76
- int64_t Result;
77
- AddOverflow (A, B, Result);
78
- return Result;
79
- }
80
-
81
67
static Instruction *getContextInstForUse (Use &U) {
82
68
Instruction *UserI = cast<Instruction>(U.getUser ());
83
69
if (auto *Phi = dyn_cast<PHINode>(UserI))
@@ -366,26 +352,42 @@ struct Decomposition {
366
352
Decomposition (int64_t Offset, ArrayRef<DecompEntry> Vars)
367
353
: Offset(Offset), Vars(Vars) {}
368
354
369
- void add (int64_t OtherOffset) {
370
- Offset = addWithOverflow (Offset, OtherOffset);
355
+ // / Add \p OtherOffset and return true if the operation overflows, i.e. the
356
+ // / new decomposition is invalid.
357
+ [[nodiscard]] bool add (int64_t OtherOffset) {
358
+ return AddOverflow (Offset, OtherOffset, Offset);
371
359
}
372
360
373
- void add (const Decomposition &Other) {
374
- add (Other.Offset );
361
+ // / Add \p Other and return true if the operation overflows, i.e. the new
362
+ // / decomposition is invalid.
363
+ [[nodiscard]] bool add (const Decomposition &Other) {
364
+ if (add (Other.Offset ))
365
+ return true ;
375
366
append_range (Vars, Other.Vars );
367
+ return false ;
376
368
}
377
369
378
- void sub (const Decomposition &Other) {
370
+ // / Subtract \p Other and return true if the operation overflows, i.e. the new
371
+ // / decomposition is invalid.
372
+ [[nodiscard]] bool sub (const Decomposition &Other) {
379
373
Decomposition Tmp = Other;
380
- Tmp.mul (-1 );
381
- add (Tmp.Offset );
374
+ if (Tmp.mul (-1 ))
375
+ return true ;
376
+ if (add (Tmp.Offset ))
377
+ return true ;
382
378
append_range (Vars, Tmp.Vars );
379
+ return false ;
383
380
}
384
381
385
- void mul (int64_t Factor) {
386
- Offset = multiplyWithOverflow (Offset, Factor);
382
+ // / Multiply all coefficients by \p Factor and return true if the operation
383
+ // / overflows, i.e. the new decomposition is invalid.
384
+ [[nodiscard]] bool mul (int64_t Factor) {
385
+ if (MulOverflow (Offset, Factor, Offset))
386
+ return true ;
387
387
for (auto &Var : Vars)
388
- Var.Coefficient = multiplyWithOverflow (Var.Coefficient , Factor);
388
+ if (MulOverflow (Var.Coefficient , Factor, Var.Coefficient ))
389
+ return true ;
390
+ return false ;
389
391
}
390
392
};
391
393
@@ -467,8 +469,10 @@ static Decomposition decomposeGEP(GEPOperator &GEP,
467
469
Decomposition Result (ConstantOffset.getSExtValue (), DecompEntry (1 , BasePtr));
468
470
for (auto [Index, Scale] : VariableOffsets) {
469
471
auto IdxResult = decompose (Index, Preconditions, IsSigned, DL);
470
- IdxResult.mul (Scale.getSExtValue ());
471
- Result.add (IdxResult);
472
+ if (IdxResult.mul (Scale.getSExtValue ()))
473
+ return &GEP;
474
+ if (Result.add (IdxResult))
475
+ return &GEP;
472
476
473
477
if (!NW.hasNoUnsignedWrap ()) {
474
478
// Try to prove nuw from nusw and nneg.
@@ -488,11 +492,13 @@ static Decomposition decompose(Value *V,
488
492
SmallVectorImpl<ConditionTy> &Preconditions,
489
493
bool IsSigned, const DataLayout &DL) {
490
494
491
- auto MergeResults = [&Preconditions, IsSigned, &DL](Value *A, Value *B,
492
- bool IsSignedB) {
495
+ auto MergeResults = [&Preconditions, IsSigned,
496
+ &DL](Value *A, Value *B,
497
+ bool IsSignedB) -> std::optional<Decomposition> {
493
498
auto ResA = decompose (A, Preconditions, IsSigned, DL);
494
499
auto ResB = decompose (B, Preconditions, IsSignedB, DL);
495
- ResA.add (ResB);
500
+ if (ResA.add (ResB))
501
+ return std::nullopt;
496
502
return ResA;
497
503
};
498
504
@@ -533,21 +539,26 @@ static Decomposition decompose(Value *V,
533
539
V = Op0;
534
540
}
535
541
536
- if (match (V, m_NSWAdd (m_Value (Op0), m_Value (Op1))))
537
- return MergeResults (Op0, Op1, IsSigned);
542
+ if (match (V, m_NSWAdd (m_Value (Op0), m_Value (Op1)))) {
543
+ if (auto Decomp = MergeResults (Op0, Op1, IsSigned))
544
+ return *Decomp;
545
+ return {V, IsKnownNonNegative};
546
+ }
538
547
539
548
if (match (V, m_NSWSub (m_Value (Op0), m_Value (Op1)))) {
540
549
auto ResA = decompose (Op0, Preconditions, IsSigned, DL);
541
550
auto ResB = decompose (Op1, Preconditions, IsSigned, DL);
542
- ResA.sub (ResB);
543
- return ResA;
551
+ if (!ResA.sub (ResB))
552
+ return ResA;
553
+ return {V, IsKnownNonNegative};
544
554
}
545
555
546
556
ConstantInt *CI;
547
557
if (match (V, m_NSWMul (m_Value (Op0), m_ConstantInt (CI))) && canUseSExt (CI)) {
548
558
auto Result = decompose (Op0, Preconditions, IsSigned, DL);
549
- Result.mul (CI->getSExtValue ());
550
- return Result;
559
+ if (!Result.mul (CI->getSExtValue ()))
560
+ return Result;
561
+ return {V, IsKnownNonNegative};
551
562
}
552
563
553
564
// (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of
@@ -557,8 +568,9 @@ static Decomposition decompose(Value *V,
557
568
if (Shift < Ty->getIntegerBitWidth () - 1 ) {
558
569
assert (Shift < 64 && " Would overflow" );
559
570
auto Result = decompose (Op0, Preconditions, IsSigned, DL);
560
- Result.mul (int64_t (1 ) << Shift);
561
- return Result;
571
+ if (!Result.mul (int64_t (1 ) << Shift))
572
+ return Result;
573
+ return {V, IsKnownNonNegative};
562
574
}
563
575
}
564
576
@@ -593,8 +605,11 @@ static Decomposition decompose(Value *V,
593
605
Value *Op1;
594
606
ConstantInt *CI;
595
607
if (match (V, m_NUWAdd (m_Value (Op0), m_Value (Op1)))) {
596
- return MergeResults (Op0, Op1, IsSigned);
608
+ if (auto Decomp = MergeResults (Op0, Op1, IsSigned))
609
+ return *Decomp;
610
+ return {V, IsKnownNonNegative};
597
611
}
612
+
598
613
if (match (V, m_NSWAdd (m_Value (Op0), m_Value (Op1)))) {
599
614
if (!isKnownNonNegative (Op0, DL))
600
615
Preconditions.emplace_back (CmpInst::ICMP_SGE, Op0,
@@ -603,41 +618,51 @@ static Decomposition decompose(Value *V,
603
618
Preconditions.emplace_back (CmpInst::ICMP_SGE, Op1,
604
619
ConstantInt::get (Op1->getType (), 0 ));
605
620
606
- return MergeResults (Op0, Op1, IsSigned);
621
+ if (auto Decomp = MergeResults (Op0, Op1, IsSigned))
622
+ return *Decomp;
623
+ return {V, IsKnownNonNegative};
607
624
}
608
625
609
626
if (match (V, m_Add (m_Value (Op0), m_ConstantInt (CI))) && CI->isNegative () &&
610
627
canUseSExt (CI)) {
611
628
Preconditions.emplace_back (
612
629
CmpInst::ICMP_UGE, Op0,
613
630
ConstantInt::get (Op0->getType (), CI->getSExtValue () * -1 ));
614
- return MergeResults (Op0, CI, true );
631
+ if (auto Decomp = MergeResults (Op0, CI, true ))
632
+ return *Decomp;
633
+ return {V, IsKnownNonNegative};
615
634
}
616
635
617
636
// Decompose or as an add if there are no common bits between the operands.
618
- if (match (V, m_DisjointOr (m_Value (Op0), m_ConstantInt (CI))))
619
- return MergeResults (Op0, CI, IsSigned);
637
+ if (match (V, m_DisjointOr (m_Value (Op0), m_ConstantInt (CI)))) {
638
+ if (auto Decomp = MergeResults (Op0, CI, IsSigned))
639
+ return *Decomp;
640
+ return {V, IsKnownNonNegative};
641
+ }
620
642
621
643
if (match (V, m_NUWShl (m_Value (Op1), m_ConstantInt (CI))) && canUseSExt (CI)) {
622
644
if (CI->getSExtValue () < 0 || CI->getSExtValue () >= 64 )
623
645
return {V, IsKnownNonNegative};
624
646
auto Result = decompose (Op1, Preconditions, IsSigned, DL);
625
- Result.mul (int64_t {1 } << CI->getSExtValue ());
626
- return Result;
647
+ if (!Result.mul (int64_t {1 } << CI->getSExtValue ()))
648
+ return Result;
649
+ return {V, IsKnownNonNegative};
627
650
}
628
651
629
652
if (match (V, m_NUWMul (m_Value (Op1), m_ConstantInt (CI))) && canUseSExt (CI) &&
630
653
(!CI->isNegative ())) {
631
654
auto Result = decompose (Op1, Preconditions, IsSigned, DL);
632
- Result.mul (CI->getSExtValue ());
633
- return Result;
655
+ if (!Result.mul (CI->getSExtValue ()))
656
+ return Result;
657
+ return {V, IsKnownNonNegative};
634
658
}
635
659
636
660
if (match (V, m_NUWSub (m_Value (Op0), m_Value (Op1)))) {
637
661
auto ResA = decompose (Op0, Preconditions, IsSigned, DL);
638
662
auto ResB = decompose (Op1, Preconditions, IsSigned, DL);
639
- ResA.sub (ResB);
640
- return ResA;
663
+ if (!ResA.sub (ResB))
664
+ return ResA;
665
+ return {V, IsKnownNonNegative};
641
666
}
642
667
643
668
return {V, IsKnownNonNegative};
0 commit comments