aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-08-20 12:48:06 +0200
committerGitHub <noreply@github.com>2024-08-20 12:48:06 +0200
commitb3fa45b64265d182ba081b2cfdcce454b72280d5 (patch)
treea159667a1060ddc421f633df4c19adb2700d029d /llvm/lib/Transforms/Utils/SimplifyCFG.cpp
parentc99347a9f5f94eba7dff53dffeb94ab390663f8a (diff)
downloadllvm-b3fa45b64265d182ba081b2cfdcce454b72280d5.zip
llvm-b3fa45b64265d182ba081b2cfdcce454b72280d5.tar.gz
llvm-b3fa45b64265d182ba081b2cfdcce454b72280d5.tar.bz2
[SimplifyCFG] Add support for hoisting commutative instructions (#104805)
This extends SimplifyCFG hoisting to also hoist instructions with commuted operands, for example a+b on one side and b+a on the other side. This should address the issue mentioned in: https://github.com/llvm/llvm-project/pull/91185#issuecomment-2097447927
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index ebdf760..00efd3c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1583,6 +1583,26 @@ static void hoistLockstepIdenticalDbgVariableRecords(
}
}
+static bool areIdenticalUpToCommutativity(const Instruction *I1,
+ const Instruction *I2) {
+ if (I1->isIdenticalToWhenDefined(I2))
+ return true;
+
+ if (auto *Cmp1 = dyn_cast<CmpInst>(I1))
+ if (auto *Cmp2 = dyn_cast<CmpInst>(I2))
+ return Cmp1->getPredicate() == Cmp2->getSwappedPredicate() &&
+ Cmp1->getOperand(0) == Cmp2->getOperand(1) &&
+ Cmp1->getOperand(1) == Cmp2->getOperand(0);
+
+ if (I1->isCommutative() && I1->isSameOperationAs(I2)) {
+ return I1->getOperand(0) == I2->getOperand(1) &&
+ I1->getOperand(1) == I2->getOperand(0) &&
+ equal(drop_begin(I1->operands(), 2), drop_begin(I2->operands(), 2));
+ }
+
+ return false;
+}
+
/// Hoist any common code in the successor blocks up into the block. This
/// function guarantees that BB dominates all successors. If EqTermsOnly is
/// given, only perform hoisting in case both blocks only contain a terminator.
@@ -1676,7 +1696,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
for (auto &SuccIter : OtherSuccIterRange) {
Instruction *I2 = &*SuccIter;
HasTerminator |= I2->isTerminator();
- if (AllInstsAreIdentical && (!I1->isIdenticalToWhenDefined(I2) ||
+ if (AllInstsAreIdentical && (!areIdenticalUpToCommutativity(I1, I2) ||
MMRAMetadata(*I1) != MMRAMetadata(*I2)))
AllInstsAreIdentical = false;
}