From 75f69e3a3dff78cb89ded1d6c96ccb65603a82d9 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 12 Nov 2011 02:07:50 +0000 Subject: [PATCH] Make sure scalarrepl picks the correct alloca when it rewrites a bitcast. Fixes PR11353. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144442 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/ScalarReplAggregates.cpp | 12 +++++++-- .../ScalarRepl/2011-11-11-EmptyStruct.ll | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index b89f7306a28..c12f403d57e 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1875,8 +1875,14 @@ void SROA::RewriteBitCast(BitCastInst *BC, AllocaInst *AI, uint64_t Offset, return; // The bitcast references the original alloca. Replace its uses with - // references to the first new element alloca. - Instruction *Val = NewElts[0]; + // references to the alloca containing offset zero (which is normally at + // index zero, but might not be in cases involving structs with elements + // of size zero). + Type *T = AI->getAllocatedType(); + uint64_t EltOffset = 0; + Type *IdxTy; + uint64_t Idx = FindElementAndOffset(T, EltOffset, IdxTy); + Instruction *Val = NewElts[Idx]; if (Val->getType() != BC->getDestTy()) { Val = new BitCastInst(Val, BC->getDestTy(), "", BC); Val->takeName(BC); @@ -2160,6 +2166,8 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, } unsigned EltSize = TD->getTypeAllocSize(EltTy); + if (!EltSize) + continue; IRBuilder<> Builder(MI); diff --git a/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll b/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll new file mode 100644 index 00000000000..da707b706d6 --- /dev/null +++ b/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll @@ -0,0 +1,26 @@ +; RUN: opt < %s -S -scalarrepl | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" + +%struct.S = type { [2 x %struct.anon], double } +%struct.anon = type {} + +; CHECK: @test() +; CHECK-NOT: alloca +; CHECK: ret double 1.0 + +define double @test() nounwind uwtable ssp { +entry: + %retval = alloca %struct.S, align 8 + %ret = alloca %struct.S, align 8 + %b = getelementptr inbounds %struct.S* %ret, i32 0, i32 1 + store double 1.000000e+00, double* %b, align 8 + %0 = bitcast %struct.S* %retval to i8* + %1 = bitcast %struct.S* %ret to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 8, i32 8, i1 false) + %2 = bitcast %struct.S* %retval to double* + %3 = load double* %2, align 1 + ret double %3 +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind -- 2.34.1