fix the clang side of PR7437: EmitAggregateCopy

was not producing a memcpy with the right address
spaces because of two places in it doing casts of
the arguments to i8, one of which that didn't
preserve the address space.

There is also an optimizer bug here.

llvm-svn: 107842
This commit is contained in:
Chris Lattner 2010-07-08 00:07:45 +00:00
parent 26b1a19842
commit cb7696cf35
2 changed files with 20 additions and 15 deletions

View File

@ -806,11 +806,6 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
// equal, but other compilers do this optimization, and almost every memcpy // equal, but other compilers do this optimization, and almost every memcpy
// implementation handles this case safely. If there is a libc that does not // implementation handles this case safely. If there is a libc that does not
// safely handle this, we can add a target hook. // safely handle this, we can add a target hook.
const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
if (DestPtr->getType() != BP)
DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
if (SrcPtr->getType() != BP)
SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
// Get size and alignment info for this aggregate. // Get size and alignment info for this aggregate.
std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty); std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
@ -829,18 +824,16 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
// //
// we need to use a different call here. We use isVolatile to indicate when // we need to use a different call here. We use isVolatile to indicate when
// either the source or the destination is volatile. // either the source or the destination is volatile.
const llvm::Type *I1Ty = llvm::Type::getInt1Ty(VMContext);
const llvm::Type *I8Ty = llvm::Type::getInt8Ty(VMContext);
const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
const llvm::Type *DBP = llvm::PointerType::get(I8Ty, DPT->getAddressSpace()); const llvm::Type *DBP =
if (DestPtr->getType() != DBP) llvm::Type::getInt8PtrTy(VMContext, DPT->getAddressSpace());
DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp"); DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
const llvm::Type *SBP = llvm::PointerType::get(I8Ty, SPT->getAddressSpace()); const llvm::Type *SBP =
if (SrcPtr->getType() != SBP) llvm::Type::getInt8PtrTy(VMContext, SPT->getAddressSpace());
SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp"); SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
RecordDecl *Record = RecordTy->getDecl(); RecordDecl *Record = RecordTy->getDecl();
@ -871,6 +864,6 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
DestPtr, SrcPtr, DestPtr, SrcPtr,
// TypeInfo.first describes size in bits. // TypeInfo.first describes size in bits.
llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8), llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
llvm::ConstantInt::get(Int32Ty, TypeInfo.second/8), Builder.getInt32(TypeInfo.second/8),
llvm::ConstantInt::get(I1Ty, isVolatile)); Builder.getInt1(isVolatile));
} }

View File

@ -30,3 +30,15 @@ void test3() {
*A = *B; *A = *B;
} }
// PR7437
typedef struct {
float aData[1];
} MyStruct;
// CHECK: define void @test4(
// CHECK: call void @llvm.memcpy.p0i8.p2i8.i64
// CHECK: call void @llvm.memcpy.p2i8.p0i8.i64
void test4(MyStruct __attribute__((address_space(2))) *pPtr) {
MyStruct s = pPtr[0];
pPtr[0] = s;
}