]> granicus.if.org Git - clang/commitdiff
fix the clang side of PR7437: EmitAggregateCopy
authorChris Lattner <sabre@nondot.org>
Thu, 8 Jul 2010 00:07:45 +0000 (00:07 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 8 Jul 2010 00:07:45 +0000 (00:07 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107842 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprAgg.cpp
test/CodeGen/address-space.c

index 8cf07fd36b61fa464e7d60b8a9d456ba7974e29e..35b7016ab3509ae3d1499d8a510c09126d8e5b8a 100644 (file)
@@ -806,11 +806,6 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
   // equal, but other compilers do this optimization, and almost every memcpy
   // implementation handles this case safely.  If there is a libc that does not
   // 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.
   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
   // 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::Type *DBP = llvm::PointerType::get(I8Ty, DPT->getAddressSpace());
-  if (DestPtr->getType() != DBP)
-    DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
+  const llvm::Type *DBP =
+    llvm::Type::getInt8PtrTy(VMContext, DPT->getAddressSpace());
+  DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
 
   const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
-  const llvm::Type *SBP = llvm::PointerType::get(I8Ty, SPT->getAddressSpace());
-  if (SrcPtr->getType() != SBP)
-    SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
+  const llvm::Type *SBP =
+    llvm::Type::getInt8PtrTy(VMContext, SPT->getAddressSpace());
+  SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
 
   if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
     RecordDecl *Record = RecordTy->getDecl();
@@ -871,6 +864,6 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
                       DestPtr, SrcPtr,
                       // TypeInfo.first describes size in bits.
                       llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
-                      llvm::ConstantInt::get(Int32Ty,  TypeInfo.second/8),
-                      llvm::ConstantInt::get(I1Ty,  isVolatile));
+                      Builder.getInt32(TypeInfo.second/8),
+                      Builder.getInt1(isVolatile));
 }
index 354f58be2f643b224c245afdaf49d2ecbd2d094c..1545e8fe98254f513b247d3368430ebe74100f5f 100644 (file)
@@ -30,3 +30,15 @@ void test3() {
   *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;
+}