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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165101 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2012-10-03 08:26:28 +00:00
parent f710fb14ee
commit 322e9ba2cb
2 changed files with 37 additions and 0 deletions

View File

@ -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)

View File

@ -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
}