diff options
author | Nikita Popov <npopov@redhat.com> | 2024-08-20 12:48:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-20 12:48:06 +0200 |
commit | b3fa45b64265d182ba081b2cfdcce454b72280d5 (patch) | |
tree | a159667a1060ddc421f633df4c19adb2700d029d /llvm/lib/Transforms/Utils/SimplifyCFG.cpp | |
parent | c99347a9f5f94eba7dff53dffeb94ab390663f8a (diff) | |
download | llvm-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.cpp | 22 |
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; } |