@@ -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->hasNoSignedWrap ();
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->setHasNoSignedWrap (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)) {
@@ -1481,6 +1513,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
1481
1513
V = fixupLCSSAFormFor (V);
1482
1514
} else {
1483
1515
for (Instruction *I : DropPoisonGeneratingInsts) {
1516
+ rememberFlags (I);
1484
1517
I->dropPoisonGeneratingFlagsAndMetadata ();
1485
1518
// See if we can re-infer from first principles any of the flags we just
1486
1519
// dropped.
@@ -1521,6 +1554,11 @@ void SCEVExpander::rememberInstruction(Value *I) {
1521
1554
DoInsert (I);
1522
1555
}
1523
1556
1557
+ void SCEVExpander::rememberFlags (Instruction *I) {
1558
+ // If we already have flags for the instruction, keep the existing ones.
1559
+ OrigFlags.try_emplace (I, PoisonFlags (I));
1560
+ }
1561
+
1524
1562
void SCEVExpander::replaceCongruentIVInc (
1525
1563
PHINode *&Phi, PHINode *&OrigPhi, Loop *L, const DominatorTree *DT,
1526
1564
SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
@@ -2318,6 +2356,10 @@ void SCEVExpanderCleaner::cleanup() {
2318
2356
if (ResultUsed)
2319
2357
return ;
2320
2358
2359
+ // Restore original poison flags.
2360
+ for (auto [I, Flags] : Expander.OrigFlags )
2361
+ Flags.apply (I);
2362
+
2321
2363
auto InsertedInstructions = Expander.getAllInsertedInstructions ();
2322
2364
#ifndef NDEBUG
2323
2365
SmallPtrSet<Instruction *, 8 > InsertedSet (InsertedInstructions.begin (),
0 commit comments