@@ -471,7 +471,7 @@ using RepeatedValue = std::pair<Value*, APInt>;
471471static bool LinearizeExprTree (Instruction *I,
472472 SmallVectorImpl<RepeatedValue> &Ops,
473473 ReassociatePass::OrderedSet &ToRedo,
474- bool &HasNUW ) {
474+ reassociate::OverflowTracking &Flags ) {
475475 assert ((isa<UnaryOperator>(I) || isa<BinaryOperator>(I)) &&
476476 " Expected a UnaryOperator or BinaryOperator!" );
477477 LLVM_DEBUG (dbgs () << " LINEARIZE: " << *I << ' \n ' );
@@ -512,6 +512,7 @@ static bool LinearizeExprTree(Instruction *I,
512512 using LeafMap = DenseMap<Value *, APInt>;
513513 LeafMap Leaves; // Leaf -> Total weight so far.
514514 SmallVector<Value *, 8 > LeafOrder; // Ensure deterministic leaf output order.
515+ const DataLayout DL = I->getModule ()->getDataLayout ();
515516
516517#ifndef NDEBUG
517518 SmallPtrSet<Value *, 8 > Visited; // For checking the iteration scheme.
@@ -520,8 +521,10 @@ static bool LinearizeExprTree(Instruction *I,
520521 std::pair<Instruction*, APInt> P = Worklist.pop_back_val ();
521522 I = P.first ; // We examine the operands of this binary operator.
522523
523- if (isa<OverflowingBinaryOperator>(I))
524- HasNUW &= I->hasNoUnsignedWrap ();
524+ if (isa<OverflowingBinaryOperator>(I)) {
525+ Flags.HasNUW &= I->hasNoUnsignedWrap ();
526+ Flags.HasNSW &= I->hasNoSignedWrap ();
527+ }
525528
526529 for (unsigned OpIdx = 0 ; OpIdx < I->getNumOperands (); ++OpIdx) { // Visit operands.
527530 Value *Op = I->getOperand (OpIdx);
@@ -648,6 +651,8 @@ static bool LinearizeExprTree(Instruction *I,
648651 // Ensure the leaf is only output once.
649652 It->second = 0 ;
650653 Ops.push_back (std::make_pair (V, Weight));
654+ if (Opcode == Instruction::Add && Flags.AllKnownNonNegative && Flags.HasNSW )
655+ Flags.AllKnownNonNegative &= isKnownNonNegative (V, SimplifyQuery (DL));
651656 }
652657
653658 // For nilpotent operations or addition there may be no operands, for example
@@ -666,7 +671,7 @@ static bool LinearizeExprTree(Instruction *I,
666671// / linearized and optimized, emit them in-order.
667672void ReassociatePass::RewriteExprTree (BinaryOperator *I,
668673 SmallVectorImpl<ValueEntry> &Ops,
669- bool HasNUW ) {
674+ OverflowTracking Flags ) {
670675 assert (Ops.size () > 1 && " Single values should be used directly!" );
671676
672677 // Since our optimizations should never increase the number of operations, the
@@ -834,8 +839,12 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I,
834839 // Note that it doesn't hold for mul if one of the operands is zero.
835840 // TODO: We can preserve NUW flag if we prove that all mul operands
836841 // are non-zero.
837- if (HasNUW && ExpressionChangedStart->getOpcode () == Instruction::Add)
838- ExpressionChangedStart->setHasNoUnsignedWrap ();
842+ if (ExpressionChangedStart->getOpcode () == Instruction::Add) {
843+ if (Flags.HasNUW )
844+ ExpressionChangedStart->setHasNoUnsignedWrap ();
845+ if (Flags.HasNSW && (Flags.AllKnownNonNegative || Flags.HasNUW ))
846+ ExpressionChangedStart->setHasNoSignedWrap ();
847+ }
839848 }
840849 }
841850
@@ -1192,8 +1201,8 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) {
11921201 return nullptr ;
11931202
11941203 SmallVector<RepeatedValue, 8 > Tree;
1195- bool HasNUW = true ;
1196- MadeChange |= LinearizeExprTree (BO, Tree, RedoInsts, HasNUW );
1204+ OverflowTracking Flags ;
1205+ MadeChange |= LinearizeExprTree (BO, Tree, RedoInsts, Flags );
11971206 SmallVector<ValueEntry, 8 > Factors;
11981207 Factors.reserve (Tree.size ());
11991208 for (unsigned i = 0 , e = Tree.size (); i != e; ++i) {
@@ -1235,7 +1244,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) {
12351244
12361245 if (!FoundFactor) {
12371246 // Make sure to restore the operands to the expression tree.
1238- RewriteExprTree (BO, Factors, HasNUW );
1247+ RewriteExprTree (BO, Factors, Flags );
12391248 return nullptr ;
12401249 }
12411250
@@ -1247,7 +1256,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) {
12471256 RedoInsts.insert (BO);
12481257 V = Factors[0 ].Op ;
12491258 } else {
1250- RewriteExprTree (BO, Factors, HasNUW );
1259+ RewriteExprTree (BO, Factors, Flags );
12511260 V = BO;
12521261 }
12531262
@@ -2373,8 +2382,8 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) {
23732382 // First, walk the expression tree, linearizing the tree, collecting the
23742383 // operand information.
23752384 SmallVector<RepeatedValue, 8 > Tree;
2376- bool HasNUW = true ;
2377- MadeChange |= LinearizeExprTree (I, Tree, RedoInsts, HasNUW );
2385+ OverflowTracking Flags ;
2386+ MadeChange |= LinearizeExprTree (I, Tree, RedoInsts, Flags );
23782387 SmallVector<ValueEntry, 8 > Ops;
23792388 Ops.reserve (Tree.size ());
23802389 for (const RepeatedValue &E : Tree)
@@ -2567,7 +2576,7 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) {
25672576 dbgs () << ' \n ' );
25682577 // Now that we ordered and optimized the expressions, splat them back into
25692578 // the expression tree, removing any unneeded nodes.
2570- RewriteExprTree (I, Ops, HasNUW );
2579+ RewriteExprTree (I, Ops, Flags );
25712580}
25722581
25732582void
0 commit comments