aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-05-14 19:57:25 +0000
committerChris Lattner <sabre@nondot.org>2002-05-14 19:57:25 +0000
commit0f9fd5b0f820c57c88ea103ddeec44efbfd3345d (patch)
tree6f1abc1c4d44ae337323719bfc0634a6cf63c809 /lib/Transforms
parentf54d0dea8faa11fbae4cf7d6505414564f4ddfa9 (diff)
downloadexternal_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')
-rw-r--r--lib/Transforms/Scalar/GCSE.cpp39
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!