diff options
author | Chris Lattner <sabre@nondot.org> | 2002-05-14 19:57:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-05-14 19:57:25 +0000 |
commit | 0f9fd5b0f820c57c88ea103ddeec44efbfd3345d (patch) | |
tree | 6f1abc1c4d44ae337323719bfc0634a6cf63c809 /lib/Transforms/Scalar/GCSE.cpp | |
parent | f54d0dea8faa11fbae4cf7d6505414564f4ddfa9 (diff) | |
download | external_llvm-0f9fd5b0f820c57c88ea103ddeec44efbfd3345d.zip external_llvm-0f9fd5b0f820c57c88ea103ddeec44efbfd3345d.tar.gz external_llvm-0f9fd5b0f820c57c88ea103ddeec44efbfd3345d.tar.bz2 |
* Fix bug: test/Regression/Transforms/GCSE/2002-05-14-OperandSwap.ll
By making sure to consider binary expressions identical if their operands
are backwards, but swappable.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2629 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/GCSE.cpp')
-rw-r--r-- | lib/Transforms/Scalar/GCSE.cpp | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/lib/Transforms/Scalar/GCSE.cpp b/lib/Transforms/Scalar/GCSE.cpp index d9f5f3a..2792550 100644 --- a/lib/Transforms/Scalar/GCSE.cpp +++ b/lib/Transforms/Scalar/GCSE.cpp @@ -256,6 +256,37 @@ bool GCSE::visitUnaryOperator(Instruction *I) { return false; } +// isIdenticalBinaryInst - Return true if the two binary instructions are +// identical. +// +static inline bool isIdenticalBinaryInst(const Instruction *I1, + const Instruction *I2) { + // Is it embeded in the same function? (This could be false if LHS + // is a constant or global!) + if (I1->getOpcode() != I2->getOpcode() || + I1->getParent()->getParent() != I2->getParent()->getParent()) + return false; + + // They are identical if both operands are the same! + if (I1->getOperand(0) == I2->getOperand(0) && + I1->getOperand(1) == I2->getOperand(1)) + return true; + + // If the instruction is commutative and associative, the instruction can + // match if the operands are swapped! + // + if ((I1->getOperand(0) == I2->getOperand(1) && + I1->getOperand(1) == I2->getOperand(0)) && + (I1->getOpcode() == Instruction::Add || + I1->getOpcode() == Instruction::Mul || + I1->getOpcode() == Instruction::And || + I1->getOpcode() == Instruction::Or || + I1->getOpcode() == Instruction::Xor)) + return true; + + return false; +} + bool GCSE::visitBinaryOperator(Instruction *I) { Value *LHS = I->getOperand(0), *RHS = I->getOperand(1); Function *F = I->getParent()->getParent(); @@ -264,13 +295,7 @@ bool GCSE::visitBinaryOperator(Instruction *I) { UI != UE; ++UI) if (Instruction *Other = dyn_cast<Instruction>(*UI)) // Check to see if this new binary operator is not I, but same operand... - if (Other != I && Other->getOpcode() == I->getOpcode() && - // Are the LHS and RHS the same? - Other->getOperand(0) == LHS && Other->getOperand(1) == RHS && - // Is it embeded in the same function? (This could be false if LHS - // is a constant or global!) - Other->getParent()->getParent() == F) { - + if (Other != I && isIdenticalBinaryInst(I, Other)) { // These instructions are identical. Handle the situation. CommonSubExpressionFound(I, Other); return true; // One instruction eliminated! |