@@ -43,6 +43,37 @@ cl::opt<unsigned> llvm::SCEVCheapExpansionBudget(
43
43
44
44
using namespace PatternMatch ;
45
45
46
+ PoisonFlags::PoisonFlags (const Instruction *I) {
47
+ NUW = false ;
48
+ NSW = false ;
49
+ Exact = false ;
50
+ Disjoint = false ;
51
+ NNeg = false ;
52
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I)) {
53
+ NUW = OBO->hasNoUnsignedWrap ();
54
+ NSW = OBO->hasNoUnsignedWrap ();
55
+ }
56
+ if (auto *PEO = dyn_cast<PossiblyExactOperator>(I))
57
+ Exact = PEO->isExact ();
58
+ if (auto *PDI = dyn_cast<PossiblyDisjointInst>(I))
59
+ Disjoint = PDI->isDisjoint ();
60
+ if (auto *PNI = dyn_cast<PossiblyNonNegInst>(I))
61
+ NNeg = PNI->hasNonNeg ();
62
+ }
63
+
64
+ void PoisonFlags::apply (Instruction *I) {
65
+ if (isa<OverflowingBinaryOperator>(I)) {
66
+ I->setHasNoUnsignedWrap (NUW);
67
+ I->setHasNoUnsignedWrap (NSW);
68
+ }
69
+ if (isa<PossiblyExactOperator>(I))
70
+ I->setIsExact (Exact);
71
+ if (auto *PDI = dyn_cast<PossiblyDisjointInst>(I))
72
+ PDI->setIsDisjoint (Disjoint);
73
+ if (auto *PNI = dyn_cast<PossiblyNonNegInst>(I))
74
+ PNI->setNonNeg (NNeg);
75
+ }
76
+
46
77
// / ReuseOrCreateCast - Arrange for there to be a cast of V to Ty at IP,
47
78
// / reusing an existing cast if a suitable one (= dominating IP) exists, or
48
79
// / creating a new one.
@@ -724,6 +755,7 @@ bool SCEVExpander::hoistIVInc(Instruction *IncV, Instruction *InsertPos,
724
755
auto FixupPoisonFlags = [this ](Instruction *I) {
725
756
// Drop flags that are potentially inferred from old context and infer flags
726
757
// in new context.
758
+ rememberFlags (I);
727
759
I->dropPoisonGeneratingFlags ();
728
760
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I))
729
761
if (auto Flags = SE.getStrengthenedNoWrapFlagsFromBinOp (OBO)) {
@@ -1472,6 +1504,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
1472
1504
V = fixupLCSSAFormFor (V);
1473
1505
} else {
1474
1506
for (Instruction *I : DropPoisonGeneratingInsts) {
1507
+ rememberFlags (I);
1475
1508
I->dropPoisonGeneratingFlagsAndMetadata ();
1476
1509
// See if we can re-infer from first principles any of the flags we just
1477
1510
// dropped.
@@ -1512,6 +1545,11 @@ void SCEVExpander::rememberInstruction(Value *I) {
1512
1545
DoInsert (I);
1513
1546
}
1514
1547
1548
+ void SCEVExpander::rememberFlags (Instruction *I) {
1549
+ // If we already have flags for the instruction, keep the existing ones.
1550
+ OrigFlags.try_emplace (I, PoisonFlags (I));
1551
+ }
1552
+
1515
1553
void SCEVExpander::replaceCongruentIVInc (
1516
1554
PHINode *&Phi, PHINode *&OrigPhi, Loop *L, const DominatorTree *DT,
1517
1555
SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
@@ -2309,6 +2347,10 @@ void SCEVExpanderCleaner::cleanup() {
2309
2347
if (ResultUsed)
2310
2348
return ;
2311
2349
2350
+ // Restore original poison flags.
2351
+ for (auto [I, Flags] : Expander.OrigFlags )
2352
+ Flags.apply (I);
2353
+
2312
2354
auto InsertedInstructions = Expander.getAllInsertedInstructions ();
2313
2355
#ifndef NDEBUG
2314
2356
SmallPtrSet<Instruction *, 8 > InsertedSet (InsertedInstructions.begin (),
0 commit comments