diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-01-14 00:20:05 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-01-14 00:20:05 +0000 |
| commit | 4fa89827e29b29bb989993774749e3cd4fb9dd06 (patch) | |
| tree | 30b1aa139fc2c5c86853e31a40597c1195030b02 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp | |
| parent | d35d210ea08cc048f5faebcdf7df4d7634972321 (diff) | |
| download | bcm5719-llvm-4fa89827e29b29bb989993774749e3cd4fb9dd06.tar.gz bcm5719-llvm-4fa89827e29b29bb989993774749e3cd4fb9dd06.zip | |
if two gep comparisons only differ by one index, compare that index directly.
This allows us to better optimize begin() -> end() comparisons in common cases.
llvm-svn: 19542
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index e8f52d11573..948eb329040 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2219,6 +2219,8 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS, if (AllZeros) return FoldGEPSetCC(GEPRHS, GEPLHS->getOperand(0), SetCondInst::getSwappedCondition(Cond), I); + + // If the other GEP has all zero indices, recurse. AllZeros = true; for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i) if (!isa<Constant>(GEPRHS->getOperand(i)) || @@ -2229,6 +2231,32 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS, if (AllZeros) return FoldGEPSetCC(GEPLHS, GEPRHS->getOperand(0), Cond, I); + if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands()) { + // If the GEPs only differ by one index, compare it. + unsigned NumDifferences = 0; // Keep track of # differences. + unsigned DiffOperand = 0; // The operand that differs. + for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i) + if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) { + if (GEPLHS->getOperand(i)->getType() != + GEPRHS->getOperand(i)->getType()) { + // Irreconsilable differences. + NumDifferences = 2; + break; + } else { + if (NumDifferences++) break; + DiffOperand = i; + } + } + + if (NumDifferences == 0) // SAME GEP? + return ReplaceInstUsesWith(I, // No comparison is needed here. + ConstantBool::get(Cond == Instruction::SetEQ)); + else if (NumDifferences == 1) { + return new SetCondInst(Cond, GEPLHS->getOperand(DiffOperand), + GEPRHS->getOperand(DiffOperand)); + } + } + // Only lower this if the setcc is the only user of the GEP or if we expect // the result to fold to a constant! if ((isa<ConstantExpr>(GEPLHS) || GEPLHS->hasOneUse()) && |

