aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-04-07 18:38:20 +0000
committerChris Lattner <sabre@nondot.org>2004-04-07 18:38:20 +0000
commitcb69a4ed6424af04ea9c4705ce3674483dc4e02a (patch)
tree319289d4555dbc155cdc322636ce07de69cc3804 /lib/Transforms
parentef09aab9ce34039d1daa15dd4d92170264a09502 (diff)
downloadexternal_llvm-cb69a4ed6424af04ea9c4705ce3674483dc4e02a.zip
external_llvm-cb69a4ed6424af04ea9c4705ce3674483dc4e02a.tar.gz
external_llvm-cb69a4ed6424af04ea9c4705ce3674483dc4e02a.tar.bz2
Implement test/Regression/Transforms/InstCombine/getelementptr_index.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12762 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp61
1 files changed, 38 insertions, 23 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 18da86a..03477e0 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -2317,32 +2317,47 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// Eliminate unneeded casts for indices.
bool MadeChange = false;
- for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i)
- if (CastInst *CI = dyn_cast<CastInst>(GEP.getOperand(i))) {
- Value *Src = CI->getOperand(0);
- const Type *SrcTy = Src->getType();
- const Type *DestTy = CI->getType();
- if (Src->getType()->isInteger()) {
- if (SrcTy->getPrimitiveSize() == DestTy->getPrimitiveSize()) {
- // We can always eliminate a cast from ulong or long to the other. We
- // can always eliminate a cast from uint to int or the other on 32-bit
- // pointer platforms.
- if (DestTy->getPrimitiveSize() >= TD->getPointerSize()) {
- MadeChange = true;
- GEP.setOperand(i, Src);
- }
- } else if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
- SrcTy->getPrimitiveSize() == 4) {
- // We can always eliminate a cast from int to [u]long. We can
- // eliminate a cast from uint to [u]long iff the target is a 32-bit
- // pointer target.
- if (SrcTy->isSigned() ||
- SrcTy->getPrimitiveSize() >= TD->getPointerSize()) {
- MadeChange = true;
- GEP.setOperand(i, Src);
+ gep_type_iterator GTI = gep_type_begin(GEP);
+ for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i, ++GTI)
+ if (isa<SequentialType>(*GTI)) {
+ if (CastInst *CI = dyn_cast<CastInst>(GEP.getOperand(i))) {
+ Value *Src = CI->getOperand(0);
+ const Type *SrcTy = Src->getType();
+ const Type *DestTy = CI->getType();
+ if (Src->getType()->isInteger()) {
+ if (SrcTy->getPrimitiveSize() == DestTy->getPrimitiveSize()) {
+ // We can always eliminate a cast from ulong or long to the other.
+ // We can always eliminate a cast from uint to int or the other on
+ // 32-bit pointer platforms.
+ if (DestTy->getPrimitiveSize() >= TD->getPointerSize()) {
+ MadeChange = true;
+ GEP.setOperand(i, Src);
+ }
+ } else if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
+ SrcTy->getPrimitiveSize() == 4) {
+ // We can always eliminate a cast from int to [u]long. We can
+ // eliminate a cast from uint to [u]long iff the target is a 32-bit
+ // pointer target.
+ if (SrcTy->isSigned() ||
+ SrcTy->getPrimitiveSize() >= TD->getPointerSize()) {
+ MadeChange = true;
+ GEP.setOperand(i, Src);
+ }
}
}
}
+ // If we are using a wider index than needed for this platform, shrink it
+ // to what we need. If the incoming value needs a cast instruction,
+ // insert it. This explicit cast can make subsequent optimizations more
+ // obvious.
+ Value *Op = GEP.getOperand(i);
+ if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
+ if (!isa<Constant>(Op)) {
+ Op = InsertNewInstBefore(new CastInst(Op, TD->getIntPtrType(),
+ Op->getName()), GEP);
+ GEP.setOperand(i, Op);
+ MadeChange = true;
+ }
}
if (MadeChange) return &GEP;