From 08e5f49f90a82ab2aacb2fe096a239625eb17e84 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 3 Oct 2012 08:26:28 +0000 Subject: [PATCH] Fix an issue where we failed to adjust the alignment constraint on a memcpy to reflect that '0' has a different meaning when applied to a load or store. Now we correctly use underaligned loads and stores for the test case added. llvm-svn: 165101 --- llvm/lib/Transforms/Scalar/SROA.cpp | 6 ++++++ llvm/test/Transforms/SROA/alignment.ll | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 58bae09..f4fd857 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -2585,6 +2585,12 @@ private: return false; } + // Note that we clamp the alignment to 1 here as a 0 alignment for a memcpy + // is equivalent to 1, but that isn't true if we end up rewriting this as + // a load or store. + if (!Align) + Align = 1; + Value *SrcPtr = OtherPtr; Value *DstPtr = &NewAI; if (!IsDest) diff --git a/llvm/test/Transforms/SROA/alignment.ll b/llvm/test/Transforms/SROA/alignment.ll index f8f3270..9fe3bcbb 100644 --- a/llvm/test/Transforms/SROA/alignment.ll +++ b/llvm/test/Transforms/SROA/alignment.ll @@ -169,3 +169,34 @@ entry: ret void } + +define void @test7(i8* %out) { +; Test that we properly compute the destination alignment when rewriting +; memcpys as direct loads or stores. +; CHECK: @test7 +; CHECK-NOT: alloca + +entry: + %a = alloca [16 x i8] + %raw1 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 0 + %ptr1 = bitcast i8* %raw1 to double* + %raw2 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 8 + %ptr2 = bitcast i8* %raw2 to double* + + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %raw1, i8* %out, i32 16, i32 0, i1 false) +; CHECK: %[[val2:.*]] = load double* %{{.*}}, align 1 +; CHECK: %[[val1:.*]] = load double* %{{.*}}, align 1 + + %val1 = load double* %ptr2, align 1 + %val2 = load double* %ptr1, align 1 + + store double %val1, double* %ptr1, align 1 + store double %val2, double* %ptr2, align 1 + + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %out, i8* %raw1, i32 16, i32 0, i1 false) +; CHECK: store double %[[val1]], double* %{{.*}}, align 1 +; CHECK: store double %[[val2]], double* %{{.*}}, align 1 + + ret void +; CHECK: ret void +} -- 2.7.4