aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/Reassociate.cpp
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2023-07-03 10:05:40 +0100
committerDavid Green <david.green@arm.com>2023-07-03 10:05:40 +0100
commitdb32d11a386ed20bb44448e671a641cc895d65f8 (patch)
treee7a9a97030241caafc7d8ddc7240d5d8a7d48fa6 /llvm/lib/Transforms/Scalar/Reassociate.cpp
parent273600ccea914b1178df70dfbe8aa28d4ddea835 (diff)
downloadllvm-db32d11a386ed20bb44448e671a641cc895d65f8.zip
llvm-db32d11a386ed20bb44448e671a641cc895d65f8.tar.gz
llvm-db32d11a386ed20bb44448e671a641cc895d65f8.tar.bz2
[Reassociate] Keep flags for more unchanged operations
Reassociation destroys nsw/nuw flags from BinOps that are changed. But if the expression at the end of a tree that was altered, but didn't change itself, the flags do not need to be removed. For example, if %a, %b and %c are reassociated in %x = add nsw i32 %a, %c %y = add nsw i32 %x, %b %z = add nsw i32 %y, %d The value of %y and so add %y %d remains the same, and %z needn't drop the nsw flags. https://alive2.llvm.org/ce/z/_juAiV Differential Revision: https://reviews.llvm.org/D154289
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/Reassociate.cpp61
1 files changed, 39 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index e1d0a2d..40c84e2 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -689,10 +689,12 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I,
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 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I,
}
LLVM_DEBUG(dbgs() << "TO: " << *Op << '\n');
- ExpressionChanged = Op;
+ ExpressionChangedStart = Op;
+ if (!ExpressionChangedEnd)
+ ExpressionChangedEnd = Op;
MadeChange = true;
++NumChanged;
@@ -756,7 +760,9 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I,
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 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I,
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 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I,
// 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<FPMathOperator>(I)) {
- FastMathFlags Flags = I->getFastMathFlags();
- ExpressionChanged->clearSubclassOptionalData();
- ExpressionChanged->setFastMathFlags(Flags);
- } else
- ExpressionChanged->clearSubclassOptionalData();
-
- if (ExpressionChanged == I)
+ if (ClearFlags) {
+ if (isa<FPMathOperator>(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<BinaryOperator>(*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<BinaryOperator>(*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)