aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadav Rotem <nadav.rotem@intel.com>2011-04-05 14:29:52 +0000
committerNadav Rotem <nadav.rotem@intel.com>2011-04-05 14:29:52 +0000
commit0286ca89f0734a81c273e80732a573f619c7ace4 (patch)
treec664441ac594a8c2bf50a1b207a4933d08e33762
parent45c435a24a048c53714c2ebda74037befaf8725c (diff)
InstCombine optimizes gep(bitcast(x)) even when the bitcasts casts away address
space info. We crash with an assert in this case. This change checks that the address space of the bitcasted pointer is the same as the gep ptr. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128884 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp19
-rw-r--r--test/Transforms/InstCombine/gep-addrspace.ll16
2 files changed, 27 insertions, 8 deletions
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index 21851768cb..4be671f031 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -849,22 +849,23 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
Indices.end(), GEP.getName());
}
-
+
// Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
Value *StrippedPtr = PtrOp->stripPointerCasts();
- if (StrippedPtr != PtrOp) {
- const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType());
+ const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType());
+ if (StrippedPtr != PtrOp &&
+ StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) {
bool HasZeroPointerIndex = false;
if (ConstantInt *C = dyn_cast<ConstantInt>(GEP.getOperand(1)))
HasZeroPointerIndex = C->isZero();
-
+
// Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ...
// into : GEP [10 x i8]* X, i32 0, ...
//
// Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ...
// into : GEP i8* X, ...
- //
+ //
// This occurs when the program declares an array extern like "int X[];"
if (HasZeroPointerIndex) {
const PointerType *CPTy = cast<PointerType>(PtrOp->getType());
@@ -975,7 +976,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
}
}
}
-
+
/// See if we can simplify:
/// X = bitcast A* to B*
/// Y = gep X, <...constant indices...>
@@ -983,12 +984,14 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
/// analysis of unions. If "A" is also a bitcast, wait for A/X to be merged.
if (BitCastInst *BCI = dyn_cast<BitCastInst>(PtrOp)) {
if (TD &&
- !isa<BitCastInst>(BCI->getOperand(0)) && GEP.hasAllConstantIndices()) {
+ !isa<BitCastInst>(BCI->getOperand(0)) && GEP.hasAllConstantIndices() &&
+ StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) {
+
// Determine how much the GEP moves the pointer. We are guaranteed to get
// a constant back from EmitGEPOffset.
ConstantInt *OffsetV = cast<ConstantInt>(EmitGEPOffset(&GEP));
int64_t Offset = OffsetV->getSExtValue();
-
+
// If this GEP instruction doesn't move the pointer, just replace the GEP
// with a bitcast of the real input to the dest type.
if (Offset == 0) {
diff --git a/test/Transforms/InstCombine/gep-addrspace.ll b/test/Transforms/InstCombine/gep-addrspace.ll
new file mode 100644
index 0000000000..4c971072cf
--- /dev/null
+++ b/test/Transforms/InstCombine/gep-addrspace.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -instcombine -S
+
+%myStruct = type { float, [3 x float], [4 x float], i32 }
+
+; make sure that we are not crashing when creating an illegal type
+define void @func(%myStruct addrspace(1)* nocapture %p) nounwind {
+ST:
+ %A = getelementptr inbounds %myStruct addrspace(1)* %p, i64 0
+ %B = bitcast %myStruct addrspace(1)* %A to %myStruct*
+ %C = getelementptr inbounds %myStruct* %B, i32 0, i32 1
+ %D = getelementptr inbounds [3 x float]* %C, i32 0, i32 2
+ %E = load float* %D, align 4
+ %F = fsub float %E, undef
+ ret void
+}
+