<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Mar 9, 2018, at 8:51 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" class="">richard@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi,<div class=""><br class=""></div><div class="">This change increases the size of a CallArg, and thus that of a CallArgList, dramatically (an LValue is *much* larger than an RValue, and unlike an RValue, does not appear to be at all optimized for size). This results in CallArgList (which contains inline storage for 16 CallArgs) ballooning in size from ~500 bytes to 2KB, resulting in stack overflows on programs with deep ASTs.</div><div class=""><br class=""></div><div class="">Given that this introduces a regression (due to stack overflow), I've reverted in r327195. Sorry about that.</div></div></div></blockquote><div><br class=""></div>Seems reasonable.</div><div><br class=""></div><div>The right short-term fix is probably a combination of the following:</div><div>  - put a little bit of effort into packing LValue (using fewer than 64 bits for the alignment and packing the bit-fields, I think)</div><div>  - drop the inline argument count to something like 8, which should still capture the vast majority of calls.</div><div><br class=""></div><div>There are quite a few other space optimizations we could do the LValue afterwards.   I think we could eliminate BaseIVarExp completely by storing some sort of ObjC GC classification and then just evaluating the base expression normally.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">The program it broke looked something like this:</div><div class=""><br class=""></div><div class=""><div class="">struct VectorBuilder {</div><div class="">  VectorBuilder &operator,(int);</div><div class="">};</div><div class="">void f() {</div><div class="">  VectorBuilder(),</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,</div><div class="">  1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0;</div><div class="">}</div></div><div class=""><br class=""></div><div class="">using Eigen's somewhat-ridiculous comma initializer technique (<a href="https://eigen.tuxfamily.org/dox/group__TutorialAdvancedInitialization.html" class="">https://eigen.tuxfamily.org/dox/group__TutorialAdvancedInitialization.html</a>) to build an approx 40 x 40 array.</div></div></div></blockquote><br class=""><div><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">An AST 1600 levels deep is somewhat extreme, but it still seems like something we should be able to handle within our default 8MB stack limit.</div></div></blockquote><div class=""><div dir="ltr" class=""><div class=""><br class=""></div></div></div></div>I mean, at some point this really is not supportable, even if it happens to build on current compilers.  If we actually documented and enforced our implementation limits like we're supposed to, I do not think we would allow this much call nesting.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div></div><div class="gmail_extra"><div class="gmail_quote">On 7 March 2018 at 13:45, Yaxun Liu via cfe-commits <span dir="ltr" class=""><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: yaxunl<br class="">
Date: Wed Mar  7 13:45:40 2018<br class="">
New Revision: 326946<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=326946&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=326946&view=rev</a><br class="">
Log:<br class="">
CodeGen: Fix address space of indirect function argument<br class="">
<br class="">
The indirect function argument is in alloca address space in LLVM IR. However,<br class="">
during Clang codegen for C++, the address space of indirect function argument<br class="">
should match its address space in the source code, i.e., default addr space, even<br class="">
for indirect argument. This is because destructor of the indirect argument may<br class="">
be called in the caller function, and address of the indirect argument may be<br class="">
taken, in either case the indirect function argument is expected to be in default<br class="">
addr space, not the alloca address space.<br class="">
<br class="">
Therefore, the indirect function argument should be mapped to the temp var<br class="">
casted to default address space. The caller will cast it to alloca addr space<br class="">
when passing it to the callee. In the callee, the argument is also casted to the<br class="">
default address space and used.<br class="">
<br class="">
CallArg is refactored to facilitate this fix.<br class="">
<br class="">
Differential Revision: <a href="https://reviews.llvm.org/D34367" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/<wbr class="">D34367</a><br class="">
<br class="">
Added:<br class="">
    cfe/trunk/test/CodeGenCXX/<wbr class="">amdgcn-func-arg.cpp<br class="">
Modified:<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">CGAtomic.cpp<br class="">
    cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp<br class="">
    cfe/trunk/lib/CodeGen/CGCall.h<br class="">
    cfe/trunk/lib/CodeGen/CGClass.<wbr class="">cpp<br class="">
    cfe/trunk/lib/CodeGen/CGDecl.<wbr class="">cpp<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">CGExprCXX.cpp<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">CGGPUBuiltin.cpp<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">CGObjCGNU.cpp<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">CGObjCMac.cpp<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">CodeGenFunction.h<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp<br class="">
    cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp<br class="">
    cfe/trunk/test/CodeGenOpenCL/<a href="http://addr-space-struct-arg.cl/" rel="noreferrer" target="_blank" class="">a<wbr class="">ddr-space-struct-arg.cl</a><br class="">
    cfe/trunk/test/CodeGenOpenCL/<a href="http://byval.cl/" rel="noreferrer" target="_blank" class="">b<wbr class="">yval.cl</a><br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">CGAtomic.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGAtomic.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">CGAtomic.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">CGAtomic.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1160,7 +1160,7 @@ RValue CodeGenFunction::<wbr class="">EmitAtomicExpr(A<br class="">
     if (UseOptimizedLibcall && Res.getScalarVal()) {<br class="">
       llvm::Value *ResVal = Res.getScalarVal();<br class="">
       if (PostOp) {<br class="">
-        llvm::Value *LoadVal1 = Args[1].RV.getScalarVal();<br class="">
+        llvm::Value *LoadVal1 = Args[1].getRValue(*this).<wbr class="">getScalarVal();<br class="">
         ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1);<br class="">
       }<br class="">
       if (E->getOp() == AtomicExpr::AO__atomic_nand_<wbr class="">fetch)<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGCall.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGCall.<wbr class="">cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1040,42 +1040,49 @@ void CodeGenFunction::<wbr class="">ExpandTypeFromArgs<br class="">
 }<br class="">
<br class="">
 void CodeGenFunction::<wbr class="">ExpandTypeToArgs(<br class="">
-    QualType Ty, RValue RV, llvm::FunctionType *IRFuncTy,<br class="">
+    QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,<br class="">
     SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos) {<br class="">
   auto Exp = getTypeExpansion(Ty, getContext());<br class="">
   if (auto CAExp = dyn_cast<<wbr class="">ConstantArrayExpansion>(Exp.<wbr class="">get())) {<br class="">
-    forConstantArrayExpansion(*<wbr class="">this, CAExp, RV.getAggregateAddress(),<br class="">
-                              [&](Address EltAddr) {<br class="">
-      RValue EltRV =<br class="">
-          convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation());<br class="">
-      ExpandTypeToArgs(CAExp->EltTy, EltRV, IRFuncTy, IRCallArgs, IRCallArgPos);<br class="">
-    });<br class="">
+    Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().<wbr class="">getAddress()<br class="">
+                                   : Arg.getKnownRValue().<wbr class="">getAggregateAddress();<br class="">
+    forConstantArrayExpansion(<br class="">
+        *this, CAExp, Addr, [&](Address EltAddr) {<br class="">
+          CallArg EltArg = CallArg(<br class="">
+              convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),<br class="">
+              CAExp->EltTy);<br class="">
+          ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,<br class="">
+                           IRCallArgPos);<br class="">
+        });<br class="">
   } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.<wbr class="">get())) {<br class="">
-    Address This = RV.getAggregateAddress();<br class="">
+    Address This = Arg.hasLValue() ? Arg.getKnownLValue().<wbr class="">getAddress()<br class="">
+                                   : Arg.getKnownRValue().<wbr class="">getAggregateAddress();<br class="">
     for (const CXXBaseSpecifier *BS : RExp->Bases) {<br class="">
       // Perform a single step derived-to-base conversion.<br class="">
       Address Base =<br class="">
           GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1,<br class="">
                                 /*NullCheckValue=*/false, SourceLocation());<br class="">
-      RValue BaseRV = RValue::getAggregate(Base);<br class="">
+      CallArg BaseArg = CallArg(RValue::getAggregate(<wbr class="">Base), BS->getType());<br class="">
<br class="">
       // Recurse onto bases.<br class="">
-      ExpandTypeToArgs(BS->getType()<wbr class="">, BaseRV, IRFuncTy, IRCallArgs,<br class="">
+      ExpandTypeToArgs(BS->getType()<wbr class="">, BaseArg, IRFuncTy, IRCallArgs,<br class="">
                        IRCallArgPos);<br class="">
     }<br class="">
<br class="">
     LValue LV = MakeAddrLValue(This, Ty);<br class="">
     for (auto FD : RExp->Fields) {<br class="">
-      RValue FldRV = EmitRValueForField(LV, FD, SourceLocation());<br class="">
-      ExpandTypeToArgs(FD->getType()<wbr class="">, FldRV, IRFuncTy, IRCallArgs,<br class="">
+      CallArg FldArg =<br class="">
+          CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());<br class="">
+      ExpandTypeToArgs(FD->getType()<wbr class="">, FldArg, IRFuncTy, IRCallArgs,<br class="">
                        IRCallArgPos);<br class="">
     }<br class="">
   } else if (isa<ComplexExpansion>(Exp.<wbr class="">get())) {<br class="">
-    ComplexPairTy CV = RV.getComplexVal();<br class="">
+    ComplexPairTy CV = Arg.getKnownRValue().<wbr class="">getComplexVal();<br class="">
     IRCallArgs[IRCallArgPos++] = CV.first;<br class="">
     IRCallArgs[IRCallArgPos++] = CV.second;<br class="">
   } else {<br class="">
     assert(isa<NoExpansion>(Exp.<wbr class="">get()));<br class="">
+    auto RV = Arg.getKnownRValue();<br class="">
     assert(RV.isScalar() &&<br class="">
            "Unexpected non-scalar rvalue during struct expansion.");<br class="">
<br class="">
@@ -3418,13 +3425,17 @@ void CodeGenFunction::EmitCallArgs(<br class="">
     assert(InitialArgSize + 1 == Args.size() &&<br class="">
            "The code below depends on only adding one arg per EmitCallArg");<br class="">
     (void)InitialArgSize;<br class="">
-    RValue RVArg = Args.back().RV;<br class="">
-    EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,<br class="">
-                        ParamsToSkip + Idx);<br class="">
-    // @llvm.objectsize should never have side-effects and shouldn't need<br class="">
-    // destruction/cleanups, so we can safely "emit" it after its arg,<br class="">
-    // regardless of right-to-leftness<br class="">
-    MaybeEmitImplicitObjectSize(<wbr class="">Idx, *Arg, RVArg);<br class="">
+    // Since pointer argument are never emitted as LValue, it is safe to emit<br class="">
+    // non-null argument check for r-value only.<br class="">
+    if (!Args.back().hasLValue()) {<br class="">
+      RValue RVArg = Args.back().getKnownRValue();<br class="">
+      EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,<br class="">
+                          ParamsToSkip + Idx);<br class="">
+      // @llvm.objectsize should never have side-effects and shouldn't need<br class="">
+      // destruction/cleanups, so we can safely "emit" it after its arg,<br class="">
+      // regardless of right-to-leftness<br class="">
+      MaybeEmitImplicitObjectSize(<wbr class="">Idx, *Arg, RVArg);<br class="">
+    }<br class="">
   }<br class="">
<br class="">
   if (!LeftToRight) {<br class="">
@@ -3471,6 +3482,31 @@ struct DisableDebugLocationUpdates {<br class="">
<br class="">
 } // end anonymous namespace<br class="">
<br class="">
+RValue CallArg::getRValue(<wbr class="">CodeGenFunction &CGF) const {<br class="">
+  if (!HasLV)<br class="">
+    return RV;<br class="">
+  LValue Copy = CGF.MakeAddrLValue(CGF.<wbr class="">CreateMemTemp(Ty), Ty);<br class="">
+  CGF.EmitAggregateCopy(Copy, LV, Ty, LV.isVolatile());<br class="">
+  IsUsed = true;<br class="">
+  return RValue::getAggregate(Copy.<wbr class="">getAddress());<br class="">
+}<br class="">
+<br class="">
+void CallArg::copyInto(<wbr class="">CodeGenFunction &CGF, Address Addr) const {<br class="">
+  LValue Dst = CGF.MakeAddrLValue(Addr, Ty);<br class="">
+  if (!HasLV && RV.isScalar())<br class="">
+    CGF.EmitStoreOfScalar(RV.<wbr class="">getScalarVal(), Dst, /*init=*/true);<br class="">
+  else if (!HasLV && RV.isComplex())<br class="">
+    CGF.EmitStoreOfComplex(RV.<wbr class="">getComplexVal(), Dst, /*init=*/true);<br class="">
+  else {<br class="">
+    auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress();<br class="">
+    LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty);<br class="">
+    CGF.EmitAggregateCopy(Dst, SrcLV, Ty,<br class="">
+                          HasLV ? LV.isVolatileQualified()<br class="">
+                                : RV.isVolatileQualified());<br class="">
+  }<br class="">
+  IsUsed = true;<br class="">
+}<br class="">
+<br class="">
 void CodeGenFunction::EmitCallArg(<wbr class="">CallArgList &args, const Expr *E,<br class="">
                                   QualType type) {<br class="">
   DisableDebugLocationUpdates Dis(*this, E);<br class="">
@@ -3536,15 +3572,7 @@ void CodeGenFunction::EmitCallArg(<wbr class="">CallAr<br class="">
       cast<CastExpr>(E)-><wbr class="">getCastKind() == CK_LValueToRValue) {<br class="">
     LValue L = EmitLValue(cast<CastExpr>(E)-><wbr class="">getSubExpr());<br class="">
     assert(L.isSimple());<br class="">
-    if (L.getAlignment() >= getContext().<wbr class="">getTypeAlignInChars(type)) {<br class="">
-      args.add(L.asAggregateRValue()<wbr class="">, type, /*NeedsCopy*/true);<br class="">
-    } else {<br class="">
-      // We can't represent a misaligned lvalue in the CallArgList, so copy<br class="">
-      // to an aligned temporary now.<br class="">
-      LValue Dest = MakeAddrLValue(CreateMemTemp(<wbr class="">type), type);<br class="">
-      EmitAggregateCopy(Dest, L, type, L.isVolatile());<br class="">
-      args.add(RValue::getAggregate(<wbr class="">Dest.getAddress()), type);<br class="">
-    }<br class="">
+    args.addUncopiedAggregate(L, type);<br class="">
     return;<br class="">
   }<br class="">
<br class="">
@@ -3702,16 +3730,6 @@ CodeGenFunction::<wbr class="">EmitCallOrInvoke(llvm::<br class="">
   return llvm::CallSite(Inst);<br class="">
 }<br class="">
<br class="">
-/// \brief Store a non-aggregate value to an address to initialize it.  For<br class="">
-/// initialization, a non-atomic store will be used.<br class="">
-static void EmitInitStoreOfNonAggregate(<wbr class="">CodeGenFunction &CGF, RValue Src,<br class="">
-                                        LValue Dst) {<br class="">
-  if (Src.isScalar())<br class="">
-    CGF.EmitStoreOfScalar(Src.<wbr class="">getScalarVal(), Dst, /*init=*/true);<br class="">
-  else<br class="">
-    CGF.EmitStoreOfComplex(Src.<wbr class="">getComplexVal(), Dst, /*init=*/true);<br class="">
-}<br class="">
-<br class="">
 void CodeGenFunction::<wbr class="">deferPlaceholderReplacement(<wbr class="">llvm::Instruction *Old,<br class="">
                                                   llvm::Value *New) {<br class="">
   DeferredReplacements.push_<wbr class="">back(std::make_pair(Old, New));<br class="">
@@ -3804,7 +3822,6 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
   for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();<br class="">
        I != E; ++I, ++info_it, ++ArgNo) {<br class="">
     const ABIArgInfo &ArgInfo = info_it->info;<br class="">
-    RValue RV = I->RV;<br class="">
<br class="">
     // Insert a padding argument to ensure proper alignment.<br class="">
     if (IRFunctionArgs.hasPaddingArg(<wbr class="">ArgNo))<br class="">
@@ -3818,13 +3835,16 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
     case ABIArgInfo::InAlloca: {<br class="">
       assert(NumIRArgs == 0);<br class="">
       assert(getTarget().getTriple()<wbr class="">.getArch() == llvm::Triple::x86);<br class="">
-      if (RV.isAggregate()) {<br class="">
+      if (I->isAggregate()) {<br class="">
         // Replace the placeholder with the appropriate argument slot GEP.<br class="">
+        Address Addr = I->hasLValue()<br class="">
+                           ? I->getKnownLValue().<wbr class="">getAddress()<br class="">
+                           : I->getKnownRValue().<wbr class="">getAggregateAddress();<br class="">
         llvm::Instruction *Placeholder =<br class="">
-            cast<llvm::Instruction>(RV.<wbr class="">getAggregatePointer());<br class="">
+            cast<llvm::Instruction>(Addr.<wbr class="">getPointer());<br class="">
         CGBuilderTy::InsertPoint IP = Builder.saveIP();<br class="">
         Builder.SetInsertPoint(<wbr class="">Placeholder);<br class="">
-        Address Addr = createInAllocaStructGEP(<wbr class="">ArgInfo.getInAllocaFieldIndex(<wbr class="">));<br class="">
+        Addr = createInAllocaStructGEP(<wbr class="">ArgInfo.getInAllocaFieldIndex(<wbr class="">));<br class="">
         Builder.restoreIP(IP);<br class="">
         deferPlaceholderReplacement(<wbr class="">Placeholder, Addr.getPointer());<br class="">
       } else {<br class="">
@@ -3837,22 +3857,20 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
         // from {}* to (%struct.foo*)*.<br class="">
         if (Addr.getType() != MemType)<br class="">
           Addr = Builder.CreateBitCast(Addr, MemType);<br class="">
-        LValue argLV = MakeAddrLValue(Addr, I->Ty);<br class="">
-        EmitInitStoreOfNonAggregate(*<wbr class="">this, RV, argLV);<br class="">
+        I->copyInto(*this, Addr);<br class="">
       }<br class="">
       break;<br class="">
     }<br class="">
<br class="">
     case ABIArgInfo::Indirect: {<br class="">
       assert(NumIRArgs == 1);<br class="">
-      if (RV.isScalar() || RV.isComplex()) {<br class="">
+      if (!I->isAggregate()) {<br class="">
         // Make a temporary alloca to pass the argument.<br class="">
         Address Addr = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(),<br class="">
                                      "indirect-arg-temp", false);<br class="">
         IRCallArgs[FirstIRArg] = Addr.getPointer();<br class="">
<br class="">
-        LValue argLV = MakeAddrLValue(Addr, I->Ty);<br class="">
-        EmitInitStoreOfNonAggregate(*<wbr class="">this, RV, argLV);<br class="">
+        I->copyInto(*this, Addr);<br class="">
       } else {<br class="">
         // We want to avoid creating an unnecessary temporary+copy here;<br class="">
         // however, we need one in three cases:<br class="">
@@ -3860,32 +3878,51 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
         //    source.  (This case doesn't occur on any common architecture.)<br class="">
         // 2. If the argument is byval, RV is not sufficiently aligned, and<br class="">
         //    we cannot force it to be sufficiently aligned.<br class="">
-        // 3. If the argument is byval, but RV is located in an address space<br class="">
-        //    different than that of the argument (0).<br class="">
-        Address Addr = RV.getAggregateAddress();<br class="">
+        // 3. If the argument is byval, but RV is not located in default<br class="">
+        //    or alloca address space.<br class="">
+        Address Addr = I->hasLValue()<br class="">
+                           ? I->getKnownLValue().<wbr class="">getAddress()<br class="">
+                           : I->getKnownRValue().<wbr class="">getAggregateAddress();<br class="">
+        llvm::Value *V = Addr.getPointer();<br class="">
         CharUnits Align = ArgInfo.getIndirectAlign();<br class="">
         const llvm::DataLayout *TD = &CGM.getDataLayout();<br class="">
-        const unsigned RVAddrSpace = Addr.getType()-><wbr class="">getAddressSpace();<br class="">
-        const unsigned ArgAddrSpace =<br class="">
-            (FirstIRArg < IRFuncTy->getNumParams()<br class="">
-                 ? IRFuncTy->getParamType(<wbr class="">FirstIRArg)-><wbr class="">getPointerAddressSpace()<br class="">
-                 : 0);<br class="">
-        if ((!ArgInfo.getIndirectByVal() && I->NeedsCopy) ||<br class="">
-            (ArgInfo.getIndirectByVal() && Addr.getAlignment() < Align &&<br class="">
-             llvm::<wbr class="">getOrEnforceKnownAlignment(<wbr class="">Addr.getPointer(),<br class="">
-                                              Align.getQuantity(), *TD)<br class="">
-               < Align.getQuantity()) ||<br class="">
-            (ArgInfo.getIndirectByVal() && (RVAddrSpace != ArgAddrSpace))) {<br class="">
+<br class="">
+        assert((FirstIRArg >= IRFuncTy->getNumParams() ||<br class="">
+                IRFuncTy->getParamType(<wbr class="">FirstIRArg)-><wbr class="">getPointerAddressSpace() ==<br class="">
+                    TD->getAllocaAddrSpace()) &&<br class="">
+               "indirect argument must be in alloca address space");<br class="">
+<br class="">
+        bool NeedCopy = false;<br class="">
+<br class="">
+        if (Addr.getAlignment() < Align &&<br class="">
+            llvm::<wbr class="">getOrEnforceKnownAlignment(V, Align.getQuantity(), *TD) <<br class="">
+                Align.getQuantity()) {<br class="">
+          NeedCopy = true;<br class="">
+        } else if (I->hasLValue()) {<br class="">
+          auto LV = I->getKnownLValue();<br class="">
+          auto AS = LV.getAddressSpace();<br class="">
+          if ((!ArgInfo.getIndirectByVal() &&<br class="">
+               (LV.getAlignment() >=<br class="">
+                getContext().<wbr class="">getTypeAlignInChars(I->Ty))) ||<br class="">
+              (ArgInfo.getIndirectByVal() &&<br class="">
+               ((AS != LangAS::Default && AS != LangAS::opencl_private &&<br class="">
+                 AS != CGM.getASTAllocaAddressSpace()<wbr class="">)))) {<br class="">
+            NeedCopy = true;<br class="">
+          }<br class="">
+        }<br class="">
+        if (NeedCopy) {<br class="">
           // Create an aligned temporary, and copy to it.<br class="">
           Address AI = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(),<br class="">
                                      "byval-temp", false);<br class="">
           IRCallArgs[FirstIRArg] = AI.getPointer();<br class="">
-          LValue Dest = MakeAddrLValue(AI, I->Ty);<br class="">
-          LValue Src = MakeAddrLValue(Addr, I->Ty);<br class="">
-          EmitAggregateCopy(Dest, Src, I->Ty, RV.isVolatileQualified());<br class="">
+          I->copyInto(*this, AI);<br class="">
         } else {<br class="">
           // Skip the extra memcpy call.<br class="">
-          IRCallArgs[FirstIRArg] = Addr.getPointer();<br class="">
+          auto *T = V->getType()-><wbr class="">getPointerElementType()-><wbr class="">getPointerTo(<br class="">
+              CGM.getDataLayout().<wbr class="">getAllocaAddrSpace());<br class="">
+          IRCallArgs[FirstIRArg] = getTargetHooks().<wbr class="">performAddrSpaceCast(<br class="">
+              *this, V, LangAS::Default, CGM.getASTAllocaAddressSpace()<wbr class="">, T,<br class="">
+              true);<br class="">
         }<br class="">
       }<br class="">
       break;<br class="">
@@ -3902,10 +3939,12 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
           ArgInfo.getDirectOffset() == 0) {<br class="">
         assert(NumIRArgs == 1);<br class="">
         llvm::Value *V;<br class="">
-        if (RV.isScalar())<br class="">
-          V = RV.getScalarVal();<br class="">
+        if (!I->isAggregate())<br class="">
+          V = I->getKnownRValue().<wbr class="">getScalarVal();<br class="">
         else<br class="">
-          V = Builder.CreateLoad(RV.<wbr class="">getAggregateAddress());<br class="">
+          V = Builder.CreateLoad(<br class="">
+              I->hasLValue() ? I->getKnownLValue().<wbr class="">getAddress()<br class="">
+                             : I->getKnownRValue().<wbr class="">getAggregateAddress());<br class="">
<br class="">
         // Implement swifterror by copying into a new swifterror argument.<br class="">
         // We'll write back in the normal path out of the call.<br class="">
@@ -3943,12 +3982,12 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
<br class="">
       // FIXME: Avoid the conversion through memory if possible.<br class="">
       Address Src = Address::invalid();<br class="">
-      if (RV.isScalar() || RV.isComplex()) {<br class="">
+      if (!I->isAggregate()) {<br class="">
         Src = CreateMemTemp(I->Ty, "coerce");<br class="">
-        LValue SrcLV = MakeAddrLValue(Src, I->Ty);<br class="">
-        EmitInitStoreOfNonAggregate(*<wbr class="">this, RV, SrcLV);<br class="">
+        I->copyInto(*this, Src);<br class="">
       } else {<br class="">
-        Src = RV.getAggregateAddress();<br class="">
+        Src = I->hasLValue() ? I->getKnownLValue().<wbr class="">getAddress()<br class="">
+                             : I->getKnownRValue().<wbr class="">getAggregateAddress();<br class="">
       }<br class="">
<br class="">
       // If the value is offset in memory, apply the offset now.<br class="">
@@ -4002,9 +4041,12 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
<br class="">
       llvm::Value *tempSize = nullptr;<br class="">
       Address addr = Address::invalid();<br class="">
-      if (RV.isAggregate()) {<br class="">
-        addr = RV.getAggregateAddress();<br class="">
+      if (I->isAggregate()) {<br class="">
+        addr = I->hasLValue() ? I->getKnownLValue().<wbr class="">getAddress()<br class="">
+                              : I->getKnownRValue().<wbr class="">getAggregateAddress();<br class="">
+<br class="">
       } else {<br class="">
+        RValue RV = I->getKnownRValue();<br class="">
         assert(RV.isScalar()); // complex should always just be direct<br class="">
<br class="">
         llvm::Type *scalarType = RV.getScalarVal()->getType();<br class="">
@@ -4041,7 +4083,7 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
<br class="">
     case ABIArgInfo::Expand:<br class="">
       unsigned IRArgPos = FirstIRArg;<br class="">
-      ExpandTypeToArgs(I->Ty, RV, IRFuncTy, IRCallArgs, IRArgPos);<br class="">
+      ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);<br class="">
       assert(IRArgPos == FirstIRArg + NumIRArgs);<br class="">
       break;<br class="">
     }<br class="">
@@ -4393,7 +4435,7 @@ RValue CodeGenFunction::EmitCall(<wbr class="">const C<br class="">
                               OffsetValue);<br class="">
     } else if (const auto *AA = TargetDecl->getAttr<<wbr class="">AllocAlignAttr>()) {<br class="">
       llvm::Value *ParamVal =<br class="">
-          CallArgs[AA->getParamIndex() - 1].RV.getScalarVal();<br class="">
+          CallArgs[AA->getParamIndex() - 1].getRValue(*this).<wbr class="">getScalarVal();<br class="">
       EmitAlignmentAssumption(Ret.<wbr class="">getScalarVal(), ParamVal);<br class="">
     }<br class="">
   }<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGCall.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGCall.h?rev=326946&r1=326945&<wbr class="">r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGCall.h (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGCall.h Wed Mar  7 13:45:40 2018<br class="">
@@ -213,12 +213,46 @@ public:<br class="">
   };<br class="">
<br class="">
   struct CallArg {<br class="">
-    RValue RV;<br class="">
+  private:<br class="">
+    union {<br class="">
+      RValue RV;<br class="">
+      LValue LV; /// The argument is semantically a load from this l-value.<br class="">
+    };<br class="">
+    bool HasLV;<br class="">
+<br class="">
+    /// A data-flow flag to make sure getRValue and/or copyInto are not<br class="">
+    /// called twice for duplicated IR emission.<br class="">
+    mutable bool IsUsed;<br class="">
+<br class="">
+  public:<br class="">
     QualType Ty;<br class="">
-    bool NeedsCopy;<br class="">
-    CallArg(RValue rv, QualType ty, bool needscopy)<br class="">
-    : RV(rv), Ty(ty), NeedsCopy(needscopy)<br class="">
-    { }<br class="">
+    CallArg(RValue rv, QualType ty)<br class="">
+        : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {}<br class="">
+    CallArg(LValue lv, QualType ty)<br class="">
+        : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {}<br class="">
+    bool hasLValue() const { return HasLV; }<br class="">
+    QualType getType() const { return Ty; }<br class="">
+<br class="">
+    /// \returns an independent RValue. If the CallArg contains an LValue,<br class="">
+    /// a temporary copy is returned.<br class="">
+    RValue getRValue(CodeGenFunction &CGF) const;<br class="">
+<br class="">
+    LValue getKnownLValue() const {<br class="">
+      assert(HasLV && !IsUsed);<br class="">
+      return LV;<br class="">
+    }<br class="">
+    RValue getKnownRValue() const {<br class="">
+      assert(!HasLV && !IsUsed);<br class="">
+      return RV;<br class="">
+    }<br class="">
+    void setRValue(RValue _RV) {<br class="">
+      assert(!HasLV);<br class="">
+      RV = _RV;<br class="">
+    }<br class="">
+<br class="">
+    bool isAggregate() const { return HasLV || RV.isAggregate(); }<br class="">
+<br class="">
+    void copyInto(CodeGenFunction &CGF, Address A) const;<br class="">
   };<br class="">
<br class="">
   /// CallArgList - Type for representing both the value and type of<br class="">
@@ -248,8 +282,10 @@ public:<br class="">
       llvm::Instruction *IsActiveIP;<br class="">
     };<br class="">
<br class="">
-    void add(RValue rvalue, QualType type, bool needscopy = false) {<br class="">
-      push_back(CallArg(rvalue, type, needscopy));<br class="">
+    void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); }<br class="">
+<br class="">
+    void addUncopiedAggregate(LValue LV, QualType type) {<br class="">
+      push_back(CallArg(LV, type));<br class="">
     }<br class="">
<br class="">
     /// Add all the arguments from another CallArgList to this one. After doing<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGClass.<wbr class="">cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGClass.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGClass.<wbr class="">cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGClass.<wbr class="">cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -2077,7 +2077,8 @@ void CodeGenFunction::<wbr class="">EmitCXXConstructor<br class="">
     assert(Args.size() == 2 && "unexpected argcount for trivial ctor");<br class="">
<br class="">
     QualType SrcTy = D->getParamDecl(0)->getType().<wbr class="">getNonReferenceType();<br class="">
-    Address Src(Args[1].RV.getScalarVal(), getNaturalTypeAlignment(SrcTy)<wbr class="">);<br class="">
+    Address Src(Args[1].getRValue(*this).<wbr class="">getScalarVal(),<br class="">
+                getNaturalTypeAlignment(SrcTy)<wbr class="">);<br class="">
     LValue SrcLVal = MakeAddrLValue(Src, SrcTy);<br class="">
     QualType DestTy = getContext().getTypeDeclType(<wbr class="">ClassDecl);<br class="">
     LValue DestLVal = MakeAddrLValue(This, DestTy);<br class="">
@@ -2131,8 +2132,7 @@ void CodeGenFunction::<wbr class="">EmitInheritedCXXCo<br class="">
     const CXXConstructorDecl *D, bool ForVirtualBase, Address This,<br class="">
     bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {<br class="">
   CallArgList Args;<br class="">
-  CallArg ThisArg(RValue::get(This.<wbr class="">getPointer()), D->getThisType(getContext()),<br class="">
-                  /*NeedsCopy=*/false);<br class="">
+  CallArg ThisArg(RValue::get(This.<wbr class="">getPointer()), D->getThisType(getContext()));<br class="">
<br class="">
   // Forward the parameters.<br class="">
   if (InheritedFromVBase &&<br class="">
@@ -2196,7 +2196,7 @@ void CodeGenFunction::<wbr class="">EmitInlinedInherit<br class="">
   assert(Args.size() >= Params.size() && "too few arguments for call");<br class="">
   for (unsigned I = 0, N = Args.size(); I != N; ++I) {<br class="">
     if (I < Params.size() && isa<ImplicitParamDecl>(Params[<wbr class="">I])) {<br class="">
-      const RValue &RV = Args[I].RV;<br class="">
+      const RValue &RV = Args[I].getRValue(*this);<br class="">
       assert(!RV.isComplex() && "complex indirect params not supported");<br class="">
       ParamValue Val = RV.isScalar()<br class="">
                            ? ParamValue::forDirect(RV.<wbr class="">getScalarVal())<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGDecl.<wbr class="">cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGDecl.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGDecl.<wbr class="">cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGDecl.<wbr class="">cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1882,6 +1882,22 @@ void CodeGenFunction::EmitParmDecl(<wbr class="">const<br class="">
     llvm::Type *IRTy = ConvertTypeForMem(Ty)-><wbr class="">getPointerTo(AS);<br class="">
     if (DeclPtr.getType() != IRTy)<br class="">
       DeclPtr = Builder.CreateBitCast(DeclPtr, IRTy, D.getName());<br class="">
+    // Indirect argument is in alloca address space, which may be different<br class="">
+    // from the default address space.<br class="">
+    auto AllocaAS = CGM.getASTAllocaAddressSpace()<wbr class="">;<br class="">
+    auto *V = DeclPtr.getPointer();<br class="">
+    auto SrcLangAS = getLangOpts().OpenCL ? LangAS::opencl_private : AllocaAS;<br class="">
+    auto DestLangAS =<br class="">
+        getLangOpts().OpenCL ? LangAS::opencl_private : LangAS::Default;<br class="">
+    if (SrcLangAS != DestLangAS) {<br class="">
+      assert(getContext().<wbr class="">getTargetAddressSpace(<wbr class="">SrcLangAS) ==<br class="">
+             CGM.getDataLayout().<wbr class="">getAllocaAddrSpace());<br class="">
+      auto DestAS = getContext().<wbr class="">getTargetAddressSpace(<wbr class="">DestLangAS);<br class="">
+      auto *T = V->getType()-><wbr class="">getPointerElementType()-><wbr class="">getPointerTo(DestAS);<br class="">
+      DeclPtr = Address(getTargetHooks().<wbr class="">performAddrSpaceCast(<br class="">
+                            *this, V, SrcLangAS, DestLangAS, T, true),<br class="">
+                        DeclPtr.getAlignment());<br class="">
+    }<br class="">
<br class="">
     // Push a destructor cleanup for this parameter if the ABI requires it.<br class="">
     // Don't push a cleanup in a thunk for a method that will also emit a<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">CGExprCXX.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGExprCXX.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">CGExprCXX.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">CGExprCXX.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -265,7 +265,7 @@ RValue CodeGenFunction::<wbr class="">EmitCXXMemberOrO<br class="">
         // when it isn't necessary; just produce the proper effect here.<br class="">
         LValue RHS = isa<CXXOperatorCallExpr>(CE)<br class="">
                          ? MakeNaturalAlignAddrLValue(<br class="">
-                               (*RtlArgs)[0].RV.getScalarVal(<wbr class="">),<br class="">
+                               (*RtlArgs)[0].getRValue(*this)<wbr class="">.getScalarVal(),<br class="">
                                (*(CE->arg_begin() + 1))->getType())<br class="">
                          : EmitLValue(*CE->arg_begin());<br class="">
         EmitAggregateAssign(This, RHS, CE->getType());<br class="">
@@ -1490,7 +1490,7 @@ static void EnterNewDeleteCleanup(CodeGe<br class="">
                                            AllocAlign);<br class="">
     for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {<br class="">
       auto &Arg = NewArgs[I + NumNonPlacementArgs];<br class="">
-      Cleanup->setPlacementArg(I, Arg.RV, Arg.Ty);<br class="">
+      Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);<br class="">
     }<br class="">
<br class="">
     return;<br class="">
@@ -1521,8 +1521,8 @@ static void EnterNewDeleteCleanup(CodeGe<br class="">
                                               AllocAlign);<br class="">
   for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {<br class="">
     auto &Arg = NewArgs[I + NumNonPlacementArgs];<br class="">
-    Cleanup->setPlacementArg(I, DominatingValue<RValue>::save(<wbr class="">CGF, Arg.RV),<br class="">
-                             Arg.Ty);<br class="">
+    Cleanup->setPlacementArg(<br class="">
+        I, DominatingValue<RValue>::save(<wbr class="">CGF, Arg.getRValue(CGF)), Arg.Ty);<br class="">
   }<br class="">
<br class="">
   CGF.initFullExprCleanup();<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">CGGPUBuiltin.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGGPUBuiltin.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGGPUBuiltin.cpp?rev=326946&<wbr class="">r1=326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">CGGPUBuiltin.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">CGGPUBuiltin.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -83,8 +83,9 @@ CodeGenFunction::<wbr class="">EmitNVPTXDevicePrintfCa<br class="">
                /* ParamsToSkip = */ 0);<br class="">
<br class="">
   // We don't know how to emit non-scalar varargs.<br class="">
-  if (std::any_of(Args.begin() + 1, Args.end(),<br class="">
-                  [](const CallArg &A) { return !A.RV.isScalar(); })) {<br class="">
+  if (std::any_of(Args.begin() + 1, Args.end(), [&](const CallArg &A) {<br class="">
+        return !A.getRValue(*this).isScalar()<wbr class="">;<br class="">
+      })) {<br class="">
     CGM.ErrorUnsupported(E, "non-scalar arg to printf");<br class="">
     return RValue::get(llvm::ConstantInt:<wbr class="">:get(IntTy, 0));<br class="">
   }<br class="">
@@ -97,7 +98,7 @@ CodeGenFunction::<wbr class="">EmitNVPTXDevicePrintfCa<br class="">
   } else {<br class="">
     llvm::SmallVector<llvm::Type *, 8> ArgTypes;<br class="">
     for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)<br class="">
-      ArgTypes.push_back(Args[I].RV.<wbr class="">getScalarVal()->getType());<br class="">
+      ArgTypes.push_back(Args[I].<wbr class="">getRValue(*this).getScalarVal(<wbr class="">)->getType());<br class="">
<br class="">
     // Using llvm::StructType is correct only because printf doesn't accept<br class="">
     // aggregates.  If we had to handle aggregates here, we'd have to manually<br class="">
@@ -109,7 +110,7 @@ CodeGenFunction::<wbr class="">EmitNVPTXDevicePrintfCa<br class="">
<br class="">
     for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {<br class="">
       llvm::Value *P = Builder.CreateStructGEP(<wbr class="">AllocaTy, Alloca, I - 1);<br class="">
-      llvm::Value *Arg = Args[I].RV.getScalarVal();<br class="">
+      llvm::Value *Arg = Args[I].getRValue(*this).<wbr class="">getScalarVal();<br class="">
       Builder.CreateAlignedStore(<wbr class="">Arg, P, DL.getPrefTypeAlignment(Arg-><wbr class="">getType()));<br class="">
     }<br class="">
     BufferPtr = Builder.CreatePointerCast(<wbr class="">Alloca, llvm::Type::getInt8PtrTy(Ctx))<wbr class="">;<br class="">
@@ -117,6 +118,6 @@ CodeGenFunction::<wbr class="">EmitNVPTXDevicePrintfCa<br class="">
<br class="">
   // Invoke vprintf and return.<br class="">
   llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.<wbr class="">getModule());<br class="">
-  return RValue::get(<br class="">
-      Builder.CreateCall(<wbr class="">VprintfFunc, {Args[0].RV.getScalarVal(), BufferPtr}));<br class="">
+  return RValue::get(Builder.<wbr class="">CreateCall(<br class="">
+      VprintfFunc, {Args[0].getRValue(*this).<wbr class="">getScalarVal(), BufferPtr}));<br class="">
 }<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">CGObjCGNU.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGObjCGNU.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">CGObjCGNU.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">CGObjCGNU.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1441,7 +1441,7 @@ CGObjCGNU::<wbr class="">GenerateMessageSend(CodeGenFu<br class="">
   }<br class="">
<br class="">
   // Reset the receiver in case the lookup modified it<br class="">
-  ActualArgs[0] = CallArg(RValue::get(Receiver), ASTIdTy, false);<br class="">
+  ActualArgs[0] = CallArg(RValue::get(Receiver), ASTIdTy);<br class="">
<br class="">
   imp = EnforceType(Builder, imp, MSI.MessengerType);<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">CGObjCMac.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGObjCMac.cpp?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">CGObjCMac.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">CGObjCMac.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1708,7 +1708,7 @@ struct NullReturnState {<br class="">
            e = Method->param_end(); i != e; ++i, ++I) {<br class="">
         const ParmVarDecl *ParamDecl = (*i);<br class="">
         if (ParamDecl->hasAttr<<wbr class="">NSConsumedAttr>()) {<br class="">
-          RValue RV = I->RV;<br class="">
+          RValue RV = I->getRValue(CGF);<br class="">
           assert(RV.isScalar() &&<br class="">
                  "NullReturnState::complete - arg not on object");<br class="">
           CGF.EmitARCRelease(RV.<wbr class="">getScalarVal(), ARCImpreciseLifetime);<br class="">
@@ -7071,7 +7071,7 @@ CGObjCNonFragileABIMac::<wbr class="">EmitVTableMessag<br class="">
             CGF.getPointerAlign());<br class="">
<br class="">
   // Update the message ref argument.<br class="">
-  args[1].RV = RValue::get(mref.getPointer())<wbr class="">;<br class="">
+  args[1].setRValue(RValue::get(<wbr class="">mref.getPointer()));<br class="">
<br class="">
   // Load the function to call from the message ref table.<br class="">
   Address calleeAddr =<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">CodeGenFunction.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CodeGenFunction.h?rev=326946&<wbr class="">r1=326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">CodeGenFunction.h (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">CodeGenFunction.h Wed Mar  7 13:45:40 2018<br class="">
@@ -3899,10 +3899,10 @@ private:<br class="">
   void ExpandTypeFromArgs(QualType Ty, LValue Dst,<br class="">
                           SmallVectorImpl<llvm::Value *>::iterator &AI);<br class="">
<br class="">
-  /// ExpandTypeToArgs - Expand an RValue \arg RV, with the LLVM type for \arg<br class="">
+  /// ExpandTypeToArgs - Expand an CallArg \arg Arg, with the LLVM type for \arg<br class="">
   /// Ty, into individual arguments on the provided vector \arg IRCallArgs,<br class="">
   /// starting at index \arg IRCallArgPos. See ABIArgInfo::Expand.<br class="">
-  void ExpandTypeToArgs(QualType Ty, RValue RV, llvm::FunctionType *IRFuncTy,<br class="">
+  void ExpandTypeToArgs(QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,<br class="">
                         SmallVectorImpl<llvm::Value *> &IRCallArgs,<br class="">
                         unsigned &IRCallArgPos);<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp?rev=326946&<wbr class="">r1=326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">ItaniumCXXABI.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1474,8 +1474,7 @@ CGCXXABI::AddedStructorArgs ItaniumCXXAB<br class="">
   llvm::Value *VTT =<br class="">
       CGF.GetVTTParameter(<wbr class="">GlobalDecl(D, Type), ForVirtualBase, Delegating);<br class="">
   QualType VTTTy = getContext().getPointerType(<wbr class="">getContext().VoidPtrTy);<br class="">
-  Args.insert(Args.begin() + 1,<br class="">
-              CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false));<br class="">
+  Args.insert(Args.begin() + 1, CallArg(RValue::get(VTT), VTTTy));<br class="">
   return AddedStructorArgs::prefix(1);  // Added one arg.<br class="">
 }<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp?rev=<wbr class="">326946&r1=326945&r2=326946&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/<wbr class="">MicrosoftCXXABI.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -1537,8 +1537,7 @@ CGCXXABI::AddedStructorArgs MicrosoftCXX<br class="">
   }<br class="">
   RValue RV = RValue::get(MostDerivedArg);<br class="">
   if (FPT->isVariadic()) {<br class="">
-    Args.insert(Args.begin() + 1,<br class="">
-                CallArg(RV, getContext().IntTy, /*needscopy=*/false));<br class="">
+    Args.insert(Args.begin() + 1, CallArg(RV, getContext().IntTy));<br class="">
     return AddedStructorArgs::prefix(1);<br class="">
   }<br class="">
   Args.add(RV, getContext().IntTy);<br class="">
<br class="">
Added: cfe/trunk/test/CodeGenCXX/<wbr class="">amdgcn-func-arg.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/amdgcn-func-arg.cpp?rev=326946&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenCXX/amdgcn-func-arg.<wbr class="">cpp?rev=326946&view=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/CodeGenCXX/<wbr class="">amdgcn-func-arg.cpp (added)<br class="">
+++ cfe/trunk/test/CodeGenCXX/<wbr class="">amdgcn-func-arg.cpp Wed Mar  7 13:45:40 2018<br class="">
@@ -0,0 +1,94 @@<br class="">
+// RUN: %clang_cc1 -O0 -triple amdgcn -emit-llvm %s -o - | FileCheck %s<br class="">
+<br class="">
+class A {<br class="">
+public:<br class="">
+  int x;<br class="">
+  A():x(0) {}<br class="">
+  ~A() {}<br class="">
+};<br class="">
+<br class="">
+class B {<br class="">
+int x[100];<br class="">
+};<br class="">
+<br class="">
+A g_a;<br class="">
+B g_b;<br class="">
+<br class="">
+void func_with_ref_arg(A &a);<br class="">
+void func_with_ref_arg(B &b);<br class="">
+<br class="">
+// CHECK-LABEL: define void @_Z22func_with_indirect_arg1A(<wbr class="">%class.A addrspace(5)* %a)<br class="">
+// CHECK:  %p = alloca %class.A*, align 8, addrspace(5)<br class="">
+// CHECK:  %[[r1:.+]] = addrspacecast %class.A* addrspace(5)* %p to %class.A**<br class="">
+// CHECK:  %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %a to %class.A*<br class="">
+// CHECK:  store %class.A* %[[r0]], %class.A** %[[r1]], align 8<br class="">
+void func_with_indirect_arg(A a) {<br class="">
+  A *p = &a;<br class="">
+}<br class="">
+<br class="">
+// CHECK-LABEL: define void @_Z22test_indirect_arg_autov()<br class="">
+// CHECK:  %a = alloca %class.A, align 4, addrspace(5)<br class="">
+// CHECK:  %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %a to %class.A*<br class="">
+// CHECK:  %agg.tmp = alloca %class.A, align 4, addrspace(5)<br class="">
+// CHECK:  %[[r1:.+]] = addrspacecast %class.A addrspace(5)* %agg.tmp to %class.A*<br class="">
+// CHECK:  call void @_ZN1AC1Ev(%class.A* %[[r0]])<br class="">
+// CHECK:  call void @llvm.memcpy.p0i8.p0i8.i64<br class="">
+// CHECK:  %[[r4:.+]] = addrspacecast %class.A* %[[r1]] to %class.A addrspace(5)*<br class="">
+// CHECK:  call void @_Z22func_with_indirect_arg1A(<wbr class="">%class.A addrspace(5)* %[[r4]])<br class="">
+// CHECK:  call void @_ZN1AD1Ev(%class.A* %[[r1]])<br class="">
+// CHECK:  call void @_Z17func_with_ref_argR1A(%<wbr class="">class.A* dereferenceable(4) %[[r0]])<br class="">
+// CHECK:  call void @_ZN1AD1Ev(%class.A* %[[r0]])<br class="">
+void test_indirect_arg_auto() {<br class="">
+  A a;<br class="">
+  func_with_indirect_arg(a);<br class="">
+  func_with_ref_arg(a);<br class="">
+}<br class="">
+<br class="">
+// CHECK: define void @_Z24test_indirect_arg_<wbr class="">globalv()<br class="">
+// CHECK:  %agg.tmp = alloca %class.A, align 4, addrspace(5)<br class="">
+// CHECK:  %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %agg.tmp to %class.A*<br class="">
+// CHECK:  call void @llvm.memcpy.p0i8.p0i8.i64<br class="">
+// CHECK:  %[[r2:.+]] = addrspacecast %class.A* %[[r0]] to %class.A addrspace(5)*<br class="">
+// CHECK:  call void @_Z22func_with_indirect_arg1A(<wbr class="">%class.A addrspace(5)* %[[r2]])<br class="">
+// CHECK:  call void @_ZN1AD1Ev(%class.A* %[[r0]])<br class="">
+// CHECK:  call void @_Z17func_with_ref_argR1A(%<wbr class="">class.A* dereferenceable(4) addrspacecast (%class.A addrspace(1)* @g_a to %class.A*))<br class="">
+void test_indirect_arg_global() {<br class="">
+  func_with_indirect_arg(g_a);<br class="">
+  func_with_ref_arg(g_a);<br class="">
+}<br class="">
+<br class="">
+// CHECK-LABEL: define void @_Z19func_with_byval_arg1B(%<wbr class="">class.B addrspace(5)* byval align 4 %b)<br class="">
+// CHECK:  %p = alloca %class.B*, align 8, addrspace(5)<br class="">
+// CHECK:  %[[r1:.+]] = addrspacecast %class.B* addrspace(5)* %p to %class.B**<br class="">
+// CHECK:  %[[r0:.+]] = addrspacecast %class.B addrspace(5)* %b to %class.B*<br class="">
+// CHECK:  store %class.B* %[[r0]], %class.B** %[[r1]], align 8<br class="">
+void func_with_byval_arg(B b) {<br class="">
+  B *p = &b;<br class="">
+}<br class="">
+<br class="">
+// CHECK-LABEL: define void @_Z19test_byval_arg_autov()<br class="">
+// CHECK:  %b = alloca %class.B, align 4, addrspace(5)<br class="">
+// CHECK:  %[[r0:.+]] = addrspacecast %class.B addrspace(5)* %b to %class.B*<br class="">
+// CHECK:  %agg.tmp = alloca %class.B, align 4, addrspace(5)<br class="">
+// CHECK:  %[[r1:.+]] = addrspacecast %class.B addrspace(5)* %agg.tmp to %class.B*<br class="">
+// CHECK:  call void @llvm.memcpy.p0i8.p0i8.i64<br class="">
+// CHECK:  %[[r4:.+]] = addrspacecast %class.B* %[[r1]] to %class.B addrspace(5)*<br class="">
+// CHECK:  call void @_Z19func_with_byval_arg1B(%<wbr class="">class.B addrspace(5)* byval align 4 %[[r4]])<br class="">
+// CHECK:  call void @_Z17func_with_ref_argR1B(%<wbr class="">class.B* dereferenceable(400) %[[r0]])<br class="">
+void test_byval_arg_auto() {<br class="">
+  B b;<br class="">
+  func_with_byval_arg(b);<br class="">
+  func_with_ref_arg(b);<br class="">
+}<br class="">
+<br class="">
+// CHECK-LABEL: define void @_Z21test_byval_arg_globalv()<br class="">
+// CHECK:  %agg.tmp = alloca %class.B, align 4, addrspace(5)<br class="">
+// CHECK:  %[[r0:.+]] = addrspacecast %class.B addrspace(5)* %agg.tmp to %class.B*<br class="">
+// CHECK:  call void @llvm.memcpy.p0i8.p0i8.i64<br class="">
+// CHECK:  %[[r2:.+]] = addrspacecast %class.B* %[[r0]] to %class.B addrspace(5)*<br class="">
+// CHECK:  call void @_Z19func_with_byval_arg1B(%<wbr class="">class.B addrspace(5)* byval align 4 %[[r2]])<br class="">
+// CHECK:  call void @_Z17func_with_ref_argR1B(%<wbr class="">class.B* dereferenceable(400) addrspacecast (%class.B addrspace(1)* @g_b to %class.B*))<br class="">
+void test_byval_arg_global() {<br class="">
+  func_with_byval_arg(g_b);<br class="">
+  func_with_ref_arg(g_b);<br class="">
+}<br class="">
<br class="">
Modified: cfe/trunk/test/CodeGenOpenCL/<a href="http://addr-space-struct-arg.cl/" rel="noreferrer" target="_blank" class="">a<wbr class="">ddr-space-struct-arg.cl</a><br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/addr-space-struct-arg.cl?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenOpenCL/addr-space-<wbr class="">struct-arg.cl?rev=326946&r1=<wbr class="">326945&r2=326946&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/CodeGenOpenCL/<a href="http://addr-space-struct-arg.cl/" rel="noreferrer" target="_blank" class="">a<wbr class="">ddr-space-struct-arg.cl</a> (original)<br class="">
+++ cfe/trunk/test/CodeGenOpenCL/<a href="http://addr-space-struct-arg.cl/" rel="noreferrer" target="_blank" class="">a<wbr class="">ddr-space-struct-arg.cl</a> Wed Mar  7 13:45:40 2018<br class="">
@@ -1,5 +1,6 @@<br class="">
 // RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=COM,X86 %s<br class="">
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple amdgcn-amdhsa-amd | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN %s<br class="">
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN %s<br class="">
+// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -finclude-default-header -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN,<wbr class="">AMDGCN20 %s<br class="">
<br class="">
 typedef struct {<br class="">
   int cells[9];<br class="">
@@ -35,6 +36,9 @@ struct LargeStructTwoMember {<br class="">
   int2 y[20];<br class="">
 };<br class="">
<br class="">
+#if __OPENCL_C_VERSION__ >= 200<br class="">
+struct LargeStructOneMember g_s;<br class="">
+#endif<br class="">
<br class="">
 // X86-LABEL: define void @foo(%struct.Mat4X4* noalias sret %agg.result, %struct.Mat3X3* byval align 4 %in)<br class="">
 // AMDGCN-LABEL: define %struct.Mat4X4 @foo([9 x i32] %in.coerce)<br class="">
@@ -80,10 +84,42 @@ void FuncOneMember(struct StructOneMembe<br class="">
 }<br class="">
<br class="">
 // AMDGCN-LABEL: define void @FuncOneLargeMember(%struct.<wbr class="">LargeStructOneMember addrspace(5)* byval align 8 %u)<br class="">
+// AMDGCN-NOT: addrspacecast<br class="">
+// AMDGCN:   store <2 x i32> %{{.*}}, <2 x i32> addrspace(5)*<br class="">
 void FuncOneLargeMember(struct LargeStructOneMember u) {<br class="">
   u.x[0] = (int2)(0, 0);<br class="">
 }<br class="">
<br class="">
+// AMDGCN20-LABEL: define void @test_indirect_arg_globl()<br class="">
+// AMDGCN20:  %[[byval_temp:.*]] = alloca %struct.LargeStructOneMember, align 8, addrspace(5)<br class="">
+// AMDGCN20:  %[[r0:.*]] = bitcast %struct.LargeStructOneMember addrspace(5)* %[[byval_temp]] to i8 addrspace(5)*<br class="">
+// AMDGCN20:  call void @llvm.memcpy.p5i8.p1i8.i64(i8 addrspace(5)* align 8 %[[r0]], i8 addrspace(1)* align 8 bitcast (%struct.LargeStructOneMember addrspace(1)* @g_s to i8 addrspace(1)*), i64 800, i1 false)<br class="">
+// AMDGCN20:  call void @FuncOneLargeMember(%struct.<wbr class="">LargeStructOneMember addrspace(5)* byval align 8 %[[byval_temp]])<br class="">
+#if __OPENCL_C_VERSION__ >= 200<br class="">
+void test_indirect_arg_globl(void) {<br class="">
+  FuncOneLargeMember(g_s);<br class="">
+}<br class="">
+#endif<br class="">
+<br class="">
+// AMDGCN-LABEL: define amdgpu_kernel void @test_indirect_arg_local()<br class="">
+// AMDGCN: %[[byval_temp:.*]] = alloca %struct.LargeStructOneMember, align 8, addrspace(5)<br class="">
+// AMDGCN: %[[r0:.*]] = bitcast %struct.LargeStructOneMember addrspace(5)* %[[byval_temp]] to i8 addrspace(5)*<br class="">
+// AMDGCN: call void @llvm.memcpy.p5i8.p3i8.i64(i8 addrspace(5)* align 8 %[[r0]], i8 addrspace(3)* align 8 bitcast (%struct.LargeStructOneMember addrspace(3)* @test_indirect_arg_local.l_s to i8 addrspace(3)*), i64 800, i1 false)<br class="">
+// AMDGCN: call void @FuncOneLargeMember(%struct.<wbr class="">LargeStructOneMember addrspace(5)* byval align 8 %[[byval_temp]])<br class="">
+kernel void test_indirect_arg_local(void) {<br class="">
+  local struct LargeStructOneMember l_s;<br class="">
+  FuncOneLargeMember(l_s);<br class="">
+}<br class="">
+<br class="">
+// AMDGCN-LABEL: define void @test_indirect_arg_private()<br class="">
+// AMDGCN: %[[p_s:.*]] = alloca %struct.LargeStructOneMember, align 8, addrspace(5)<br class="">
+// AMDGCN-NOT: @llvm.memcpy<br class="">
+// AMDGCN-NEXT: call void @FuncOneLargeMember(%struct.<wbr class="">LargeStructOneMember addrspace(5)* byval align 8 %[[p_s]])<br class="">
+void test_indirect_arg_private(<wbr class="">void) {<br class="">
+  struct LargeStructOneMember p_s;<br class="">
+  FuncOneLargeMember(p_s);<br class="">
+}<br class="">
+<br class="">
 // AMDGCN-LABEL: define amdgpu_kernel void @KernelOneMember<br class="">
 // AMDGCN-SAME:  (<2 x i32> %[[u_coerce:.*]])<br class="">
 // AMDGCN:  %[[u:.*]] = alloca %struct.StructOneMember, align 8, addrspace(5)<br class="">
@@ -112,7 +148,6 @@ void FuncLargeTwoMember(struct LargeStru<br class="">
   u.y[0] = (int2)(0, 0);<br class="">
 }<br class="">
<br class="">
-<br class="">
 // AMDGCN-LABEL: define amdgpu_kernel void @KernelTwoMember<br class="">
 // AMDGCN-SAME:  (%struct.StructTwoMember %[[u_coerce:.*]])<br class="">
 // AMDGCN:  %[[u:.*]] = alloca %struct.StructTwoMember, align 8, addrspace(5)<br class="">
<br class="">
Modified: cfe/trunk/test/CodeGenOpenCL/<a href="http://byval.cl/" rel="noreferrer" target="_blank" class="">b<wbr class="">yval.cl</a><br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/byval.cl?rev=326946&r1=326945&r2=326946&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenOpenCL/byval.cl?rev=<wbr class="">326946&r1=326945&r2=326946&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/test/CodeGenOpenCL/<a href="http://byval.cl/" rel="noreferrer" target="_blank" class="">b<wbr class="">yval.cl</a> (original)<br class="">
+++ cfe/trunk/test/CodeGenOpenCL/<a href="http://byval.cl/" rel="noreferrer" target="_blank" class="">b<wbr class="">yval.cl</a> Wed Mar  7 13:45:40 2018<br class="">
@@ -1,5 +1,4 @@<br class="">
 // RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s<br class="">
-// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---opencl %s | FileCheck %s<br class="">
<br class="">
 struct A {<br class="">
   int x[100];<br class="">
<br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>