aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorMeador Inge <meadori@codesourcery.com>2013-02-27 02:26:42 +0000
committerMeador Inge <meadori@codesourcery.com>2013-02-27 02:26:42 +0000
commit8df7c39976890d94198d835e032848a374fec158 (patch)
tree720c2f50e52f22799557139f939fdf79d84ce37f /lib/IR/ConstantFold.cpp
parent5e5974f51ad079a3ed890ca8be1d3f50150320ad (diff)
IR: Don't constant fold GEP bitcasts between different address spaces
PR15262 reported a bug where the following instruction: i8 getelementptr inbounds i8* bitcast ([4 x i8] addrspace(12)* @buf to i8*), i32 2 was getting folded into: addrspace(12)* getelementptr inbounds ([4 x i8] addrspace(12)* @buf, i32 0, i32 2) This caused instcombine to crash because the original instruction and the folded instruction have different types. The issue was fixed by disallowing bitcasts between different address spaces to be folded away. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176156 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR/ConstantFold.cpp')
-rw-r--r--lib/IR/ConstantFold.cpp35
1 files changed, 22 insertions, 13 deletions
diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp
index a5a9d9f3a7..bf93d4f956 100644
--- a/lib/IR/ConstantFold.cpp
+++ b/lib/IR/ConstantFold.cpp
@@ -1971,21 +1971,30 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
}
}
- // Implement folding of:
- // i32* getelementptr ([2 x i32]* bitcast ([3 x i32]* %X to [2 x i32]*),
- // i64 0, i64 0)
- // To: i32* getelementptr ([3 x i32]* %X, i64 0, i64 0)
+ // Attempt to fold casts to the same type away. For example, folding:
//
+ // i32* getelementptr ([2 x i32]* bitcast ([3 x i32]* %X to [2 x i32]*),
+ // i64 0, i64 0)
+ // into:
+ //
+ // i32* getelementptr ([3 x i32]* %X, i64 0, i64 0)
+ //
+ // Don't fold if the cast is changing address spaces.
if (CE->isCast() && Idxs.size() > 1 && Idx0->isNullValue()) {
- if (PointerType *SPT =
- dyn_cast<PointerType>(CE->getOperand(0)->getType()))
- if (ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType()))
- if (ArrayType *CAT =
- dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType()))
- if (CAT->getElementType() == SAT->getElementType())
- return
- ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0),
- Idxs, inBounds);
+ PointerType *SrcPtrTy =
+ dyn_cast<PointerType>(CE->getOperand(0)->getType());
+ PointerType *DstPtrTy = dyn_cast<PointerType>(CE->getType());
+ if (SrcPtrTy && DstPtrTy) {
+ ArrayType *SrcArrayTy =
+ dyn_cast<ArrayType>(SrcPtrTy->getElementType());
+ ArrayType *DstArrayTy =
+ dyn_cast<ArrayType>(DstPtrTy->getElementType());
+ if (SrcArrayTy && DstArrayTy
+ && SrcArrayTy->getElementType() == DstArrayTy->getElementType()
+ && SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
+ return ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0),
+ Idxs, inBounds);
+ }
}
}