r176786 - Fix indirect byval passing of records in address spaced memory. Allocate memory on stack, and memcpy the actual value before the call.

Guy Benyei guy.benyei at intel.com
Sun Mar 10 05:59:01 PDT 2013


Author: gbenyei
Date: Sun Mar 10 07:59:00 2013
New Revision: 176786

URL: http://llvm.org/viewvc/llvm-project?rev=176786&view=rev
Log:
Fix indirect byval passing of records in address spaced memory. Allocate memory on stack, and memcpy the actual value before the call.

Added:
    cfe/trunk/test/CodeGenOpenCL/addr-space-struct-arg.cl
Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=176786&r1=176785&r2=176786&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Sun Mar 10 07:59:00 2013
@@ -2199,17 +2199,23 @@ RValue CodeGenFunction::EmitCall(const C
         checkArgMatches(AI, IRArgNo, IRFuncTy);
       } else {
         // We want to avoid creating an unnecessary temporary+copy here;
-        // however, we need one in two cases:
+        // however, we need one in three cases:
         // 1. If the argument is not byval, and we are required to copy the
         //    source.  (This case doesn't occur on any common architecture.)
         // 2. If the argument is byval, RV is not sufficiently aligned, and
         //    we cannot force it to be sufficiently aligned.
+        // 3. If the argument is byval, but RV is located in an address space
+        //    different than that of the argument (0).
         llvm::Value *Addr = RV.getAggregateAddr();
         unsigned Align = ArgInfo.getIndirectAlign();
         const llvm::DataLayout *TD = &CGM.getDataLayout();
+        const unsigned RVAddrSpace = Addr->getType()->getPointerAddressSpace();
+        const unsigned ArgAddrSpace = (IRArgNo < IRFuncTy->getNumParams() ?
+          IRFuncTy->getParamType(IRArgNo)->getPointerAddressSpace() : 0);
         if ((!ArgInfo.getIndirectByVal() && I->NeedsCopy) ||
             (ArgInfo.getIndirectByVal() && TypeAlign.getQuantity() < Align &&
-             llvm::getOrEnforceKnownAlignment(Addr, Align, TD) < Align)) {
+             llvm::getOrEnforceKnownAlignment(Addr, Align, TD) < Align) ||
+             (ArgInfo.getIndirectByVal() && (RVAddrSpace != ArgAddrSpace))) {
           // Create an aligned temporary, and copy to it.
           llvm::AllocaInst *AI = CreateMemTemp(I->Ty);
           if (Align > AI->getAlignment())

Added: cfe/trunk/test/CodeGenOpenCL/addr-space-struct-arg.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/addr-space-struct-arg.cl?rev=176786&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/addr-space-struct-arg.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/addr-space-struct-arg.cl Sun Mar 10 07:59:00 2013
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -ffake-address-space-map -triple i686-pc-darwin | FileCheck %s
+
+typedef struct {
+  int cells[9];
+} Mat3X3;
+
+typedef struct {
+  int cells[16];
+} Mat4X4;
+
+Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) {
+  Mat4X4 out;
+  return out;
+}
+
+kernel void ker(global Mat3X3 *in, global Mat4X4 *out) {
+  out[0] = foo(in[1]);
+}
+
+// Expect two mem copies: one for the argument "in", and one for
+// the return value.
+// CHECK: call void @llvm.memcpy.p0i8.p1i8.i32(i8*
+// CHECK: call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)*





More information about the cfe-commits mailing list