> On Mar 9, 2018, at 8:51 PM, Richard Smith <rich...@metafoo.co.uk> wrote:
> 
> Hi,
> 
> 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.
> 
> Given that this introduces a regression (due to stack overflow), I've 
> reverted in r327195. Sorry about that.

Seems reasonable.

The right short-term fix is probably a combination of the following:
  - put a little bit of effort into packing LValue (using fewer than 64 bits 
for the alignment and packing the bit-fields, I think)
  - drop the inline argument count to something like 8, which should still 
capture the vast majority of calls.

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.

> The program it broke looked something like this:
> 
> struct VectorBuilder {
>   VectorBuilder &operator,(int);
> };
> void f() {
>   VectorBuilder(),
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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,
>   
> 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;
> }
> 
> using Eigen's somewhat-ridiculous comma initializer technique 
> (https://eigen.tuxfamily.org/dox/group__TutorialAdvancedInitialization.html 
> <https://eigen.tuxfamily.org/dox/group__TutorialAdvancedInitialization.html>) 
> to build an approx 40 x 40 array.

> 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.

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.

John.

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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to