diff options
-rw-r--r-- | llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp | 11 | ||||
-rw-r--r-- | llvm/test/Transforms/ScalarRepl/crash.ll | 22 |
2 files changed, 30 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index ec835b15ca8..6637126fcb7 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -612,11 +612,16 @@ void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User)) { // Compute the offset that this GEP adds to the pointer. SmallVector<Value*, 8> Indices(GEP->op_begin()+1, GEP->op_end()); - if (!GEP->hasAllConstantIndices()) - NonConstantIdx = Indices.pop_back_val(); + Value* GEPNonConstantIdx = 0; + if (!GEP->hasAllConstantIndices()) { + assert(!NonConstantIdx && + "Dynamic GEP reading from dynamic GEP unsupported"); + GEPNonConstantIdx = Indices.pop_back_val(); + } else + GEPNonConstantIdx = NonConstantIdx; uint64_t GEPOffset = TD.getIndexedOffset(GEP->getPointerOperandType(), Indices); - ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8, NonConstantIdx); + ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8, GEPNonConstantIdx); GEP->eraseFromParent(); continue; } diff --git a/llvm/test/Transforms/ScalarRepl/crash.ll b/llvm/test/Transforms/ScalarRepl/crash.ll index cd4dc328e69..58c5a3a0527 100644 --- a/llvm/test/Transforms/ScalarRepl/crash.ll +++ b/llvm/test/Transforms/ScalarRepl/crash.ll @@ -260,5 +260,27 @@ entry: ret void } +; rdar://11861001 - The dynamic GEP here was incorrectly making all accesses +; to the alloca think they were also dynamic. Inserts and extracts created to +; access the vector were all being based from the dynamic access, even in BBs +; not dominated by the GEP. +define fastcc void @test() optsize inlinehint ssp align 2 { +entry: + %alloc.0.0 = alloca <4 x float>, align 16 + %bitcast = bitcast <4 x float>* %alloc.0.0 to [4 x float]* + %idx3 = getelementptr inbounds [4 x float]* %bitcast, i32 0, i32 3 + store float 0.000000e+00, float* %idx3, align 4 + br label %for.body10 + +for.body10: ; preds = %for.body10, %entry + %loopidx = phi i32 [ 0, %entry ], [ undef, %for.body10 ] + %unusedidx = getelementptr inbounds <4 x float>* %alloc.0.0, i32 0, i32 %loopidx + br i1 undef, label %for.end, label %for.body10 + +for.end: ; preds = %for.body10 + store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float 0.000000e+00>, <4 x float>* %alloc.0.0, align 16 + ret void +} + declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind |