diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -689,10 +689,12 @@ for (unsigned i = 0, e = Ops.size(); i != e; ++i) NotRewritable.insert(Ops[i].Op); - // ExpressionChanged - Non-null if the rewritten expression differs from the - // original in some non-trivial way, requiring the clearing of optional flags. - // Flags are cleared from the operator in ExpressionChanged up to I inclusive. - BinaryOperator *ExpressionChanged = nullptr; + // ExpressionChangedStart - Non-null if the rewritten expression differs from + // the original in some non-trivial way, requiring the clearing of optional + // flags. Flags are cleared from the operator in ExpressionChangedStart up to + // ExpressionChangedEnd inclusive. + BinaryOperator *ExpressionChangedStart = nullptr, + *ExpressionChangedEnd = nullptr; for (unsigned i = 0; ; ++i) { // The last operation (which comes earliest in the IR) is special as both // operands will come from Ops, rather than just one with the other being @@ -734,7 +736,9 @@ } LLVM_DEBUG(dbgs() << "TO: " << *Op << '\n'); - ExpressionChanged = Op; + ExpressionChangedStart = Op; + if (!ExpressionChangedEnd) + ExpressionChangedEnd = Op; MadeChange = true; ++NumChanged; @@ -756,7 +760,9 @@ if (BO && !NotRewritable.count(BO)) NodesToRewrite.push_back(BO); Op->setOperand(1, NewRHS); - ExpressionChanged = Op; + ExpressionChangedStart = Op; + if (!ExpressionChangedEnd) + ExpressionChangedEnd = Op; } LLVM_DEBUG(dbgs() << "TO: " << *Op << '\n'); MadeChange = true; @@ -793,7 +799,9 @@ LLVM_DEBUG(dbgs() << "RA: " << *Op << '\n'); Op->setOperand(0, NewOp); LLVM_DEBUG(dbgs() << "TO: " << *Op << '\n'); - ExpressionChanged = Op; + ExpressionChangedStart = Op; + if (!ExpressionChangedEnd) + ExpressionChangedEnd = Op; MadeChange = true; ++NumChanged; Op = NewOp; @@ -803,27 +811,36 @@ // starting from the operator specified in ExpressionChanged, and compactify // the operators to just before the expression root to guarantee that the // expression tree is dominated by all of Ops. - if (ExpressionChanged) + if (ExpressionChangedStart) { + bool ClearFlags = true; do { // Preserve FastMathFlags. - if (isa(I)) { - FastMathFlags Flags = I->getFastMathFlags(); - ExpressionChanged->clearSubclassOptionalData(); - ExpressionChanged->setFastMathFlags(Flags); - } else - ExpressionChanged->clearSubclassOptionalData(); - - if (ExpressionChanged == I) + if (ClearFlags) { + if (isa(I)) { + FastMathFlags Flags = I->getFastMathFlags(); + ExpressionChangedStart->clearSubclassOptionalData(); + ExpressionChangedStart->setFastMathFlags(Flags); + } else + ExpressionChangedStart->clearSubclassOptionalData(); + } + + if (ExpressionChangedStart == ExpressionChangedEnd) + ClearFlags = false; + if (ExpressionChangedStart == I) break; // Discard any debug info related to the expressions that has changed (we - // can leave debug infor related to the root, since the result of the - // expression tree should be the same even after reassociation). - replaceDbgUsesWithUndef(ExpressionChanged); - - ExpressionChanged->moveBefore(I); - ExpressionChanged = cast(*ExpressionChanged->user_begin()); + // can leave debug info related to the root and any operation that didn't + // change, since the result of the expression tree should be the same + // even after reassociation). + if (ClearFlags) + replaceDbgUsesWithUndef(ExpressionChangedStart); + + ExpressionChangedStart->moveBefore(I); + ExpressionChangedStart = + cast(*ExpressionChangedStart->user_begin()); } while (true); + } // Throw away any left over nodes from the original expression. for (unsigned i = 0, e = NodesToRewrite.size(); i != e; ++i) diff --git a/llvm/test/Transforms/Reassociate/cse-pairs.ll b/llvm/test/Transforms/Reassociate/cse-pairs.ll --- a/llvm/test/Transforms/Reassociate/cse-pairs.ll +++ b/llvm/test/Transforms/Reassociate/cse-pairs.ll @@ -34,7 +34,7 @@ ; CHECK-LABEL: @twoPairsAllOpInPairs( ; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP2:%.*]], [[TMP1:%.*]] ; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], [[TMP0:%.*]] -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3:%.*]] +; CHECK-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP6]], [[TMP3:%.*]] ; CHECK-NEXT: store i32 [[TMP7]], ptr @num1, align 4 ; CHECK-NEXT: store i32 [[TMP5]], ptr @num2, align 4 ; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP3]], [[TMP0]] @@ -57,8 +57,8 @@ ; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP3:%.*]], [[TMP2:%.*]] ; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[TMP7]], [[TMP0:%.*]] ; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[TMP8]], [[TMP1:%.*]] -; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[TMP9]], [[TMP4:%.*]] -; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP10]], [[TMP5:%.*]] +; CHECK-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], [[TMP4:%.*]] +; CHECK-NEXT: [[TMP11:%.*]] = add nsw i32 [[TMP10]], [[TMP5:%.*]] ; CHECK-NEXT: store i32 [[TMP11]], ptr @num1, align 4 ; CHECK-NEXT: [[TMP12:%.*]] = add nsw i32 [[TMP5]], [[TMP0]] ; CHECK-NEXT: store i32 [[TMP12]], ptr @num2, align 4 diff --git a/llvm/test/Transforms/Reassociate/local-cse.ll b/llvm/test/Transforms/Reassociate/local-cse.ll --- a/llvm/test/Transforms/Reassociate/local-cse.ll +++ b/llvm/test/Transforms/Reassociate/local-cse.ll @@ -49,7 +49,7 @@ ; CSE-NEXT: [[VAL_BB2:%.*]] = call i64 @get_val() ; CSE-NEXT: [[CHAIN_A0:%.*]] = add i64 [[VAL_BB2]], [[INV1]] ; CSE-NEXT: [[CHAIN_A1:%.*]] = add i64 [[CHAIN_A0]], [[INV2]] -; CSE-NEXT: [[CHAIN_A2:%.*]] = add i64 [[CHAIN_A1]], [[INV4]] +; CSE-NEXT: [[CHAIN_A2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV4]] ; CSE-NEXT: [[CHAIN_B2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV5]] ; CSE-NEXT: [[CHAIN_C1:%.*]] = add i64 [[CHAIN_A0]], [[INV3]] ; CSE-NEXT: call void @keep_alive(i64 [[CHAIN_A2]]) @@ -122,7 +122,7 @@ ; CSE-NEXT: [[VAL_BB2:%.*]] = call i64 @get_val() ; CSE-NEXT: [[CHAIN_A0:%.*]] = add i64 [[VAL_BB2]], [[INV1_BB1]] ; CSE-NEXT: [[CHAIN_A1:%.*]] = add i64 [[CHAIN_A0]], [[INV2_BB0]] -; CSE-NEXT: [[CHAIN_A2:%.*]] = add i64 [[CHAIN_A1]], [[INV4_BB2]] +; CSE-NEXT: [[CHAIN_A2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV4_BB2]] ; CSE-NEXT: [[CHAIN_B2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV5_BB2]] ; CSE-NEXT: [[CHAIN_C1:%.*]] = add i64 [[CHAIN_A0]], [[INV3_BB2]] ; CSE-NEXT: call void @keep_alive(i64 [[CHAIN_A2]])