diff options
author | Owen Anderson <resistor@mac.com> | 2014-10-05 23:41:26 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2014-10-05 23:41:26 +0000 |
commit | eb2be340947ec1acf325710d1e7297345f56ff35 (patch) | |
tree | 8da4864056e161d6d0c79e732c2c602c16b1c3dd /lib/Transforms/Scalar/Reassociate.cpp | |
parent | 1d02acb7a0330ad68bce53e80e5538bedfcb6c2f (diff) |
Give the Reassociate pass a bit more flexibility and autonomy when optimizing expressions.
Particularly, it addresses cases where Reassociate breaks Subtracts but then fails to optimize combinations like I1 + -I2 where I1 and I2 have the same rank and are identical.
Patch by Dmitri Shtilman.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219092 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r-- | lib/Transforms/Scalar/Reassociate.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index d0cd48a3a26..b8fb25d0b9a 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -1034,13 +1034,23 @@ static unsigned FindInOperandList(SmallVectorImpl<ValueEntry> &Ops, unsigned i, Value *X) { unsigned XRank = Ops[i].Rank; unsigned e = Ops.size(); - for (unsigned j = i+1; j != e && Ops[j].Rank == XRank; ++j) + for (unsigned j = i+1; j != e && Ops[j].Rank == XRank; ++j) { if (Ops[j].Op == X) return j; + if (Instruction *I1 = dyn_cast<Instruction>(Ops[j].Op)) + if (Instruction *I2 = dyn_cast<Instruction>(X)) + if (I1->isIdenticalTo(I2)) + return j; + } // Scan backwards. - for (unsigned j = i-1; j != ~0U && Ops[j].Rank == XRank; --j) + for (unsigned j = i-1; j != ~0U && Ops[j].Rank == XRank; --j) { if (Ops[j].Op == X) return j; + if (Instruction *I1 = dyn_cast<Instruction>(Ops[j].Op)) + if (Instruction *I2 = dyn_cast<Instruction>(X)) + if (I1->isIdenticalTo(I2)) + return j; + } return i; } |