[clang] [clang][CodeGen] Return RValue from `EmitVAArg` (PR #94635)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 14 08:32:29 PDT 2024


https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/94635

>From bdb7aba4927dc61fbd8ef6896b6b4335fe5bac6d Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Thu, 6 Jun 2024 08:46:11 -0700
Subject: [PATCH 01/10] [clang][CodeGen] Return RValue from `EmitVAArg`

This should simplify handling of resulting value by the callers.
---
 clang/lib/CodeGen/CGCall.cpp                  | 29 +++++++++++++++----
 clang/lib/CodeGen/CGExprAgg.cpp               |  6 ++--
 clang/lib/CodeGen/CGExprComplex.cpp           |  7 ++---
 clang/lib/CodeGen/CGExprScalar.cpp            | 21 ++------------
 clang/lib/CodeGen/CodeGenFunction.h           |  2 +-
 .../CodeGen/PowerPC/aix32-complex-varargs.c   | 18 +++++-------
 6 files changed, 40 insertions(+), 43 deletions(-)

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 97449a5e51e73..8a6b9797b6a1d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5988,12 +5988,29 @@ CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
 
 /* VarArg handling */
 
-Address CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) {
-  VAListAddr = VE->isMicrosoftABI()
-                 ? EmitMSVAListRef(VE->getSubExpr())
-                 : EmitVAListRef(VE->getSubExpr());
+RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) {
+  VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr())
+                                    : EmitVAListRef(VE->getSubExpr());
   QualType Ty = VE->getType();
+  Address ResAddr = Address::invalid();
   if (VE->isMicrosoftABI())
-    return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty);
-  return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty);
+    ResAddr = CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty);
+  else
+    ResAddr = CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty);
+
+  switch (getEvaluationKind(VE->getType())) {
+  case TEK_Scalar: {
+    llvm::Value *Load = Builder.CreateLoad(ResAddr);
+    return RValue::get(Load);
+  }
+  case TEK_Complex: {
+    llvm::Value *Load = Builder.CreateLoad(ResAddr);
+    llvm::Value *Real = Builder.CreateExtractValue(Load, 0);
+    llvm::Value *Imag = Builder.CreateExtractValue(Load, 1);
+    return RValue::getComplex(std::make_pair(Real, Imag));
+  }
+  case TEK_Aggregate:
+    return RValue::getAggregate(ResAddr);
+  }
+  llvm_unreachable("bad evaluation kind");
 }
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 5b2039af6128b..41688c1f861ed 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1328,15 +1328,15 @@ void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
 
 void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   Address ArgValue = Address::invalid();
-  Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
+  RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);
 
   // If EmitVAArg fails, emit an error.
-  if (!ArgPtr.isValid()) {
+  if (!ArgValue.isValid()) {
     CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
     return;
   }
 
-  EmitFinalDestCopy(VE->getType(), CGF.MakeAddrLValue(ArgPtr, VE->getType()));
+  EmitFinalDestCopy(VE->getType(), ArgPtr);
 }
 
 void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 9ef73e36f66f3..3b3f026eaaeac 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -1449,9 +1449,9 @@ ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
 
 ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
   Address ArgValue = Address::invalid();
-  Address ArgPtr = CGF.EmitVAArg(E, ArgValue);
+  RValue RV = CGF.EmitVAArg(E, ArgValue);
 
-  if (!ArgPtr.isValid()) {
+  if (!ArgValue.isValid()) {
     CGF.ErrorUnsupported(E, "complex va_arg expression");
     llvm::Type *EltTy =
       CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType());
@@ -1459,8 +1459,7 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
     return ComplexPairTy(U, U);
   }
 
-  return EmitLoadOfLValue(CGF.MakeAddrLValue(ArgPtr, E->getType()),
-                          E->getExprLoc());
+  return RV.getComplexVal();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 58f0a3113b4f8..53c3276dd0559 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5357,28 +5357,11 @@ Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
     CGF.EmitVariablyModifiedType(Ty);
 
   Address ArgValue = Address::invalid();
-  Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
+  RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);
 
   llvm::Type *ArgTy = ConvertType(VE->getType());
 
-  // If EmitVAArg fails, emit an error.
-  if (!ArgPtr.isValid()) {
-    CGF.ErrorUnsupported(VE, "va_arg expression");
-    return llvm::UndefValue::get(ArgTy);
-  }
-
-  // FIXME Volatility.
-  llvm::Value *Val = Builder.CreateLoad(ArgPtr);
-
-  // If EmitVAArg promoted the type, we must truncate it.
-  if (ArgTy != Val->getType()) {
-    if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
-      Val = Builder.CreateIntToPtr(Val, ArgTy);
-    else
-      Val = Builder.CreateTrunc(Val, ArgTy);
-  }
-
-  return Val;
+  return ArgPtr.getScalarVal();
 }
 
 Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 5739fbaaa9194..f74b6a76a7dce 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3016,7 +3016,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// \returns A pointer to the argument.
   // FIXME: We should be able to get rid of this method and use the va_arg
   // instruction in LLVM instead once it works well enough.
-  Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr);
+  RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr);
 
   /// emitArrayLength - Compute the length of an array, even if it's a
   /// VLA, and drill down to the base element type.
diff --git a/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c b/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c
index 6036adb7d23be..02dd071bdb744 100644
--- a/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c
+++ b/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c
@@ -11,14 +11,13 @@ void testva (int n, ...)
 // CHECK:  %[[VAR40:[A-Za-z0-9.]+]] = load ptr, ptr %[[VAR100:[A-Za-z0-9.]+]]
 // CHECK-NEXT:  %[[VAR41:[A-Za-z0-9.]+]] = getelementptr inbounds i8, ptr %[[VAR40]]
 // CHECK-NEXT:  store ptr %[[VAR41]], ptr %[[VAR100]], align 4
-// CHECK-NEXT:  %[[VAR6:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VAR40]], i32 0, i32 0
-// CHECK-NEXT:  %[[VAR7:[A-Za-z0-9.]+]] = load i32, ptr %[[VAR6]]
-// CHECK-NEXT:  %[[VAR8:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VAR40]], i32 0, i32 1
-// CHECK-NEXT:  %[[VAR9:[A-Za-z0-9.]+]] = load i32, ptr %[[VAR8]]
+// CHECK-NEXT:  %[[VAR6:[A-Za-z0-9.]+]] = load { i32, i32 }, ptr %[[VAR40]], align 4
+// CHECK-NEXT:  %[[VAR7:[A-Za-z0-9.]+]] = extractvalue { i32, i32 } %[[VAR6]], 0
+// CHECK-NEXT:  %[[VAR8:[A-Za-z0-9.]+]] = extractvalue { i32, i32 } %[[VAR6]], 1
 // CHECK-NEXT:  %[[VAR10:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VARINT:[A-Za-z0-9.]+]], i32 0, i32 0
 // CHECK-NEXT:  %[[VAR11:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VARINT]], i32 0, i32 1
 // CHECK-NEXT:  store i32 %[[VAR7]], ptr %[[VAR10]]
-// CHECK-NEXT:  store i32 %[[VAR9]], ptr %[[VAR11]]
+// CHECK-NEXT:  store i32 %[[VAR8]], ptr %[[VAR11]]
 
   _Complex short s = va_arg(ap, _Complex short);
 // CHECK:  %[[VAR50:[A-Za-z0-9.]+]] = load ptr, ptr %[[VAR100:[A-Za-z0-9.]+]]
@@ -51,12 +50,11 @@ void testva (int n, ...)
   _Complex float f = va_arg(ap, _Complex float);
 // CHECK:  %[[VAR70:[A-Za-z0-9.]+]] = getelementptr inbounds i8, ptr %[[VAR71:[A-Za-z0-9.]+]], i32 8
 // CHECK-NEXT:  store ptr %[[VAR70]], ptr %[[VAR100:[A-Za-z0-9.]+]]
-// CHECK-NEXT:  %[[VAR29:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %[[VAR71]], i32 0, i32 0
-// CHECK-NEXT:  %[[VAR30:[A-Za-z0-9.]+]] = load float, ptr %[[VAR29]]
-// CHECK-NEXT:  %[[VAR31:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %[[VAR71]], i32 0, i32 1
-// CHECK-NEXT:  %[[VAR32:[A-Za-z0-9.]+]] = load float, ptr %[[VAR31]]
+// CHECK-NEXT:  %[[VAR29:[A-Za-z0-9.]+]] = load { float, float }, ptr %[[VAR71]], align 4
+// CHECK-NEXT:  %[[VAR30:[A-Za-z0-9.]+]] = extractvalue { float, float } %[[VAR29]], 0
+// CHECK-NEXT:  %[[VAR31:[A-Za-z0-9.]+]] = extractvalue { float, float } %[[VAR29]], 1
 // CHECK-NEXT:  %[[VAR33:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %f, i32 0, i32 0
 // CHECK-NEXT:  %[[VAR34:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %f, i32 0, i32 1
 // CHECK-NEXT:  store float %[[VAR30]], ptr %[[VAR33]]
-// CHECK-NEXT:  store float %[[VAR32]], ptr %[[VAR34]]
+// CHECK-NEXT:  store float %[[VAR31]], ptr %[[VAR34]]
 }

>From 5a03b2a01a108708e953854f0b451cc49d6074d2 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Mon, 10 Jun 2024 07:25:57 -0700
Subject: [PATCH 02/10] Update target code

---
 clang/lib/CodeGen/ABIInfo.cpp                 |  6 +--
 clang/lib/CodeGen/ABIInfo.h                   | 11 ++---
 clang/lib/CodeGen/ABIInfoImpl.cpp             | 11 +++--
 clang/lib/CodeGen/ABIInfoImpl.h               | 12 ++---
 clang/lib/CodeGen/CGCall.cpp                  | 22 +--------
 clang/lib/CodeGen/CGExpr.cpp                  | 13 +++++
 clang/lib/CodeGen/CGExprAgg.cpp               | 30 +++++++-----
 clang/lib/CodeGen/CGExprScalar.cpp            |  2 -
 clang/lib/CodeGen/CodeGenFunction.h           | 10 ++++
 clang/lib/CodeGen/Targets/AArch64.cpp         | 47 ++++++++++---------
 clang/lib/CodeGen/Targets/AMDGPU.cpp          |  8 ++--
 clang/lib/CodeGen/Targets/ARC.cpp             |  8 ++--
 clang/lib/CodeGen/Targets/ARM.cpp             | 11 +++--
 clang/lib/CodeGen/Targets/CSKY.cpp            | 11 +++--
 clang/lib/CodeGen/Targets/Hexagon.cpp         | 14 +++---
 clang/lib/CodeGen/Targets/LoongArch.cpp       | 16 ++++---
 clang/lib/CodeGen/Targets/MSP430.cpp          |  7 +--
 clang/lib/CodeGen/Targets/Mips.cpp            | 30 ++++++------
 clang/lib/CodeGen/Targets/NVPTX.cpp           |  8 ++--
 clang/lib/CodeGen/Targets/PNaCl.cpp           | 11 +++--
 clang/lib/CodeGen/Targets/PPC.cpp             | 39 +++++++--------
 clang/lib/CodeGen/Targets/RISCV.cpp           | 13 ++---
 clang/lib/CodeGen/Targets/Sparc.cpp           | 14 +++---
 clang/lib/CodeGen/Targets/SystemZ.cpp         | 12 ++---
 clang/lib/CodeGen/Targets/WebAssembly.cpp     |  8 ++--
 clang/lib/CodeGen/Targets/X86.cpp             | 41 ++++++++--------
 clang/lib/CodeGen/Targets/XCore.cpp           | 10 ++--
 .../CodeGen/PowerPC/aix32-complex-varargs.c   | 18 +++----
 clang/test/CodeGen/arm-abi-vector.c           |  2 +-
 clang/test/CodeGen/mips-varargs.c             | 13 +----
 30 files changed, 236 insertions(+), 222 deletions(-)

diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp
index acaae9f8c3d84..623957ae3697b 100644
--- a/clang/lib/CodeGen/ABIInfo.cpp
+++ b/clang/lib/CodeGen/ABIInfo.cpp
@@ -39,9 +39,9 @@ bool ABIInfo::isOHOSFamily() const {
   return getTarget().getTriple().isOHOSFamily();
 }
 
-Address ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                             QualType Ty) const {
-  return Address::invalid();
+RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                            QualType Ty) const {
+  return RValue::getIgnored();
 }
 
 bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h
index ff4ae44a42c33..4ea12eed85261 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/lib/CodeGen/ABIInfo.h
@@ -34,6 +34,7 @@ class CGCXXABI;
 class CGFunctionInfo;
 class CodeGenFunction;
 class CodeGenTypes;
+class RValue;
 
 // FIXME: All of this stuff should be part of the target interface
 // somehow. It is currently here because it is not clear how to factor
@@ -75,18 +76,16 @@ class ABIInfo {
   // the ABI information any lower than CodeGen. Of course, for
   // VAArg handling it has to be at this level; there is no way to
   // abstract this out.
-  virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF,
-                                     CodeGen::Address VAListAddr,
-                                     QualType Ty) const = 0;
+  virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF,
+                           CodeGen::Address VAListAddr, QualType Ty) const = 0;
 
   bool isAndroid() const;
   bool isOHOSFamily() const;
 
   /// Emit the target dependent code to load a value of
   /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
-  virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
-                                       CodeGen::Address VAListAddr,
-                                       QualType Ty) const;
+  virtual RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
+                             CodeGen::Address VAListAddr, QualType Ty) const;
 
   virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
 
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index eb627a3c043bc..5a41a16fb413b 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -71,9 +71,10 @@ void DefaultABIInfo::computeInfo(CGFunctionInfo &FI) const {
     I.info = classifyArgumentType(I.type);
 }
 
-Address DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                  QualType Ty) const {
-  return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty));
+RValue DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                 QualType Ty) const {
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
+      EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty));
 }
 
 ABIArgInfo CodeGen::coerceToIntArray(QualType Ty, ASTContext &Context,
@@ -199,7 +200,7 @@ CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
   return Addr.withElementType(DirectTy);
 }
 
-Address CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
+RValue CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                   QualType ValueTy, bool IsIndirect,
                                   TypeInfoChars ValueInfo,
                                   CharUnits SlotSizeAndAlign,
@@ -230,7 +231,7 @@ Address CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
     Addr = Address(CGF.Builder.CreateLoad(Addr), ElementTy, ValueInfo.Align);
   }
 
-  return Addr;
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, ValueTy));
 }
 
 Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h
index afde08ba100cf..f4af4beff727f 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.h
+++ b/clang/lib/CodeGen/ABIInfoImpl.h
@@ -29,8 +29,8 @@ class DefaultABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 // Helper for coercing an aggregate argument or return value into an integer
@@ -112,10 +112,10 @@ Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
 /// \param ForceRightAdjust - Default is false. On big-endian platform and
 ///   if the argument is smaller than a slot, set this flag will force
 ///   right-adjust the argument in its slot irrespective of the type.
-Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                         QualType ValueTy, bool IsIndirect,
-                         TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign,
-                         bool AllowHigherAlign, bool ForceRightAdjust = false);
+RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                        QualType ValueTy, bool IsIndirect,
+                        TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign,
+                        bool AllowHigherAlign, bool ForceRightAdjust = false);
 
 Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
                      llvm::BasicBlock *Block1, Address Addr2,
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8a6b9797b6a1d..d23e2aae4c968 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5992,25 +5992,7 @@ RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) {
   VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr())
                                     : EmitVAListRef(VE->getSubExpr());
   QualType Ty = VE->getType();
-  Address ResAddr = Address::invalid();
   if (VE->isMicrosoftABI())
-    ResAddr = CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty);
-  else
-    ResAddr = CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty);
-
-  switch (getEvaluationKind(VE->getType())) {
-  case TEK_Scalar: {
-    llvm::Value *Load = Builder.CreateLoad(ResAddr);
-    return RValue::get(Load);
-  }
-  case TEK_Complex: {
-    llvm::Value *Load = Builder.CreateLoad(ResAddr);
-    llvm::Value *Real = Builder.CreateExtractValue(Load, 0);
-    llvm::Value *Imag = Builder.CreateExtractValue(Load, 1);
-    return RValue::getComplex(std::make_pair(Real, Imag));
-  }
-  case TEK_Aggregate:
-    return RValue::getAggregate(ResAddr);
-  }
-  llvm_unreachable("bad evaluation kind");
+    return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty);
+  return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty);
 }
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d6478cc6835d8..1d049da254f35 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2161,6 +2161,19 @@ static RValue EmitLoadOfMatrixLValue(LValue LV, SourceLocation Loc,
   return RValue::get(CGF.EmitLoadOfScalar(LV, Loc));
 }
 
+RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, SourceLocation Loc) {
+  QualType Ty = LV.getType();
+  switch (getEvaluationKind(Ty)) {
+  case TEK_Scalar:
+    return EmitLoadOfLValue(LV, Loc);
+  case TEK_Complex:
+    return RValue::getComplex(EmitLoadOfComplex(LV, Loc));
+  case TEK_Aggregate:
+    return RValue::getAggregate(LV.getAddress());
+  }
+  llvm_unreachable("bad evaluation kind");
+}
+
 /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
 /// method emits the address of the lvalue, then loads the result as an rvalue,
 /// returning the rvalue.
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 41688c1f861ed..fc11fb589488f 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -78,15 +78,11 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
   /// then loads the result into DestPtr.
   void EmitAggLoadOfLValue(const Expr *E);
 
-  enum ExprValueKind {
-    EVK_RValue,
-    EVK_NonRValue
-  };
-
   /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
   /// SrcIsRValue is true if source comes from an RValue.
   void EmitFinalDestCopy(QualType type, const LValue &src,
-                         ExprValueKind SrcValueKind = EVK_NonRValue);
+                         CodeGenFunction::ExprValueKind SrcValueKind =
+                             CodeGenFunction::EVK_NonRValue);
   void EmitFinalDestCopy(QualType type, RValue src);
   void EmitCopy(QualType type, const AggValueSlot &dest,
                 const AggValueSlot &src);
@@ -348,12 +344,13 @@ void AggExprEmitter::withReturnValueSlot(
 void AggExprEmitter::EmitFinalDestCopy(QualType type, RValue src) {
   assert(src.isAggregate() && "value must be aggregate value!");
   LValue srcLV = CGF.MakeAddrLValue(src.getAggregateAddress(), type);
-  EmitFinalDestCopy(type, srcLV, EVK_RValue);
+  EmitFinalDestCopy(type, srcLV, CodeGenFunction::EVK_RValue);
 }
 
 /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
-void AggExprEmitter::EmitFinalDestCopy(QualType type, const LValue &src,
-                                       ExprValueKind SrcValueKind) {
+void AggExprEmitter::EmitFinalDestCopy(
+    QualType type, const LValue &src,
+    CodeGenFunction::ExprValueKind SrcValueKind) {
   // If Dest is ignored, then we're evaluating an aggregate expression
   // in a context that doesn't care about the result.  Note that loads
   // from volatile l-values force the existence of a non-ignored
@@ -365,7 +362,7 @@ void AggExprEmitter::EmitFinalDestCopy(QualType type, const LValue &src,
   LValue DstLV = CGF.MakeAddrLValue(
       Dest.getAddress(), Dest.isVolatile() ? type.withVolatile() : type);
 
-  if (SrcValueKind == EVK_RValue) {
+  if (SrcValueKind == CodeGenFunction::EVK_RValue) {
     if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct) {
       if (Dest.isPotentiallyAliased())
         CGF.callCStructMoveAssignmentOperator(DstLV, src);
@@ -1328,7 +1325,7 @@ void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
 
 void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   Address ArgValue = Address::invalid();
-  RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);
+  RValue Res = CGF.EmitVAArg(VE, ArgValue);
 
   // If EmitVAArg fails, emit an error.
   if (!ArgValue.isValid()) {
@@ -1336,7 +1333,9 @@ void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
     return;
   }
 
-  EmitFinalDestCopy(VE->getType(), ArgPtr);
+  LValue ResLV = CGF.MakeAddrLValue(Res.getAggregateAddress(), VE->getType());
+  CGF.EmitAggFinalDestCopy(VE->getType(), Dest, ResLV,
+                           CodeGenFunction::EVK_RValue);
 }
 
 void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
@@ -2038,6 +2037,13 @@ LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
   return LV;
 }
 
+void CodeGenFunction::EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest,
+                                           const LValue &Src,
+                                           ExprValueKind SrcKind) {
+  return AggExprEmitter(*this, Dest, Dest.isIgnored())
+      .EmitFinalDestCopy(Type, Src, SrcKind);
+}
+
 AggValueSlot::Overlap_t
 CodeGenFunction::getOverlapForFieldInit(const FieldDecl *FD) {
   if (!FD->hasAttr<NoUniqueAddressAttr>() || !FD->getType()->isRecordType())
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 53c3276dd0559..7e76e57bc3f02 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5359,8 +5359,6 @@ Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   Address ArgValue = Address::invalid();
   RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);
 
-  llvm::Type *ArgTy = ConvertType(VE->getType());
-
   return ArgPtr.getScalarVal();
 }
 
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index f74b6a76a7dce..e73e2ea4e265a 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4217,6 +4217,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
   RValue EmitLoadOfGlobalRegLValue(LValue LV);
 
+  /// Like EmitLoadOfLValue but also handles complex and aggregate types.
+  RValue EmitLoadOfAnyValue(LValue V, SourceLocation Loc = {});
+
   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
   /// lvalue, where both are guaranteed to the have the same type, and that type
   /// is 'Ty'.
@@ -4777,6 +4780,13 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// aggregate type into a temporary LValue.
   LValue EmitAggExprToLValue(const Expr *E);
 
+  enum ExprValueKind { EVK_RValue, EVK_NonRValue };
+
+  /// EmitAggFinalDestCopy - Emit copy of the specified aggregate into
+  /// destination address.
+  void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src,
+                            ExprValueKind SrcKind);
+
   /// Build all the stores needed to initialize an aggregate at Dest with the
   /// value Val.
   void EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile);
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 9aa3ea75681b3..163795edb6cc9 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -55,14 +55,14 @@ class AArch64ABIInfo : public ABIInfo {
                                      FI.getCallingConvention());
   }
 
-  Address EmitDarwinVAArg(Address VAListAddr, QualType Ty,
-                          CodeGenFunction &CGF) const;
+  RValue EmitDarwinVAArg(Address VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const;
 
-  Address EmitAAPCSVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
-                         AArch64ABIKind Kind) const;
+  RValue EmitAAPCSVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
+                        AArch64ABIKind Kind) const;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override {
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override {
     llvm::Type *BaseTy = CGF.ConvertType(Ty);
     if (isa<llvm::ScalableVectorType>(BaseTy))
       llvm::report_fatal_error("Passing SVE types to variadic functions is "
@@ -73,8 +73,8 @@ class AArch64ABIInfo : public ABIInfo {
                            : EmitAAPCSVAArg(VAListAddr, Ty, CGF, Kind);
   }
 
-  Address EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                      QualType Ty) const override;
+  RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                     QualType Ty) const override;
 
   bool allowBFloatArgsAndRet() const override {
     return getTarget().hasBFloat16Type();
@@ -549,9 +549,9 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
   return true;
 }
 
-Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
-                                       CodeGenFunction &CGF,
-                                       AArch64ABIKind Kind) const {
+RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
+                                      CodeGenFunction &CGF,
+                                      AArch64ABIKind Kind) const {
   ABIArgInfo AI = classifyArgumentType(Ty, /*IsVariadic=*/true,
                                        CGF.CurFnInfo->getCallingConvention());
   // Empty records are ignored for parameter passing purposes.
@@ -560,7 +560,8 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
     CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
     VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
     auto *Load = CGF.Builder.CreateLoad(VAListAddr);
-    return Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
+    return RValue::getAggregate(
+        Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize));
   }
 
   bool IsIndirect = AI.isIndirect();
@@ -789,27 +790,31 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
                                  OnStackBlock, "vaargs.addr");
 
   if (IsIndirect)
-    return Address(CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"), ElementTy,
-                   TyAlign);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
+        Address(CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"), ElementTy,
+                TyAlign),
+        Ty));
 
-  return ResAddr;
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty));
 }
 
-Address AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
+RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
                                         CodeGenFunction &CGF) const {
   // The backend's lowering doesn't support va_arg for aggregates or
   // illegal vector types.  Lower VAArg here for these cases and use
   // the LLVM va_arg instruction for everything else.
   if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty))
-    return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect());
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
+        EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty));
 
   uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
   CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true))
-    return Address(CGF.Builder.CreateLoad(VAListAddr, "ap.cur"),
-                   CGF.ConvertTypeForMem(Ty), SlotSize);
+    return RValue::getAggregate(
+        Address(CGF.Builder.CreateLoad(VAListAddr, "ap.cur"),
+                CGF.ConvertTypeForMem(Ty), SlotSize));
 
   // The size of the actual thing passed, which might end up just
   // being a pointer for indirect types.
@@ -828,8 +833,8 @@ Address AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
                           TyInfo, SlotSize, /*AllowHigherAlign*/ true);
 }
 
-Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                    QualType Ty) const {
+RValue AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                   QualType Ty) const {
   bool IsIndirect = false;
 
   // Composites larger than 16 bytes are passed by reference.
diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp
index 057f6ef40c513..ee86512cf6d12 100644
--- a/clang/lib/CodeGen/Targets/AMDGPU.cpp
+++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp
@@ -49,8 +49,8 @@ class AMDGPUABIInfo final : public DefaultABIInfo {
                                   unsigned &NumRegsLeft) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 bool AMDGPUABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
@@ -118,8 +118,8 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const {
   }
 }
 
-Address AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                 QualType Ty) const {
+RValue AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                QualType Ty) const {
   const bool IsIndirect = false;
   const bool AllowHigherAlign = false;
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp
index 550eb4068f25f..9e259d881c10d 100644
--- a/clang/lib/CodeGen/Targets/ARC.cpp
+++ b/clang/lib/CodeGen/Targets/ARC.cpp
@@ -24,8 +24,8 @@ class ARCABIInfo : public DefaultABIInfo {
   using DefaultABIInfo::DefaultABIInfo;
 
 private:
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   void updateState(const ABIArgInfo &Info, QualType Ty, CCState &State) const {
     if (!State.FreeRegs)
@@ -81,8 +81,8 @@ ABIArgInfo ARCABIInfo::getIndirectByValue(QualType Ty) const {
                                  TypeAlign > MinABIStackAlignInBytes);
 }
 
-Address ARCABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                              QualType Ty) const {
+RValue ARCABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                             QualType Ty) const {
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
                           getContext().getTypeInfoInChars(Ty),
                           CharUnits::fromQuantity(4), true);
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index 885d9c77d0e76..4214fccc120e4 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -81,8 +81,8 @@ class ARMABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   llvm::CallingConv::ID getLLVMDefaultCC() const;
   llvm::CallingConv::ID getABIDefaultCC() const;
@@ -753,15 +753,16 @@ bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,
            (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));
 }
 
-Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                              QualType Ty) const {
+RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                             QualType Ty) const {
   CharUnits SlotSize = CharUnits::fromQuantity(4);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
     VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
     auto *Load = CGF.Builder.CreateLoad(VAListAddr);
-    return Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
+    Address Addr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
+    return RValue::getAggregate(Addr);
   }
 
   CharUnits TySize = getContext().getTypeSizeInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp
index 924eced700e1d..f120471d16539 100644
--- a/clang/lib/CodeGen/Targets/CSKY.cpp
+++ b/clang/lib/CodeGen/Targets/CSKY.cpp
@@ -33,8 +33,8 @@ class CSKYABIInfo : public DefaultABIInfo {
                                   bool isReturnType = false) const;
   ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 } // end anonymous namespace
@@ -57,14 +57,15 @@ void CSKYABIInfo::computeInfo(CGFunctionInfo &FI) const {
   }
 }
 
-Address CSKYABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+RValue CSKYABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                QualType Ty) const {
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
-    return Address(CGF.Builder.CreateLoad(VAListAddr),
-                   CGF.ConvertTypeForMem(Ty), SlotSize);
+    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
+                           CGF.ConvertTypeForMem(Ty), SlotSize);
+    return RValue::getAggregate(Addr);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/Hexagon.cpp b/clang/lib/CodeGen/Targets/Hexagon.cpp
index 944a8d002ecfc..2e101c91b7ebe 100644
--- a/clang/lib/CodeGen/Targets/Hexagon.cpp
+++ b/clang/lib/CodeGen/Targets/Hexagon.cpp
@@ -29,8 +29,8 @@ class HexagonABIInfo : public DefaultABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
   Address EmitVAArgFromMemory(CodeGenFunction &CFG, Address VAListAddr,
                               QualType Ty) const;
   Address EmitVAArgForHexagon(CodeGenFunction &CFG, Address VAListAddr,
@@ -408,13 +408,15 @@ Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF,
   return Address(ArgAddr, MemTy, CharUnits::fromQuantity(ArgAlign));
 }
 
-Address HexagonABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                  QualType Ty) const {
+RValue HexagonABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                 QualType Ty) const {
 
   if (getTarget().getTriple().isMusl())
-    return EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty);
+    return CGF.EmitLoadOfAnyValue(
+        CGF.MakeAddrLValue(EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty), Ty));
 
-  return EmitVAArgForHexagon(CGF, VAListAddr, Ty);
+  return CGF.EmitLoadOfAnyValue(
+      CGF.MakeAddrLValue(EmitVAArgForHexagon(CGF, VAListAddr, Ty), Ty));
 }
 
 std::unique_ptr<TargetCodeGenInfo>
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 3f01d9ad90f13..0f5b621841de0 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -44,8 +44,8 @@ class LoongArchABIInfo : public DefaultABIInfo {
                                   int &FARsLeft) const;
   ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   ABIArgInfo extendType(QualType Ty) const;
 
@@ -417,14 +417,16 @@ ABIArgInfo LoongArchABIInfo::classifyReturnType(QualType RetTy) const {
   return classifyArgumentType(RetTy, /*IsFixed=*/true, GARsLeft, FARsLeft);
 }
 
-Address LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                    QualType Ty) const {
+RValue LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                   QualType Ty) const {
   CharUnits SlotSize = CharUnits::fromQuantity(GRLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true))
-    return Address(CGF.Builder.CreateLoad(VAListAddr),
-                   CGF.ConvertTypeForMem(Ty), SlotSize);
+  if (isEmptyRecord(getContext(), Ty, true)) {
+    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
+                           CGF.ConvertTypeForMem(Ty), SlotSize);
+    return RValue::getAggregate(Addr);
+  }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
 
diff --git a/clang/lib/CodeGen/Targets/MSP430.cpp b/clang/lib/CodeGen/Targets/MSP430.cpp
index bb67d97f44217..93d877b9eb8b1 100644
--- a/clang/lib/CodeGen/Targets/MSP430.cpp
+++ b/clang/lib/CodeGen/Targets/MSP430.cpp
@@ -51,9 +51,10 @@ class MSP430ABIInfo : public DefaultABIInfo {
       I.info = classifyArgumentType(I.type);
   }
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override {
-    return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty));
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override {
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
+        EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty));
   }
 };
 
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index 8f11c63dcd85d..051fec8ed5d35 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -34,8 +34,8 @@ class MipsABIInfo : public ABIInfo {
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
   ABIArgInfo extendType(QualType Ty) const;
 };
 
@@ -346,8 +346,8 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
     I.info = classifyArgumentType(I.type, Offset);
 }
 
-Address MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                               QualType OrigTy) const {
+RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                              QualType OrigTy) const {
   QualType Ty = OrigTy;
 
   // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64.
@@ -373,28 +373,26 @@ Address MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   // MinABIStackAlignInBytes is the size of argument slots on the stack.
   CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes);
 
-  Address Addr = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
-                          TyInfo, ArgSlotSize, /*AllowHigherAlign*/ true);
+  RValue Res =
+      emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
+                       ArgSlotSize, /*AllowHigherAlign*/ true);
 
-
-  // If there was a promotion, "unpromote" into a temporary.
+  // If there was a promotion, "unpromote".
   // TODO: can we just use a pointer into a subset of the original slot?
   if (DidPromote) {
-    Address Temp = CGF.CreateMemTemp(OrigTy, "vaarg.promotion-temp");
-    llvm::Value *Promoted = CGF.Builder.CreateLoad(Addr);
+    llvm::Type *ValTy = CGF.ConvertType(OrigTy);
+    llvm::Value *Promoted = Res.getScalarVal();
 
     // Truncate down to the right width.
-    llvm::Type *IntTy = (OrigTy->isIntegerType() ? Temp.getElementType()
-                                                 : CGF.IntPtrTy);
+    llvm::Type *IntTy = (OrigTy->isIntegerType() ? ValTy : CGF.IntPtrTy);
     llvm::Value *V = CGF.Builder.CreateTrunc(Promoted, IntTy);
     if (OrigTy->isPointerType())
-      V = CGF.Builder.CreateIntToPtr(V, Temp.getElementType());
+      V = CGF.Builder.CreateIntToPtr(V, ValTy);
 
-    CGF.Builder.CreateStore(V, Temp);
-    Addr = Temp;
+    return RValue::get(V);
   }
 
-  return Addr;
+  return Res;
 }
 
 ABIArgInfo MipsABIInfo::extendType(QualType Ty) const {
diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp
index df798ce0ca67d..c7abe2cd14fd4 100644
--- a/clang/lib/CodeGen/Targets/NVPTX.cpp
+++ b/clang/lib/CodeGen/Targets/NVPTX.cpp
@@ -32,8 +32,8 @@ class NVPTXABIInfo : public ABIInfo {
   ABIArgInfo classifyArgumentType(QualType Ty) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
   bool isUnsupportedType(QualType T) const;
   ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, unsigned MaxSize) const;
 };
@@ -213,8 +213,8 @@ void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
   FI.setEffectiveCallingConvention(getRuntimeCC());
 }
 
-Address NVPTXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+RValue NVPTXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                               QualType Ty) const {
   llvm_unreachable("NVPTX does not support varargs");
 }
 
diff --git a/clang/lib/CodeGen/Targets/PNaCl.cpp b/clang/lib/CodeGen/Targets/PNaCl.cpp
index 771aa7469da27..5d031f6db6fbb 100644
--- a/clang/lib/CodeGen/Targets/PNaCl.cpp
+++ b/clang/lib/CodeGen/Targets/PNaCl.cpp
@@ -27,8 +27,8 @@ class PNaClABIInfo : public ABIInfo {
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF,
-                    Address VAListAddr, QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -45,15 +45,16 @@ void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
     I.info = classifyArgumentType(I.type);
 }
 
-Address PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+RValue PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                               QualType Ty) const {
   // The PNaCL ABI is a bit odd, in that varargs don't use normal
   // function classification. Structs get passed directly for varargs
   // functions, through a rewriting transform in
   // pnacl-llvm/lib/Transforms/NaCl/ExpandVarArgs.cpp, which allows
   // this target to actually support a va_arg instructions with an
   // aggregate type, unlike other targets.
-  return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect());
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
+      EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty));
 }
 
 /// Classify argument of given type \p Ty.
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 174fddabbbdb6..c5a402ea15cad 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -13,9 +13,9 @@
 using namespace clang;
 using namespace clang::CodeGen;
 
-static Address complexTempStructure(CodeGenFunction &CGF, Address VAListAddr,
-                                    QualType Ty, CharUnits SlotSize,
-                                    CharUnits EltSize, const ComplexType *CTy) {
+static RValue complexTempStructure(CodeGenFunction &CGF, Address VAListAddr,
+                                   QualType Ty, CharUnits SlotSize,
+                                   CharUnits EltSize, const ComplexType *CTy) {
   Address Addr =
       emitVoidPtrDirectVAArg(CGF, VAListAddr, CGF.Int8Ty, SlotSize * 2,
                              SlotSize, SlotSize, /*AllowHigher*/ true);
@@ -37,10 +37,7 @@ static Address complexTempStructure(CodeGenFunction &CGF, Address VAListAddr,
   llvm::Value *Real = CGF.Builder.CreateLoad(RealAddr, ".vareal");
   llvm::Value *Imag = CGF.Builder.CreateLoad(ImagAddr, ".vaimag");
 
-  Address Temp = CGF.CreateMemTemp(Ty, "vacplx");
-  CGF.EmitStoreOfComplex({Real, Imag}, CGF.MakeAddrLValue(Temp, Ty),
-                         /*init*/ true);
-  return Temp;
+  return RValue::getComplex(Real, Imag);
 }
 
 static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
@@ -129,8 +126,8 @@ class AIXABIInfo : public ABIInfo {
       I.info = classifyArgumentType(I.type);
   }
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -239,8 +236,8 @@ CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(PtrByteSize);
 }
 
-Address AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                              QualType Ty) const {
+RValue AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                             QualType Ty) const {
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
   TypeInfo.Align = getParamTypeAlignment(Ty);
@@ -348,8 +345,8 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
       I.info = classifyArgumentType(I.type);
   }
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -426,8 +423,8 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
 
 // TODO: this implementation is now likely redundant with
 // DefaultABIInfo::EmitVAArg.
-Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
-                                      QualType Ty) const {
+RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
+                                     QualType Ty) const {
   if (getTarget().getTriple().isOSDarwin()) {
     auto TI = getContext().getTypeInfoInChars(Ty);
     TI.Align = getParamTypeAlignment(Ty);
@@ -442,7 +439,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
   if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
     // TODO: Implement this. For now ignore.
     (void)CTy;
-    return Address::invalid(); // FIXME?
+    return RValue::getAggregate(Address::invalid()); // FIXME?
   }
 
   // struct __va_list_tag {
@@ -577,7 +574,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
                      getContext().getTypeAlignInChars(Ty));
   }
 
-  return Result;
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Result, Ty));
 }
 
 bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
@@ -658,8 +655,8 @@ class PPC64_SVR4_ABIInfo : public ABIInfo {
     }
   }
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -958,8 +955,8 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
 }
 
 // Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine.
-Address PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                      QualType Ty) const {
+RValue PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                     QualType Ty) const {
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
   TypeInfo.Align = getParamTypeAlignment(Ty);
 
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index 7b32c79723562..6039dabb2f773 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -48,8 +48,8 @@ class RISCVABIInfo : public DefaultABIInfo {
                                   int &ArgFPRsLeft) const;
   ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   ABIArgInfo extendType(QualType Ty) const;
 
@@ -489,14 +489,15 @@ ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy) const {
                               ArgFPRsLeft);
 }
 
-Address RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                               QualType Ty) const {
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
-    return Address(CGF.Builder.CreateLoad(VAListAddr),
-                   CGF.ConvertTypeForMem(Ty), SlotSize);
+    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
+                           CGF.ConvertTypeForMem(Ty), SlotSize);
+    return RValue::getAggregate(Addr);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index 561f0b514d909..8f077f5c88e66 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -111,8 +111,8 @@ class SparcV9ABIInfo : public ABIInfo {
 private:
   ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit) const;
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   // Coercion type builder for structs passed in registers. The coercion type
   // serves two purposes:
@@ -278,8 +278,8 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const {
     return ABIArgInfo::getDirect(CoerceTy);
 }
 
-Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                  QualType Ty) const {
+RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                 QualType Ty) const {
   ABIArgInfo AI = classifyType(Ty, 16 * 8);
   llvm::Type *ArgTy = CGT.ConvertType(Ty);
   if (AI.canHaveCoerceToType() && !AI.getCoerceToType())
@@ -325,14 +325,16 @@ Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     break;
 
   case ABIArgInfo::Ignore:
-    return Address(llvm::UndefValue::get(ArgPtrTy), ArgTy, TypeInfo.Align);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
+        Address(llvm::UndefValue::get(ArgPtrTy), ArgTy, TypeInfo.Align), Ty));
   }
 
   // Update VAList.
   Address NextPtr = Builder.CreateConstInBoundsByteGEP(Addr, Stride, "ap.next");
   Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr);
 
-  return ArgAddr.withElementType(ArgTy);
+  return CGF.EmitLoadOfAnyValue(
+      CGF.MakeAddrLValue(ArgAddr.withElementType(ArgTy), Ty));
 }
 
 void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const {
diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp
index deaafc85a3157..fa393726bdf55 100644
--- a/clang/lib/CodeGen/Targets/SystemZ.cpp
+++ b/clang/lib/CodeGen/Targets/SystemZ.cpp
@@ -38,8 +38,8 @@ class SystemZABIInfo : public ABIInfo {
   ABIArgInfo classifyArgumentType(QualType ArgTy) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -243,8 +243,8 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
   return Ty;
 }
 
-Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                  QualType Ty) const {
+RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                 QualType Ty) const {
   // Assume that va_list type is correct; should be pointer to LLVM type:
   // struct {
   //   i64 __gpr;
@@ -310,7 +310,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
         PaddedSizeV, "overflow_arg_area");
     CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
 
-    return MemAddr;
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(MemAddr, Ty));
   }
 
   assert(PaddedSize.getQuantity() == 8);
@@ -397,7 +397,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), ArgTy,
                       TyInfo.Align);
 
-  return ResAddr;
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty));
 }
 
 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp
index bd332228ce5bb..ddbc3c7ded6a0 100644
--- a/clang/lib/CodeGen/Targets/WebAssembly.cpp
+++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp
@@ -41,8 +41,8 @@ class WebAssemblyABIInfo final : public ABIInfo {
       Arg.info = classifyArgumentType(Arg.type);
   }
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo {
@@ -155,8 +155,8 @@ ABIArgInfo WebAssemblyABIInfo::classifyReturnType(QualType RetTy) const {
   return defaultInfo.classifyReturnType(RetTy);
 }
 
-Address WebAssemblyABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                      QualType Ty) const {
+RValue WebAssemblyABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                     QualType Ty) const {
   bool IsIndirect = isAggregateTypeForABI(Ty) &&
                     !isEmptyRecord(getContext(), Ty, true) &&
                     !isSingleElementStruct(Ty, getContext());
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 43dadf5e724ac..adb0aa91ddfcb 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -173,8 +173,8 @@ class X86_32ABIInfo : public ABIInfo {
 public:
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI,
                 bool RetSmallStructInRegABI, bool Win32StructABI,
@@ -1066,8 +1066,8 @@ void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const {
                   StackAlign);
 }
 
-Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF,
-                                 Address VAListAddr, QualType Ty) const {
+RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                QualType Ty) const {
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
 
@@ -1075,7 +1075,7 @@ Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF,
   ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
   // Empty records are ignored for parameter passing purposes.
   if (AI.isIgnore())
-    return CGF.CreateMemTemp(Ty);
+    return RValue::getAggregate(CGF.CreateMemTemp(Ty));
 
   // x86-32 changes the alignment of certain arguments on the stack.
   //
@@ -1367,10 +1367,10 @@ class X86_64ABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
-  Address EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                      QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
+  RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                     QualType Ty) const override;
 
   bool has64BitPointers() const {
     return Has64BitPointers;
@@ -1386,8 +1386,8 @@ class WinX86_64ABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 
   bool isHomogeneousAggregateBaseType(QualType Ty) const override {
     // FIXME: Assumes vectorcall is in use.
@@ -3020,8 +3020,8 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
   return Address(Res, LTy, Align);
 }
 
-Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                 QualType Ty) const {
+RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                QualType Ty) const {
   // Assume that va_list type is correct; should be pointer to LLVM type:
   // struct {
   //   i32 gp_offset;
@@ -3037,12 +3037,13 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
 
   // Empty records are ignored for parameter passing purposes.
   if (AI.isIgnore())
-    return CGF.CreateMemTemp(Ty);
+    return RValue::getAggregate(CGF.CreateMemTemp(Ty));
 
   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
   // in the registers. If not go to step 7.
   if (!neededInt && !neededSSE)
-    return EmitX86_64VAArgFromMemory(CGF, VAListAddr, Ty);
+    return CGF.EmitLoadOfAnyValue(
+        CGF.MakeAddrLValue(EmitX86_64VAArgFromMemory(CGF, VAListAddr, Ty), Ty));
 
   // AMD64-ABI 3.5.7p5: Step 2. Compute num_gp to hold the number of
   // general purpose registers needed to pass type and num_fp to hold
@@ -3205,11 +3206,11 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CGF.EmitBlock(ContBlock);
   Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock,
                                  "vaarg.addr");
-  return ResAddr;
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty));
 }
 
-Address X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                   QualType Ty) const {
+RValue X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                  QualType Ty) const {
   // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is
   // not 1, 2, 4, or 8 bytes, must be passed by reference."
   uint64_t Width = getContext().getTypeSize(Ty);
@@ -3410,8 +3411,8 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
   }
 }
 
-Address WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                    QualType Ty) const {
+RValue WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                                   QualType Ty) const {
   // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is
   // not 1, 2, 4, or 8 bytes, must be passed by reference."
   uint64_t Width = getContext().getTypeSize(Ty);
diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp
index 88edb781a947b..23f08a4f85d54 100644
--- a/clang/lib/CodeGen/Targets/XCore.cpp
+++ b/clang/lib/CodeGen/Targets/XCore.cpp
@@ -113,8 +113,8 @@ class FieldEncoding {
 class XCoreABIInfo : public DefaultABIInfo {
 public:
   XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
-  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                    QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                   QualType Ty) const override;
 };
 
 class XCoreTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -134,8 +134,8 @@ class XCoreTargetCodeGenInfo : public TargetCodeGenInfo {
 
 // TODO: this implementation is likely now redundant with the default
 // EmitVAArg.
-Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+RValue XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                               QualType Ty) const {
   CGBuilderTy &Builder = CGF.Builder;
 
   // Get the VAList.
@@ -183,7 +183,7 @@ Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     Builder.CreateStore(APN.emitRawPointer(CGF), VAListAddr);
   }
 
-  return Val;
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Val, Ty));
 }
 
 /// During the expansion of a RecordType, an incomplete TypeString is placed
diff --git a/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c b/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c
index 02dd071bdb744..6036adb7d23be 100644
--- a/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c
+++ b/clang/test/CodeGen/PowerPC/aix32-complex-varargs.c
@@ -11,13 +11,14 @@ void testva (int n, ...)
 // CHECK:  %[[VAR40:[A-Za-z0-9.]+]] = load ptr, ptr %[[VAR100:[A-Za-z0-9.]+]]
 // CHECK-NEXT:  %[[VAR41:[A-Za-z0-9.]+]] = getelementptr inbounds i8, ptr %[[VAR40]]
 // CHECK-NEXT:  store ptr %[[VAR41]], ptr %[[VAR100]], align 4
-// CHECK-NEXT:  %[[VAR6:[A-Za-z0-9.]+]] = load { i32, i32 }, ptr %[[VAR40]], align 4
-// CHECK-NEXT:  %[[VAR7:[A-Za-z0-9.]+]] = extractvalue { i32, i32 } %[[VAR6]], 0
-// CHECK-NEXT:  %[[VAR8:[A-Za-z0-9.]+]] = extractvalue { i32, i32 } %[[VAR6]], 1
+// CHECK-NEXT:  %[[VAR6:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VAR40]], i32 0, i32 0
+// CHECK-NEXT:  %[[VAR7:[A-Za-z0-9.]+]] = load i32, ptr %[[VAR6]]
+// CHECK-NEXT:  %[[VAR8:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VAR40]], i32 0, i32 1
+// CHECK-NEXT:  %[[VAR9:[A-Za-z0-9.]+]] = load i32, ptr %[[VAR8]]
 // CHECK-NEXT:  %[[VAR10:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VARINT:[A-Za-z0-9.]+]], i32 0, i32 0
 // CHECK-NEXT:  %[[VAR11:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }, ptr %[[VARINT]], i32 0, i32 1
 // CHECK-NEXT:  store i32 %[[VAR7]], ptr %[[VAR10]]
-// CHECK-NEXT:  store i32 %[[VAR8]], ptr %[[VAR11]]
+// CHECK-NEXT:  store i32 %[[VAR9]], ptr %[[VAR11]]
 
   _Complex short s = va_arg(ap, _Complex short);
 // CHECK:  %[[VAR50:[A-Za-z0-9.]+]] = load ptr, ptr %[[VAR100:[A-Za-z0-9.]+]]
@@ -50,11 +51,12 @@ void testva (int n, ...)
   _Complex float f = va_arg(ap, _Complex float);
 // CHECK:  %[[VAR70:[A-Za-z0-9.]+]] = getelementptr inbounds i8, ptr %[[VAR71:[A-Za-z0-9.]+]], i32 8
 // CHECK-NEXT:  store ptr %[[VAR70]], ptr %[[VAR100:[A-Za-z0-9.]+]]
-// CHECK-NEXT:  %[[VAR29:[A-Za-z0-9.]+]] = load { float, float }, ptr %[[VAR71]], align 4
-// CHECK-NEXT:  %[[VAR30:[A-Za-z0-9.]+]] = extractvalue { float, float } %[[VAR29]], 0
-// CHECK-NEXT:  %[[VAR31:[A-Za-z0-9.]+]] = extractvalue { float, float } %[[VAR29]], 1
+// CHECK-NEXT:  %[[VAR29:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %[[VAR71]], i32 0, i32 0
+// CHECK-NEXT:  %[[VAR30:[A-Za-z0-9.]+]] = load float, ptr %[[VAR29]]
+// CHECK-NEXT:  %[[VAR31:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %[[VAR71]], i32 0, i32 1
+// CHECK-NEXT:  %[[VAR32:[A-Za-z0-9.]+]] = load float, ptr %[[VAR31]]
 // CHECK-NEXT:  %[[VAR33:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %f, i32 0, i32 0
 // CHECK-NEXT:  %[[VAR34:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }, ptr %f, i32 0, i32 1
 // CHECK-NEXT:  store float %[[VAR30]], ptr %[[VAR33]]
-// CHECK-NEXT:  store float %[[VAR31]], ptr %[[VAR34]]
+// CHECK-NEXT:  store float %[[VAR32]], ptr %[[VAR34]]
 }
diff --git a/clang/test/CodeGen/arm-abi-vector.c b/clang/test/CodeGen/arm-abi-vector.c
index 7f0cc4bcb0cd8..c2a8902007980 100644
--- a/clang/test/CodeGen/arm-abi-vector.c
+++ b/clang/test/CodeGen/arm-abi-vector.c
@@ -194,7 +194,7 @@ double varargs_vec_3s(int fixed, ...) {
 // APCS-GNU: [[VAR:%.*]] = alloca <3 x i16>, align 8
 // APCS-GNU: [[AP:%.*]] = load ptr,
 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 8
-// APCS-GNU: [[VEC:%.*]] = load <3 x i16>, ptr [[AP]], align 4
+// APCS-GNU: [[VEC:%.*]] = load <4 x i16>, ptr [[AP]], align 4
 // ANDROID: varargs_vec_3s
 // ANDROID: alloca <3 x i16>, align 8
 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
diff --git a/clang/test/CodeGen/mips-varargs.c b/clang/test/CodeGen/mips-varargs.c
index 029f000c121a5..8fdffc87675e7 100644
--- a/clang/test/CodeGen/mips-varargs.c
+++ b/clang/test/CodeGen/mips-varargs.c
@@ -27,7 +27,6 @@ int test_i32(char *fmt, ...) {
 // N32:   %va = alloca ptr, align [[$PTRALIGN:4]]
 // N64:   %va = alloca ptr, align [[$PTRALIGN:8]]
 // ALL:   [[V:%.*]] = alloca i32, align 4
-// NEW:   [[PROMOTION_TEMP:%.*]] = alloca i32, align 4
 //
 // ALL:   call void @llvm.va_start.p0(ptr %va)
 // ALL:   [[AP_CUR:%.+]] = load ptr, ptr %va, align [[$PTRALIGN]]
@@ -41,9 +40,7 @@ int test_i32(char *fmt, ...) {
 // N32:   [[TMP:%.+]] = load i64, ptr [[AP_CUR]], align [[CHUNKALIGN:8]]
 // N64:   [[TMP:%.+]] = load i64, ptr [[AP_CUR]], align [[CHUNKALIGN:8]]
 // NEW:   [[TMP2:%.+]] = trunc i64 [[TMP]] to i32
-// NEW:   store i32 [[TMP2]], ptr [[PROMOTION_TEMP]], align 4
-// NEW:   [[ARG:%.+]] = load i32, ptr [[PROMOTION_TEMP]], align 4
-// ALL:   store i32 [[ARG]], ptr [[V]], align 4
+// NEW:   store i32 [[TMP2]], ptr [[V]], align 4
 //
 // ALL:   call void @llvm.va_end.p0(ptr %va)
 // ALL: }
@@ -91,7 +88,6 @@ char *test_ptr(char *fmt, ...) {
 //
 // ALL:   %va = alloca ptr, align [[$PTRALIGN]]
 // ALL:   [[V:%.*]] = alloca ptr, align [[$PTRALIGN]]
-// N32:   [[AP_CAST:%.+]] = alloca ptr, align 4
 // ALL:   call void @llvm.va_start.p0(ptr %va)
 // ALL:   [[AP_CUR:%.+]] = load ptr, ptr %va, align [[$PTRALIGN]]
 // ALL:   [[AP_NEXT:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], [[$INTPTR_T]] [[$CHUNKSIZE]]
@@ -102,12 +98,7 @@ char *test_ptr(char *fmt, ...) {
 // N32:   [[TMP2:%.+]] = load i64, ptr [[AP_CUR]], align 8
 // N32:   [[TMP3:%.+]] = trunc i64 [[TMP2]] to i32
 // N32:   [[PTR:%.+]] = inttoptr i32 [[TMP3]] to ptr
-// N32:   store ptr [[PTR]], ptr [[AP_CAST]], align 4
-// N32:   [[ARG:%.+]] = load ptr, ptr [[AP_CAST]], align [[$PTRALIGN]]
-//
-// O32:   [[ARG:%.+]] = load ptr, ptr [[AP_CUR]], align [[$PTRALIGN]]
-// N64:   [[ARG:%.+]] = load ptr, ptr [[AP_CUR]], align [[$PTRALIGN]]
-// ALL:   store ptr [[ARG]], ptr [[V]], align [[$PTRALIGN]]
+// N32:   store ptr [[PTR]], ptr [[V]], align 4
 //
 // ALL:   call void @llvm.va_end.p0(ptr %va)
 // ALL: }

>From aef775acd5aae4b1bc7a9ddd4c89d0140e6baddc Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Mon, 10 Jun 2024 07:31:27 -0700
Subject: [PATCH 03/10] Make format happy

---
 clang/lib/CodeGen/ABIInfoImpl.cpp     | 9 ++++-----
 clang/lib/CodeGen/Targets/AArch64.cpp | 2 +-
 clang/lib/CodeGen/Targets/CSKY.cpp    | 2 +-
 clang/lib/CodeGen/Targets/Mips.cpp    | 5 ++---
 4 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 5a41a16fb413b..74f1df739ea48 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -201,11 +201,10 @@ CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
 }
 
 RValue CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                  QualType ValueTy, bool IsIndirect,
-                                  TypeInfoChars ValueInfo,
-                                  CharUnits SlotSizeAndAlign,
-                                  bool AllowHigherAlign,
-                                  bool ForceRightAdjust) {
+                                 QualType ValueTy, bool IsIndirect,
+                                 TypeInfoChars ValueInfo,
+                                 CharUnits SlotSizeAndAlign,
+                                 bool AllowHigherAlign, bool ForceRightAdjust) {
   // The size and alignment of the value that was passed directly.
   CharUnits DirectSize, DirectAlign;
   if (IsIndirect) {
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 163795edb6cc9..adcd9a00ba762 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -799,7 +799,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
 }
 
 RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
-                                        CodeGenFunction &CGF) const {
+                                       CodeGenFunction &CGF) const {
   // The backend's lowering doesn't support va_arg for aggregates or
   // illegal vector types.  Lower VAArg here for these cases and use
   // the LLVM va_arg instruction for everything else.
diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp
index f120471d16539..0ba71352c5d4b 100644
--- a/clang/lib/CodeGen/Targets/CSKY.cpp
+++ b/clang/lib/CodeGen/Targets/CSKY.cpp
@@ -58,7 +58,7 @@ void CSKYABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue CSKYABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                               QualType Ty) const {
+                              QualType Ty) const {
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index 051fec8ed5d35..137d6eb2b0fd7 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -373,9 +373,8 @@ RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   // MinABIStackAlignInBytes is the size of argument slots on the stack.
   CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes);
 
-  RValue Res =
-      emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
-                       ArgSlotSize, /*AllowHigherAlign*/ true);
+  RValue Res = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
+                                ArgSlotSize, /*AllowHigherAlign*/ true);
 
   // If there was a promotion, "unpromote".
   // TODO: can we just use a pointer into a subset of the original slot?

>From e17cee9f25050f4e5346e65dac3b4085294e8304 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Tue, 11 Jun 2024 09:42:52 -0700
Subject: [PATCH 04/10] Pass AggValueSlot to EmitVAArg

---
 clang/lib/CodeGen/ABIInfo.cpp             |  2 +-
 clang/lib/CodeGen/ABIInfo.h               |  7 ++-
 clang/lib/CodeGen/ABIInfoImpl.cpp         | 13 +++--
 clang/lib/CodeGen/ABIInfoImpl.h           |  7 ++-
 clang/lib/CodeGen/CGCall.cpp              |  7 ++-
 clang/lib/CodeGen/CGExpr.cpp              |  6 +-
 clang/lib/CodeGen/CGExprAgg.cpp           |  6 +-
 clang/lib/CodeGen/CodeGenFunction.h       |  7 ++-
 clang/lib/CodeGen/Targets/AArch64.cpp     | 69 +++++++++++++----------
 clang/lib/CodeGen/Targets/AMDGPU.cpp      |  8 +--
 clang/lib/CodeGen/Targets/ARC.cpp         |  8 +--
 clang/lib/CodeGen/Targets/ARM.cpp         | 14 +++--
 clang/lib/CodeGen/Targets/CSKY.cpp        | 10 ++--
 clang/lib/CodeGen/Targets/Hexagon.cpp     | 11 ++--
 clang/lib/CodeGen/Targets/LoongArch.cpp   | 10 ++--
 clang/lib/CodeGen/Targets/MSP430.cpp      |  8 ++-
 clang/lib/CodeGen/Targets/Mips.cpp        |  8 +--
 clang/lib/CodeGen/Targets/NVPTX.cpp       |  6 +-
 clang/lib/CodeGen/Targets/PNaCl.cpp       | 12 ++--
 clang/lib/CodeGen/Targets/PPC.cpp         | 24 ++++----
 clang/lib/CodeGen/Targets/RISCV.cpp       | 11 ++--
 clang/lib/CodeGen/Targets/Sparc.cpp       | 15 +++--
 clang/lib/CodeGen/Targets/SystemZ.cpp     | 10 ++--
 clang/lib/CodeGen/Targets/WebAssembly.cpp |  8 +--
 clang/lib/CodeGen/Targets/X86.cpp         | 43 +++++++-------
 clang/lib/CodeGen/Targets/XCore.cpp       |  8 +--
 26 files changed, 185 insertions(+), 153 deletions(-)

diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp
index 623957ae3697b..edd7146dc1ac7 100644
--- a/clang/lib/CodeGen/ABIInfo.cpp
+++ b/clang/lib/CodeGen/ABIInfo.cpp
@@ -40,7 +40,7 @@ bool ABIInfo::isOHOSFamily() const {
 }
 
 RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                            QualType Ty) const {
+                            QualType Ty, AggValueSlot Slot) const {
   return RValue::getIgnored();
 }
 
diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h
index 4ea12eed85261..b8a8de57e5b97 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/lib/CodeGen/ABIInfo.h
@@ -35,6 +35,7 @@ class CGFunctionInfo;
 class CodeGenFunction;
 class CodeGenTypes;
 class RValue;
+class AggValueSlot;
 
 // FIXME: All of this stuff should be part of the target interface
 // somehow. It is currently here because it is not clear how to factor
@@ -77,7 +78,8 @@ class ABIInfo {
   // VAArg handling it has to be at this level; there is no way to
   // abstract this out.
   virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF,
-                           CodeGen::Address VAListAddr, QualType Ty) const = 0;
+                           CodeGen::Address VAListAddr, QualType Ty,
+                           AggValueSlot Slot) const = 0;
 
   bool isAndroid() const;
   bool isOHOSFamily() const;
@@ -85,7 +87,8 @@ class ABIInfo {
   /// Emit the target dependent code to load a value of
   /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
   virtual RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
-                             CodeGen::Address VAListAddr, QualType Ty) const;
+                             CodeGen::Address VAListAddr, QualType Ty,
+                             AggValueSlot Slot) const;
 
   virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
 
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 74f1df739ea48..e9a26abb77837 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -72,9 +72,11 @@ void DefaultABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                 QualType Ty) const {
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
-      EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty));
+                                 QualType Ty, AggValueSlot Slot) const {
+  return CGF.EmitLoadOfAnyValue(
+      CGF.MakeAddrLValue(
+          EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
+      Slot);
 }
 
 ABIArgInfo CodeGen::coerceToIntArray(QualType Ty, ASTContext &Context,
@@ -204,7 +206,8 @@ RValue CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                  QualType ValueTy, bool IsIndirect,
                                  TypeInfoChars ValueInfo,
                                  CharUnits SlotSizeAndAlign,
-                                 bool AllowHigherAlign, bool ForceRightAdjust) {
+                                 bool AllowHigherAlign, AggValueSlot Slot,
+                                 bool ForceRightAdjust) {
   // The size and alignment of the value that was passed directly.
   CharUnits DirectSize, DirectAlign;
   if (IsIndirect) {
@@ -230,7 +233,7 @@ RValue CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
     Addr = Address(CGF.Builder.CreateLoad(Addr), ElementTy, ValueInfo.Align);
   }
 
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, ValueTy));
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, ValueTy), Slot);
 }
 
 Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h
index f4af4beff727f..92986fb431646 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.h
+++ b/clang/lib/CodeGen/ABIInfoImpl.h
@@ -29,8 +29,8 @@ class DefaultABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 // Helper for coercing an aggregate argument or return value into an integer
@@ -115,7 +115,8 @@ Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
 RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
                         QualType ValueTy, bool IsIndirect,
                         TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign,
-                        bool AllowHigherAlign, bool ForceRightAdjust = false);
+                        bool AllowHigherAlign, AggValueSlot Slot,
+                        bool ForceRightAdjust = false);
 
 Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
                      llvm::BasicBlock *Block1, Address Addr2,
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d23e2aae4c968..7336a09100eb1 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5988,11 +5988,12 @@ CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
 
 /* VarArg handling */
 
-RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) {
+RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
+                                  AggValueSlot Slot) {
   VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr())
                                     : EmitVAListRef(VE->getSubExpr());
   QualType Ty = VE->getType();
   if (VE->isMicrosoftABI())
-    return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty);
-  return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty);
+    return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty, Slot);
+  return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty, Slot);
 }
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1d049da254f35..54b56019755d3 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2161,7 +2161,8 @@ static RValue EmitLoadOfMatrixLValue(LValue LV, SourceLocation Loc,
   return RValue::get(CGF.EmitLoadOfScalar(LV, Loc));
 }
 
-RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, SourceLocation Loc) {
+RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, AggValueSlot Slot,
+                                           SourceLocation Loc) {
   QualType Ty = LV.getType();
   switch (getEvaluationKind(Ty)) {
   case TEK_Scalar:
@@ -2169,7 +2170,8 @@ RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, SourceLocation Loc) {
   case TEK_Complex:
     return RValue::getComplex(EmitLoadOfComplex(LV, Loc));
   case TEK_Aggregate:
-    return RValue::getAggregate(LV.getAddress());
+    EmitAggFinalDestCopy(Ty, Slot, LV, EVK_RValue);
+    return Slot.asRValue();
   }
   llvm_unreachable("bad evaluation kind");
 }
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index fc11fb589488f..bb519fa5f973d 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1325,17 +1325,13 @@ void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
 
 void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   Address ArgValue = Address::invalid();
-  RValue Res = CGF.EmitVAArg(VE, ArgValue);
+  CGF.EmitVAArg(VE, ArgValue, Dest);
 
   // If EmitVAArg fails, emit an error.
   if (!ArgValue.isValid()) {
     CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
     return;
   }
-
-  LValue ResLV = CGF.MakeAddrLValue(Res.getAggregateAddress(), VE->getType());
-  CGF.EmitAggFinalDestCopy(VE->getType(), Dest, ResLV,
-                           CodeGenFunction::EVK_RValue);
 }
 
 void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index e73e2ea4e265a..bacf5a05e9b70 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3016,7 +3016,8 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// \returns A pointer to the argument.
   // FIXME: We should be able to get rid of this method and use the va_arg
   // instruction in LLVM instead once it works well enough.
-  RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr);
+  RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
+                   AggValueSlot Slot = AggValueSlot::ignored());
 
   /// emitArrayLength - Compute the length of an array, even if it's a
   /// VLA, and drill down to the base element type.
@@ -4218,7 +4219,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   RValue EmitLoadOfGlobalRegLValue(LValue LV);
 
   /// Like EmitLoadOfLValue but also handles complex and aggregate types.
-  RValue EmitLoadOfAnyValue(LValue V, SourceLocation Loc = {});
+  RValue EmitLoadOfAnyValue(LValue V,
+                            AggValueSlot Slot = AggValueSlot::ignored(),
+                            SourceLocation Loc = {});
 
   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
   /// lvalue, where both are guaranteed to the have the same type, and that type
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index adcd9a00ba762..e3b2b144cff8b 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -55,26 +55,27 @@ class AArch64ABIInfo : public ABIInfo {
                                      FI.getCallingConvention());
   }
 
-  RValue EmitDarwinVAArg(Address VAListAddr, QualType Ty,
-                         CodeGenFunction &CGF) const;
+  RValue EmitDarwinVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
+                         AggValueSlot Slot) const;
 
   RValue EmitAAPCSVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
-                        AArch64ABIKind Kind) const;
+                        AArch64ABIKind Kind, AggValueSlot Slot) const;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override {
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override {
     llvm::Type *BaseTy = CGF.ConvertType(Ty);
     if (isa<llvm::ScalableVectorType>(BaseTy))
       llvm::report_fatal_error("Passing SVE types to variadic functions is "
                                "currently not supported");
 
-    return Kind == AArch64ABIKind::Win64 ? EmitMSVAArg(CGF, VAListAddr, Ty)
-           : isDarwinPCS()               ? EmitDarwinVAArg(VAListAddr, Ty, CGF)
-                           : EmitAAPCSVAArg(VAListAddr, Ty, CGF, Kind);
+    return Kind == AArch64ABIKind::Win64
+               ? EmitMSVAArg(CGF, VAListAddr, Ty, Slot)
+           : isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF, Slot)
+                           : EmitAAPCSVAArg(VAListAddr, Ty, CGF, Kind, Slot);
   }
 
-  RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                     QualType Ty) const override;
+  RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                     AggValueSlot Slot) const override;
 
   bool allowBFloatArgsAndRet() const override {
     return getTarget().hasBFloat16Type();
@@ -550,8 +551,8 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
 }
 
 RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
-                                      CodeGenFunction &CGF,
-                                      AArch64ABIKind Kind) const {
+                                      CodeGenFunction &CGF, AArch64ABIKind Kind,
+                                      AggValueSlot Slot) const {
   ABIArgInfo AI = classifyArgumentType(Ty, /*IsVariadic=*/true,
                                        CGF.CurFnInfo->getCallingConvention());
   // Empty records are ignored for parameter passing purposes.
@@ -560,8 +561,8 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
     CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
     VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
     auto *Load = CGF.Builder.CreateLoad(VAListAddr);
-    return RValue::getAggregate(
-        Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize));
+    Address ResAddr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
   }
 
   bool IsIndirect = AI.isIndirect();
@@ -790,31 +791,37 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
                                  OnStackBlock, "vaargs.addr");
 
   if (IsIndirect)
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
-        Address(CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"), ElementTy,
-                TyAlign),
-        Ty));
-
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty));
+    return CGF.EmitLoadOfAnyValue(
+        CGF.MakeAddrLValue(
+            Address(CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"), ElementTy,
+                    TyAlign),
+            Ty),
+        Slot);
+
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
 }
 
 RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
-                                       CodeGenFunction &CGF) const {
+                                       CodeGenFunction &CGF,
+                                       AggValueSlot Slot) const {
   // The backend's lowering doesn't support va_arg for aggregates or
   // illegal vector types.  Lower VAArg here for these cases and use
   // the LLVM va_arg instruction for everything else.
   if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty))
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
-        EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty));
+    return CGF.EmitLoadOfAnyValue(
+        CGF.MakeAddrLValue(
+            EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty),
+        Slot);
 
   uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
   CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true))
-    return RValue::getAggregate(
-        Address(CGF.Builder.CreateLoad(VAListAddr, "ap.cur"),
-                CGF.ConvertTypeForMem(Ty), SlotSize));
+  if (isEmptyRecord(getContext(), Ty, true)) {
+    Address ResAddr = Address(CGF.Builder.CreateLoad(VAListAddr, "ap.cur"),
+                              CGF.ConvertTypeForMem(Ty), SlotSize);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
+  }
 
   // The size of the actual thing passed, which might end up just
   // being a pointer for indirect types.
@@ -829,12 +836,12 @@ RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
     IsIndirect = !isHomogeneousAggregate(Ty, Base, Members);
   }
 
-  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
-                          TyInfo, SlotSize, /*AllowHigherAlign*/ true);
+  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,
+                          /*AllowHigherAlign*/ true, Slot);
 }
 
 RValue AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                   QualType Ty) const {
+                                   QualType Ty, AggValueSlot Slot) const {
   bool IsIndirect = false;
 
   // Composites larger than 16 bytes are passed by reference.
@@ -844,7 +851,7 @@ RValue AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
                           CGF.getContext().getTypeInfoInChars(Ty),
                           CharUnits::fromQuantity(8),
-                          /*allowHigherAlign*/ false);
+                          /*allowHigherAlign*/ false, Slot);
 }
 
 static bool isStreamingCompatible(const FunctionDecl *F) {
diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp
index ee86512cf6d12..4d3275e17c386 100644
--- a/clang/lib/CodeGen/Targets/AMDGPU.cpp
+++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp
@@ -49,8 +49,8 @@ class AMDGPUABIInfo final : public DefaultABIInfo {
                                   unsigned &NumRegsLeft) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 bool AMDGPUABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
@@ -119,12 +119,12 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+                                QualType Ty, AggValueSlot Slot) const {
   const bool IsIndirect = false;
   const bool AllowHigherAlign = false;
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
                           getContext().getTypeInfoInChars(Ty),
-                          CharUnits::fromQuantity(4), AllowHigherAlign);
+                          CharUnits::fromQuantity(4), AllowHigherAlign, Slot);
 }
 
 ABIArgInfo AMDGPUABIInfo::classifyReturnType(QualType RetTy) const {
diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp
index 9e259d881c10d..1904e8fdb3888 100644
--- a/clang/lib/CodeGen/Targets/ARC.cpp
+++ b/clang/lib/CodeGen/Targets/ARC.cpp
@@ -24,8 +24,8 @@ class ARCABIInfo : public DefaultABIInfo {
   using DefaultABIInfo::DefaultABIInfo;
 
 private:
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   void updateState(const ABIArgInfo &Info, QualType Ty, CCState &State) const {
     if (!State.FreeRegs)
@@ -82,10 +82,10 @@ ABIArgInfo ARCABIInfo::getIndirectByValue(QualType Ty) const {
 }
 
 RValue ARCABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                             QualType Ty) const {
+                             QualType Ty, AggValueSlot Slot) const {
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
                           getContext().getTypeInfoInChars(Ty),
-                          CharUnits::fromQuantity(4), true);
+                          CharUnits::fromQuantity(4), true, Slot);
 }
 
 ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty,
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index 4214fccc120e4..bc0fa558e0c95 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -81,8 +81,8 @@ class ARMABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   llvm::CallingConv::ID getLLVMDefaultCC() const;
   llvm::CallingConv::ID getABIDefaultCC() const;
@@ -754,7 +754,7 @@ bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,
 }
 
 RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                             QualType Ty) const {
+                             QualType Ty, AggValueSlot Slot) const {
   CharUnits SlotSize = CharUnits::fromQuantity(4);
 
   // Empty records are ignored for parameter passing purposes.
@@ -762,7 +762,9 @@ RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
     auto *Load = CGF.Builder.CreateLoad(VAListAddr);
     Address Addr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
+    LValue LV = CGF.MakeAddrLValue(Addr, Ty);
+    CGF.EmitAggFinalDestCopy(Ty, Slot, LV, CodeGenFunction::EVK_RValue);
+    return Slot.asRValue();
   }
 
   CharUnits TySize = getContext().getTypeSizeInChars(Ty);
@@ -799,8 +801,8 @@ RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   }
 
   TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);
-  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo,
-                          SlotSize, /*AllowHigherAlign*/ true);
+  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,
+                          /*AllowHigherAlign*/ true, Slot);
 }
 
 std::unique_ptr<TargetCodeGenInfo>
diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp
index 0ba71352c5d4b..f2e7fab5021ea 100644
--- a/clang/lib/CodeGen/Targets/CSKY.cpp
+++ b/clang/lib/CodeGen/Targets/CSKY.cpp
@@ -33,8 +33,8 @@ class CSKYABIInfo : public DefaultABIInfo {
                                   bool isReturnType = false) const;
   ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 } // end anonymous namespace
@@ -58,20 +58,20 @@ void CSKYABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue CSKYABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                              QualType Ty) const {
+                              QualType Ty, AggValueSlot Slot) const {
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
                            CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
 
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, false, TInfo, SlotSize,
-                          /*AllowHigherAlign=*/true);
+                          /*AllowHigherAlign=*/true, Slot);
 }
 
 ABIArgInfo CSKYABIInfo::classifyArgumentType(QualType Ty, int &ArgGPRsLeft,
diff --git a/clang/lib/CodeGen/Targets/Hexagon.cpp b/clang/lib/CodeGen/Targets/Hexagon.cpp
index 2e101c91b7ebe..8fd2a81494d99 100644
--- a/clang/lib/CodeGen/Targets/Hexagon.cpp
+++ b/clang/lib/CodeGen/Targets/Hexagon.cpp
@@ -29,8 +29,8 @@ class HexagonABIInfo : public DefaultABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
   Address EmitVAArgFromMemory(CodeGenFunction &CFG, Address VAListAddr,
                               QualType Ty) const;
   Address EmitVAArgForHexagon(CodeGenFunction &CFG, Address VAListAddr,
@@ -409,14 +409,15 @@ Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF,
 }
 
 RValue HexagonABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                 QualType Ty) const {
+                                 QualType Ty, AggValueSlot Slot) const {
 
   if (getTarget().getTriple().isMusl())
     return CGF.EmitLoadOfAnyValue(
-        CGF.MakeAddrLValue(EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty), Ty));
+        CGF.MakeAddrLValue(EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty), Ty),
+        Slot);
 
   return CGF.EmitLoadOfAnyValue(
-      CGF.MakeAddrLValue(EmitVAArgForHexagon(CGF, VAListAddr, Ty), Ty));
+      CGF.MakeAddrLValue(EmitVAArgForHexagon(CGF, VAListAddr, Ty), Ty), Slot);
 }
 
 std::unique_ptr<TargetCodeGenInfo>
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 0f5b621841de0..4a3c823771f60 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -44,8 +44,8 @@ class LoongArchABIInfo : public DefaultABIInfo {
                                   int &FARsLeft) const;
   ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   ABIArgInfo extendType(QualType Ty) const;
 
@@ -418,14 +418,14 @@ ABIArgInfo LoongArchABIInfo::classifyReturnType(QualType RetTy) const {
 }
 
 RValue LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                   QualType Ty) const {
+                                   QualType Ty, AggValueSlot Slot) const {
   CharUnits SlotSize = CharUnits::fromQuantity(GRLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
                            CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
@@ -434,7 +434,7 @@ RValue LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty,
                           /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo,
                           SlotSize,
-                          /*AllowHigherAlign=*/true);
+                          /*AllowHigherAlign=*/true, Slot);
 }
 
 ABIArgInfo LoongArchABIInfo::extendType(QualType Ty) const {
diff --git a/clang/lib/CodeGen/Targets/MSP430.cpp b/clang/lib/CodeGen/Targets/MSP430.cpp
index 93d877b9eb8b1..ee3bc21467c55 100644
--- a/clang/lib/CodeGen/Targets/MSP430.cpp
+++ b/clang/lib/CodeGen/Targets/MSP430.cpp
@@ -52,9 +52,11 @@ class MSP430ABIInfo : public DefaultABIInfo {
   }
 
   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override {
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
-        EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty));
+                   QualType Ty, AggValueSlot Slot) const override {
+    return CGF.EmitLoadOfAnyValue(
+        CGF.MakeAddrLValue(
+            EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
+        Slot);
   }
 };
 
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index 137d6eb2b0fd7..06d9b6d4a5761 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -34,8 +34,8 @@ class MipsABIInfo : public ABIInfo {
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
   ABIArgInfo extendType(QualType Ty) const;
 };
 
@@ -347,7 +347,7 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                              QualType OrigTy) const {
+                              QualType OrigTy, AggValueSlot Slot) const {
   QualType Ty = OrigTy;
 
   // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64.
@@ -374,7 +374,7 @@ RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes);
 
   RValue Res = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
-                                ArgSlotSize, /*AllowHigherAlign*/ true);
+                                ArgSlotSize, /*AllowHigherAlign*/ true, Slot);
 
   // If there was a promotion, "unpromote".
   // TODO: can we just use a pointer into a subset of the original slot?
diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp
index c7abe2cd14fd4..423485c9ca16e 100644
--- a/clang/lib/CodeGen/Targets/NVPTX.cpp
+++ b/clang/lib/CodeGen/Targets/NVPTX.cpp
@@ -32,8 +32,8 @@ class NVPTXABIInfo : public ABIInfo {
   ABIArgInfo classifyArgumentType(QualType Ty) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
   bool isUnsupportedType(QualType T) const;
   ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, unsigned MaxSize) const;
 };
@@ -214,7 +214,7 @@ void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue NVPTXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                               QualType Ty) const {
+                               QualType Ty, AggValueSlot Slot) const {
   llvm_unreachable("NVPTX does not support varargs");
 }
 
diff --git a/clang/lib/CodeGen/Targets/PNaCl.cpp b/clang/lib/CodeGen/Targets/PNaCl.cpp
index 5d031f6db6fbb..9b7d757df3a39 100644
--- a/clang/lib/CodeGen/Targets/PNaCl.cpp
+++ b/clang/lib/CodeGen/Targets/PNaCl.cpp
@@ -27,8 +27,8 @@ class PNaClABIInfo : public ABIInfo {
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -46,15 +46,17 @@ void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                               QualType Ty) const {
+                               QualType Ty, AggValueSlot Slot) const {
   // The PNaCL ABI is a bit odd, in that varargs don't use normal
   // function classification. Structs get passed directly for varargs
   // functions, through a rewriting transform in
   // pnacl-llvm/lib/Transforms/NaCl/ExpandVarArgs.cpp, which allows
   // this target to actually support a va_arg instructions with an
   // aggregate type, unlike other targets.
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
-      EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty));
+  return CGF.EmitLoadOfAnyValue(
+      CGF.MakeAddrLValue(
+          EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty),
+      Slot);
 }
 
 /// Classify argument of given type \p Ty.
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index c5a402ea15cad..8a7acbe1932f8 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -126,8 +126,8 @@ class AIXABIInfo : public ABIInfo {
       I.info = classifyArgumentType(I.type);
   }
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -237,7 +237,7 @@ CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const {
 }
 
 RValue AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                             QualType Ty) const {
+                             QualType Ty, AggValueSlot Slot) const {
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
   TypeInfo.Align = getParamTypeAlignment(Ty);
@@ -258,7 +258,7 @@ RValue AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   }
 
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
-                          SlotSize, /*AllowHigher*/ true);
+                          SlotSize, /*AllowHigher*/ true, Slot);
 }
 
 bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable(
@@ -346,7 +346,7 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   }
 
   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+                   QualType Ty, AggValueSlot Slot) const override;
 };
 
 class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -424,7 +424,7 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
 // TODO: this implementation is now likely redundant with
 // DefaultABIInfo::EmitVAArg.
 RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
-                                     QualType Ty) const {
+                                     QualType Ty, AggValueSlot Slot) const {
   if (getTarget().getTriple().isOSDarwin()) {
     auto TI = getContext().getTypeInfoInChars(Ty);
     TI.Align = getParamTypeAlignment(Ty);
@@ -432,7 +432,7 @@ RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
     CharUnits SlotSize = CharUnits::fromQuantity(4);
     return emitVoidPtrVAArg(CGF, VAList, Ty,
                             classifyArgumentType(Ty).isIndirect(), TI, SlotSize,
-                            /*AllowHigherAlign=*/true);
+                            /*AllowHigherAlign=*/true, Slot);
   }
 
   const unsigned OverflowLimit = 8;
@@ -574,7 +574,7 @@ RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
                      getContext().getTypeAlignInChars(Ty));
   }
 
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Result, Ty));
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Result, Ty), Slot);
 }
 
 bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
@@ -655,8 +655,8 @@ class PPC64_SVR4_ABIInfo : public ABIInfo {
     }
   }
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -956,7 +956,7 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
 
 // Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine.
 RValue PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                     QualType Ty) const {
+                                     QualType Ty, AggValueSlot Slot) const {
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
   TypeInfo.Align = getParamTypeAlignment(Ty);
 
@@ -988,7 +988,7 @@ RValue PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   // types this way, and so right-alignment only applies to fundamental types.
   // So on PPC64, we must force the use of right-alignment even for aggregates.
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
-                          SlotSize, /*AllowHigher*/ true,
+                          SlotSize, /*AllowHigher*/ true, Slot,
                           /*ForceRightAdjust*/ true);
 }
 
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index 6039dabb2f773..1e49f74a247cc 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -48,8 +48,8 @@ class RISCVABIInfo : public DefaultABIInfo {
                                   int &ArgFPRsLeft) const;
   ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   ABIArgInfo extendType(QualType Ty) const;
 
@@ -490,14 +490,15 @@ ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy) const {
 }
 
 RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                               QualType Ty) const {
+                               QualType Ty, AggValueSlot Slot) const {
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
                            CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
+
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
@@ -513,7 +514,7 @@ RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   bool IsIndirect = TInfo.Width > 2 * SlotSize;
 
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo,
-                          SlotSize, /*AllowHigherAlign=*/true);
+                          SlotSize, /*AllowHigherAlign=*/true, Slot);
 }
 
 ABIArgInfo RISCVABIInfo::extendType(QualType Ty) const {
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index 8f077f5c88e66..36e4a890e28f4 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -111,8 +111,8 @@ class SparcV9ABIInfo : public ABIInfo {
 private:
   ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit) const;
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   // Coercion type builder for structs passed in registers. The coercion type
   // serves two purposes:
@@ -279,7 +279,7 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const {
 }
 
 RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                 QualType Ty) const {
+                                 QualType Ty, AggValueSlot Slot) const {
   ABIArgInfo AI = classifyType(Ty, 16 * 8);
   llvm::Type *ArgTy = CGT.ConvertType(Ty);
   if (AI.canHaveCoerceToType() && !AI.getCoerceToType())
@@ -325,8 +325,11 @@ RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     break;
 
   case ABIArgInfo::Ignore:
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(
-        Address(llvm::UndefValue::get(ArgPtrTy), ArgTy, TypeInfo.Align), Ty));
+    return CGF.EmitLoadOfAnyValue(
+        CGF.MakeAddrLValue(
+            Address(llvm::UndefValue::get(ArgPtrTy), ArgTy, TypeInfo.Align),
+            Ty),
+        Slot);
   }
 
   // Update VAList.
@@ -334,7 +337,7 @@ RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr);
 
   return CGF.EmitLoadOfAnyValue(
-      CGF.MakeAddrLValue(ArgAddr.withElementType(ArgTy), Ty));
+      CGF.MakeAddrLValue(ArgAddr.withElementType(ArgTy), Ty), Slot);
 }
 
 void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const {
diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp
index fa393726bdf55..e6b63b6fe093f 100644
--- a/clang/lib/CodeGen/Targets/SystemZ.cpp
+++ b/clang/lib/CodeGen/Targets/SystemZ.cpp
@@ -38,8 +38,8 @@ class SystemZABIInfo : public ABIInfo {
   ABIArgInfo classifyArgumentType(QualType ArgTy) const;
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -244,7 +244,7 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
 }
 
 RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                 QualType Ty) const {
+                                 QualType Ty, AggValueSlot Slot) const {
   // Assume that va_list type is correct; should be pointer to LLVM type:
   // struct {
   //   i64 __gpr;
@@ -310,7 +310,7 @@ RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
         PaddedSizeV, "overflow_arg_area");
     CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
 
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(MemAddr, Ty));
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(MemAddr, Ty), Slot);
   }
 
   assert(PaddedSize.getQuantity() == 8);
@@ -397,7 +397,7 @@ RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), ArgTy,
                       TyInfo.Align);
 
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty));
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
 }
 
 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp
index ddbc3c7ded6a0..70a968fe93ca7 100644
--- a/clang/lib/CodeGen/Targets/WebAssembly.cpp
+++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp
@@ -41,8 +41,8 @@ class WebAssemblyABIInfo final : public ABIInfo {
       Arg.info = classifyArgumentType(Arg.type);
   }
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo {
@@ -156,14 +156,14 @@ ABIArgInfo WebAssemblyABIInfo::classifyReturnType(QualType RetTy) const {
 }
 
 RValue WebAssemblyABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                     QualType Ty) const {
+                                     QualType Ty, AggValueSlot Slot) const {
   bool IsIndirect = isAggregateTypeForABI(Ty) &&
                     !isEmptyRecord(getContext(), Ty, true) &&
                     !isSingleElementStruct(Ty, getContext());
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
                           getContext().getTypeInfoInChars(Ty),
                           CharUnits::fromQuantity(4),
-                          /*AllowHigherAlign=*/true);
+                          /*AllowHigherAlign=*/true, Slot);
 }
 
 std::unique_ptr<TargetCodeGenInfo>
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index adb0aa91ddfcb..a648b004d0cff 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -173,8 +173,8 @@ class X86_32ABIInfo : public ABIInfo {
 public:
 
   void computeInfo(CGFunctionInfo &FI) const override;
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI,
                 bool RetSmallStructInRegABI, bool Win32StructABI,
@@ -1067,15 +1067,17 @@ void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const {
 }
 
 RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+                                QualType Ty, AggValueSlot Slot) const {
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
 
   CCState State(*const_cast<CGFunctionInfo *>(CGF.CurFnInfo));
   ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
   // Empty records are ignored for parameter passing purposes.
-  if (AI.isIgnore())
-    return RValue::getAggregate(CGF.CreateMemTemp(Ty));
+  if (AI.isIgnore()) {
+    Address Addr = CGF.CreateMemTemp(Ty);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
+  }
 
   // x86-32 changes the alignment of certain arguments on the stack.
   //
@@ -1086,7 +1088,7 @@ RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
 
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false,
                           TypeInfo, CharUnits::fromQuantity(4),
-                          /*AllowHigherAlign*/ true);
+                          /*AllowHigherAlign*/ true, Slot);
 }
 
 bool X86_32TargetCodeGenInfo::isStructReturnInRegABI(
@@ -1368,9 +1370,9 @@ class X86_64ABIInfo : public ABIInfo {
   void computeInfo(CGFunctionInfo &FI) const override;
 
   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
-  RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                     QualType Ty) const override;
+                   QualType Ty, AggValueSlot Slot) const override;
+  RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                     AggValueSlot Slot) const override;
 
   bool has64BitPointers() const {
     return Has64BitPointers;
@@ -1387,7 +1389,7 @@ class WinX86_64ABIInfo : public ABIInfo {
   void computeInfo(CGFunctionInfo &FI) const override;
 
   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+                   QualType Ty, AggValueSlot Slot) const override;
 
   bool isHomogeneousAggregateBaseType(QualType Ty) const override {
     // FIXME: Assumes vectorcall is in use.
@@ -3021,7 +3023,7 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
 }
 
 RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                QualType Ty) const {
+                                QualType Ty, AggValueSlot Slot) const {
   // Assume that va_list type is correct; should be pointer to LLVM type:
   // struct {
   //   i32 gp_offset;
@@ -3036,14 +3038,17 @@ RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                        /*isNamedArg*/false);
 
   // Empty records are ignored for parameter passing purposes.
-  if (AI.isIgnore())
-    return RValue::getAggregate(CGF.CreateMemTemp(Ty));
+  if (AI.isIgnore()) {
+    Address Addr = CGF.CreateMemTemp(Ty);
+    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
+  }
 
   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
   // in the registers. If not go to step 7.
   if (!neededInt && !neededSSE)
     return CGF.EmitLoadOfAnyValue(
-        CGF.MakeAddrLValue(EmitX86_64VAArgFromMemory(CGF, VAListAddr, Ty), Ty));
+        CGF.MakeAddrLValue(EmitX86_64VAArgFromMemory(CGF, VAListAddr, Ty), Ty),
+        Slot);
 
   // AMD64-ABI 3.5.7p5: Step 2. Compute num_gp to hold the number of
   // general purpose registers needed to pass type and num_fp to hold
@@ -3206,11 +3211,11 @@ RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CGF.EmitBlock(ContBlock);
   Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock,
                                  "vaarg.addr");
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty));
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
 }
 
 RValue X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                  QualType Ty) const {
+                                  QualType Ty, AggValueSlot Slot) const {
   // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is
   // not 1, 2, 4, or 8 bytes, must be passed by reference."
   uint64_t Width = getContext().getTypeSize(Ty);
@@ -3219,7 +3224,7 @@ RValue X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
                           CGF.getContext().getTypeInfoInChars(Ty),
                           CharUnits::fromQuantity(8),
-                          /*allowHigherAlign*/ false);
+                          /*allowHigherAlign*/ false, Slot);
 }
 
 ABIArgInfo WinX86_64ABIInfo::reclassifyHvaArgForVectorCall(
@@ -3412,7 +3417,7 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
 }
 
 RValue WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                                   QualType Ty) const {
+                                   QualType Ty, AggValueSlot Slot) const {
   // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is
   // not 1, 2, 4, or 8 bytes, must be passed by reference."
   uint64_t Width = getContext().getTypeSize(Ty);
@@ -3421,7 +3426,7 @@ RValue WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
                           CGF.getContext().getTypeInfoInChars(Ty),
                           CharUnits::fromQuantity(8),
-                          /*allowHigherAlign*/ false);
+                          /*allowHigherAlign*/ false, Slot);
 }
 
 std::unique_ptr<TargetCodeGenInfo> CodeGen::createX86_32TargetCodeGenInfo(
diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp
index 23f08a4f85d54..f3e241171b872 100644
--- a/clang/lib/CodeGen/Targets/XCore.cpp
+++ b/clang/lib/CodeGen/Targets/XCore.cpp
@@ -113,8 +113,8 @@ class FieldEncoding {
 class XCoreABIInfo : public DefaultABIInfo {
 public:
   XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class XCoreTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -135,7 +135,7 @@ class XCoreTargetCodeGenInfo : public TargetCodeGenInfo {
 // TODO: this implementation is likely now redundant with the default
 // EmitVAArg.
 RValue XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                               QualType Ty) const {
+                               QualType Ty, AggValueSlot Slot) const {
   CGBuilderTy &Builder = CGF.Builder;
 
   // Get the VAList.
@@ -183,7 +183,7 @@ RValue XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     Builder.CreateStore(APN.emitRawPointer(CGF), VAListAddr);
   }
 
-  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Val, Ty));
+  return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Val, Ty), Slot);
 }
 
 /// During the expansion of a RecordType, an incomplete TypeString is placed

>From 663bb93ed4ce97831f236efcb90458b4b21811ae Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 12 Jun 2024 01:12:48 -0700
Subject: [PATCH 05/10] Check all ABIs in MIPS test

---
 clang/test/CodeGen/mips-varargs.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/test/CodeGen/mips-varargs.c b/clang/test/CodeGen/mips-varargs.c
index 8fdffc87675e7..0c22b43600dac 100644
--- a/clang/test/CodeGen/mips-varargs.c
+++ b/clang/test/CodeGen/mips-varargs.c
@@ -39,8 +39,8 @@ int test_i32(char *fmt, ...) {
 //
 // N32:   [[TMP:%.+]] = load i64, ptr [[AP_CUR]], align [[CHUNKALIGN:8]]
 // N64:   [[TMP:%.+]] = load i64, ptr [[AP_CUR]], align [[CHUNKALIGN:8]]
-// NEW:   [[TMP2:%.+]] = trunc i64 [[TMP]] to i32
-// NEW:   store i32 [[TMP2]], ptr [[V]], align 4
+// NEW:   [[ARG:%.+]] = trunc i64 [[TMP]] to i32
+// ALL:   store i32 [[ARG]], ptr [[V]], align 4
 //
 // ALL:   call void @llvm.va_end.p0(ptr %va)
 // ALL: }
@@ -98,7 +98,9 @@ char *test_ptr(char *fmt, ...) {
 // N32:   [[TMP2:%.+]] = load i64, ptr [[AP_CUR]], align 8
 // N32:   [[TMP3:%.+]] = trunc i64 [[TMP2]] to i32
 // N32:   [[PTR:%.+]] = inttoptr i32 [[TMP3]] to ptr
-// N32:   store ptr [[PTR]], ptr [[V]], align 4
+// O32:   [[PTR:%.+]] = load ptr, ptr [[AP_CUR]], align [[$PTRALIGN]]
+// N64:   [[PTR:%.+]] = load ptr, ptr [[AP_CUR]], align [[$PTRALIGN]]
+// ALL:   store ptr [[PTR]], ptr [[V]], align [[$PTRALIGN]]
 //
 // ALL:   call void @llvm.va_end.p0(ptr %va)
 // ALL: }

>From 300521cd05c6897b4e74d3be44c4cd689c012b56 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 12 Jun 2024 01:32:16 -0700
Subject: [PATCH 06/10] Pass EVK_NonRValue

---
 clang/lib/CodeGen/CGExpr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 54b56019755d3..6ad65ca82f0df 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2170,7 +2170,7 @@ RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, AggValueSlot Slot,
   case TEK_Complex:
     return RValue::getComplex(EmitLoadOfComplex(LV, Loc));
   case TEK_Aggregate:
-    EmitAggFinalDestCopy(Ty, Slot, LV, EVK_RValue);
+    EmitAggFinalDestCopy(Ty, Slot, LV, EVK_NonRValue);
     return Slot.asRValue();
   }
   llvm_unreachable("bad evaluation kind");

>From fb790e6dfecde3a20028edfa7676e1571eb56cc7 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 12 Jun 2024 02:01:02 -0700
Subject: [PATCH 07/10] Do not copy empty records

---
 clang/lib/CodeGen/Targets/AArch64.cpp   |  4 ++--
 clang/lib/CodeGen/Targets/ARM.cpp       |  4 +---
 clang/lib/CodeGen/Targets/CSKY.cpp      |  2 +-
 clang/lib/CodeGen/Targets/LoongArch.cpp |  2 +-
 clang/lib/CodeGen/Targets/RISCV.cpp     |  3 +--
 clang/lib/CodeGen/Targets/X86.cpp       | 12 ++++--------
 clang/test/CodeGen/X86/x86_64-vaarg.c   |  3 ---
 clang/test/CodeGenCXX/x86_32-vaarg.cpp  |  1 -
 clang/test/CodeGenCXX/x86_64-vaarg.cpp  |  3 ---
 9 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index e3b2b144cff8b..678394cfbf6b3 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -562,7 +562,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
     VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
     auto *Load = CGF.Builder.CreateLoad(VAListAddr);
     Address ResAddr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
+    return RValue::getAggregate(ResAddr);
   }
 
   bool IsIndirect = AI.isIndirect();
@@ -820,7 +820,7 @@ RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address ResAddr = Address(CGF.Builder.CreateLoad(VAListAddr, "ap.cur"),
                               CGF.ConvertTypeForMem(Ty), SlotSize);
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
+    return RValue::getAggregate(ResAddr);
   }
 
   // The size of the actual thing passed, which might end up just
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index bc0fa558e0c95..79eda711da5e7 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -762,9 +762,7 @@ RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
     auto *Load = CGF.Builder.CreateLoad(VAListAddr);
     Address Addr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
-    LValue LV = CGF.MakeAddrLValue(Addr, Ty);
-    CGF.EmitAggFinalDestCopy(Ty, Slot, LV, CodeGenFunction::EVK_RValue);
-    return Slot.asRValue();
+    return RValue::getAggregate(Addr);
   }
 
   CharUnits TySize = getContext().getTypeSizeInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp
index f2e7fab5021ea..2f9a31c10d809 100644
--- a/clang/lib/CodeGen/Targets/CSKY.cpp
+++ b/clang/lib/CodeGen/Targets/CSKY.cpp
@@ -65,7 +65,7 @@ RValue CSKYABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
                            CGF.ConvertTypeForMem(Ty), SlotSize);
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
+    return RValue::getAggregate(Addr);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 4a3c823771f60..f16e30c79a25d 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -425,7 +425,7 @@ RValue LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
                            CGF.ConvertTypeForMem(Ty), SlotSize);
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
+    return RValue::getAggregate(Addr);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index 1e49f74a247cc..321be434e7e40 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -497,8 +497,7 @@ RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   if (isEmptyRecord(getContext(), Ty, true)) {
     Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
                            CGF.ConvertTypeForMem(Ty), SlotSize);
-
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
+    return RValue::getAggregate(Addr);
   }
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index a648b004d0cff..0ed8440952f98 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1074,10 +1074,8 @@ RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CCState State(*const_cast<CGFunctionInfo *>(CGF.CurFnInfo));
   ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
   // Empty records are ignored for parameter passing purposes.
-  if (AI.isIgnore()) {
-    Address Addr = CGF.CreateMemTemp(Ty);
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
-  }
+  if (AI.isIgnore())
+    return RValue::getIgnored();
 
   // x86-32 changes the alignment of certain arguments on the stack.
   //
@@ -3038,10 +3036,8 @@ RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                        /*isNamedArg*/false);
 
   // Empty records are ignored for parameter passing purposes.
-  if (AI.isIgnore()) {
-    Address Addr = CGF.CreateMemTemp(Ty);
-    return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, Ty), Slot);
-  }
+  if (AI.isIgnore())
+    return RValue::getIgnored();
 
   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
   // in the registers. If not go to step 7.
diff --git a/clang/test/CodeGen/X86/x86_64-vaarg.c b/clang/test/CodeGen/X86/x86_64-vaarg.c
index 07c6df14a0b81..d6b885d9fb18c 100644
--- a/clang/test/CodeGen/X86/x86_64-vaarg.c
+++ b/clang/test/CodeGen/X86/x86_64-vaarg.c
@@ -7,15 +7,12 @@ typedef struct { struct {} a; } empty;
 // CHECK-LABEL: define dso_local void @empty_record_test(
 // CHECK-SAME: i32 noundef [[Z:%.*]], ...) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
 // CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[LIST:%.*]] = alloca [1 x %struct.__va_list_tag], align 16
-// CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_EMPTY]], align 1
 // CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[LIST]], i64 0, i64 0
 // CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[ARRAYDECAY]])
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[LIST]], i64 0, i64 0
-// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[RETVAL]], ptr align 1 [[TMP]], i64 0, i1 false)
 // CHECK-NEXT:    ret void
 //
 empty empty_record_test(int z, ...) {
diff --git a/clang/test/CodeGenCXX/x86_32-vaarg.cpp b/clang/test/CodeGenCXX/x86_32-vaarg.cpp
index dcc2f7f96a40f..a3f2791484362 100644
--- a/clang/test/CodeGenCXX/x86_32-vaarg.cpp
+++ b/clang/test/CodeGenCXX/x86_32-vaarg.cpp
@@ -8,7 +8,6 @@ typedef struct {} empty;
 // CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4
 // CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[LIST:%.*]] = alloca ptr, align 4
-// CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
 // CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4
 // CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
 // CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[LIST]])
diff --git a/clang/test/CodeGenCXX/x86_64-vaarg.cpp b/clang/test/CodeGenCXX/x86_64-vaarg.cpp
index 985a0cc41a141..c4616a97e2055 100644
--- a/clang/test/CodeGenCXX/x86_64-vaarg.cpp
+++ b/clang/test/CodeGenCXX/x86_64-vaarg.cpp
@@ -5,15 +5,12 @@ typedef struct { struct {} a; } empty;
 
 // CHECK-LABEL: @_Z17empty_record_testiz(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
 // CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[LIST:%.*]] = alloca [1 x %struct.__va_list_tag], align 16
-// CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_EMPTY]], align 1
 // CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[LIST]], i64 0, i64 0
 // CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[ARRAYDECAY]])
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[LIST]], i64 0, i64 0
-// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[RETVAL]], ptr align 1 [[TMP]], i64 1, i1 false)
 // CHECK-NEXT:    ret void
 //
 empty empty_record_test(int z, ...) {

>From 13e52fe2766115d4bf0e72444b3b77c59006fc5f Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 12 Jun 2024 04:46:10 -0700
Subject: [PATCH 08/10] Fix format

---
 clang/lib/CodeGen/Targets/MSP430.cpp |  4 ++--
 clang/lib/CodeGen/Targets/PPC.cpp    |  4 ++--
 clang/lib/CodeGen/Targets/RISCV.cpp  |  4 ++--
 clang/lib/CodeGen/Targets/X86.cpp    | 12 ++++++------
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/MSP430.cpp b/clang/lib/CodeGen/Targets/MSP430.cpp
index ee3bc21467c55..8ce70e2111ccf 100644
--- a/clang/lib/CodeGen/Targets/MSP430.cpp
+++ b/clang/lib/CodeGen/Targets/MSP430.cpp
@@ -51,8 +51,8 @@ class MSP430ABIInfo : public DefaultABIInfo {
       I.info = classifyArgumentType(I.type);
   }
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty, AggValueSlot Slot) const override {
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override {
     return CGF.EmitLoadOfAnyValue(
         CGF.MakeAddrLValue(
             EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 8a7acbe1932f8..e4155810963eb 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -345,8 +345,8 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
       I.info = classifyArgumentType(I.type);
   }
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty, AggValueSlot Slot) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 };
 
 class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index 321be434e7e40..474564ddcad36 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -512,8 +512,8 @@ RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   // Arguments bigger than 2*Xlen bytes are passed indirectly.
   bool IsIndirect = TInfo.Width > 2 * SlotSize;
 
-  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo,
-                          SlotSize, /*AllowHigherAlign=*/true, Slot);
+  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo, SlotSize,
+                          /*AllowHigherAlign=*/true, Slot);
 }
 
 ABIArgInfo RISCVABIInfo::extendType(QualType Ty) const {
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 0ed8440952f98..1a1fc6bbfaba5 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1084,8 +1084,8 @@ RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   TypeInfo.Align = CharUnits::fromQuantity(
                 getTypeStackAlignInBytes(Ty, TypeInfo.Align.getQuantity()));
 
-  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false,
-                          TypeInfo, CharUnits::fromQuantity(4),
+  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
+                          CharUnits::fromQuantity(4),
                           /*AllowHigherAlign*/ true, Slot);
 }
 
@@ -1367,8 +1367,8 @@ class X86_64ABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty, AggValueSlot Slot) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
   RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
                      AggValueSlot Slot) const override;
 
@@ -1386,8 +1386,8 @@ class WinX86_64ABIInfo : public ABIInfo {
 
   void computeInfo(CGFunctionInfo &FI) const override;
 
-  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
-                   QualType Ty, AggValueSlot Slot) const override;
+  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+                   AggValueSlot Slot) const override;
 
   bool isHomogeneousAggregateBaseType(QualType Ty) const override {
     // FIXME: Assumes vectorcall is in use.

>From 34a384aa9233a84dc7ae048c77c06a2213f270be Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Thu, 13 Jun 2024 01:11:51 -0700
Subject: [PATCH 09/10] Do not create load for empty records

---
 clang/lib/CodeGen/Targets/AArch64.cpp        | 17 ++++-------------
 clang/lib/CodeGen/Targets/ARM.cpp            |  8 ++------
 clang/lib/CodeGen/Targets/CSKY.cpp           |  7 ++-----
 clang/lib/CodeGen/Targets/LoongArch.cpp      |  7 ++-----
 clang/lib/CodeGen/Targets/RISCV.cpp          |  7 ++-----
 clang/lib/CodeGen/Targets/X86.cpp            |  4 ++--
 clang/test/CodeGen/aarch64-varargs.c         |  1 -
 clang/test/CodeGen/arm-vaarg.c               |  3 +--
 clang/test/CodeGenCXX/arm64-empty-struct.cpp |  1 -
 9 files changed, 15 insertions(+), 40 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 678394cfbf6b3..cfb4b5f58ef72 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -556,14 +556,8 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
   ABIArgInfo AI = classifyArgumentType(Ty, /*IsVariadic=*/true,
                                        CGF.CurFnInfo->getCallingConvention());
   // Empty records are ignored for parameter passing purposes.
-  if (AI.isIgnore()) {
-    uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
-    CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
-    VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
-    auto *Load = CGF.Builder.CreateLoad(VAListAddr);
-    Address ResAddr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(ResAddr);
-  }
+  if (AI.isIgnore())
+    return Slot.asRValue();
 
   bool IsIndirect = AI.isIndirect();
 
@@ -817,11 +811,8 @@ RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
   CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true)) {
-    Address ResAddr = Address(CGF.Builder.CreateLoad(VAListAddr, "ap.cur"),
-                              CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(ResAddr);
-  }
+  if (isEmptyRecord(getContext(), Ty, true))
+    return Slot.asRValue();
 
   // The size of the actual thing passed, which might end up just
   // being a pointer for indirect types.
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index 79eda711da5e7..f362e34f38dea 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -758,12 +758,8 @@ RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CharUnits SlotSize = CharUnits::fromQuantity(4);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true)) {
-    VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
-    auto *Load = CGF.Builder.CreateLoad(VAListAddr);
-    Address Addr = Address(Load, CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
-  }
+  if (isEmptyRecord(getContext(), Ty, true))
+    return Slot.asRValue();
 
   CharUnits TySize = getContext().getTypeSizeInChars(Ty);
   CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);
diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp
index 2f9a31c10d809..d8720afd1a713 100644
--- a/clang/lib/CodeGen/Targets/CSKY.cpp
+++ b/clang/lib/CodeGen/Targets/CSKY.cpp
@@ -62,11 +62,8 @@ RValue CSKYABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true)) {
-    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
-                           CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
-  }
+  if (isEmptyRecord(getContext(), Ty, true))
+    return Slot.asRValue();
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
 
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index f16e30c79a25d..6af9375461f09 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -422,11 +422,8 @@ RValue LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CharUnits SlotSize = CharUnits::fromQuantity(GRLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true)) {
-    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
-                           CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
-  }
+  if (isEmptyRecord(getContext(), Ty, true))
+    return Slot.asRValue();
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
 
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index 474564ddcad36..a4c5ec315b8df 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -494,11 +494,8 @@ RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
 
   // Empty records are ignored for parameter passing purposes.
-  if (isEmptyRecord(getContext(), Ty, true)) {
-    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
-                           CGF.ConvertTypeForMem(Ty), SlotSize);
-    return RValue::getAggregate(Addr);
-  }
+  if (isEmptyRecord(getContext(), Ty, true))
+    return Slot.asRValue();
 
   auto TInfo = getContext().getTypeInfoInChars(Ty);
 
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 1a1fc6bbfaba5..3146caba1c615 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1075,7 +1075,7 @@ RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
   // Empty records are ignored for parameter passing purposes.
   if (AI.isIgnore())
-    return RValue::getIgnored();
+    return Slot.asRValue();
 
   // x86-32 changes the alignment of certain arguments on the stack.
   //
@@ -3037,7 +3037,7 @@ RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
 
   // Empty records are ignored for parameter passing purposes.
   if (AI.isIgnore())
-    return RValue::getIgnored();
+    return Slot.asRValue();
 
   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
   // in the registers. If not go to step 7.
diff --git a/clang/test/CodeGen/aarch64-varargs.c b/clang/test/CodeGen/aarch64-varargs.c
index 8952d6980a8d3..56fcff8ef0a6a 100644
--- a/clang/test/CodeGen/aarch64-varargs.c
+++ b/clang/test/CodeGen/aarch64-varargs.c
@@ -834,5 +834,4 @@ typedef struct {} empty;
 empty empty_record_test(void) {
 // CHECK-LABEL: define{{.*}} void @empty_record_test()
   return va_arg(the_list, empty);
-// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load ptr, ptr @the_list
 }
diff --git a/clang/test/CodeGen/arm-vaarg.c b/clang/test/CodeGen/arm-vaarg.c
index bed008039274a..b2be7405717bb 100644
--- a/clang/test/CodeGen/arm-vaarg.c
+++ b/clang/test/CodeGen/arm-vaarg.c
@@ -7,13 +7,12 @@ struct Empty emptyvar;
 void take_args(int a, ...) {
 // CHECK: [[ALLOCA_VA_LIST:%[a-zA-Z0-9._]+]] = alloca %struct.__va_list, align 4
 // CHECK: call void @llvm.va_start
-// CHECK-NEXT: [[LOAD_AP:%[a-zA-Z0-9._]+]] = load ptr, ptr [[ALLOCA_VA_LIST]], align 4
 
   // It's conceivable that EMPTY_PTR may not actually be a valid pointer
   // (e.g. it's at the very bottom of the stack and the next page is
   // invalid). This doesn't matter provided it's never loaded (there's no
   // well-defined way to tell), but it becomes a problem if we do try to use it.
-// CHECK-NOT: load %struct.Empty, ptr [[LOAD_AP]]
+// CHECK-NOT: load %struct.Empty
   __builtin_va_list l;
   __builtin_va_start(l, a);
   emptyvar = __builtin_va_arg(l, struct Empty);
diff --git a/clang/test/CodeGenCXX/arm64-empty-struct.cpp b/clang/test/CodeGenCXX/arm64-empty-struct.cpp
index c6009056f228e..99244e3b04dcb 100644
--- a/clang/test/CodeGenCXX/arm64-empty-struct.cpp
+++ b/clang/test/CodeGenCXX/arm64-empty-struct.cpp
@@ -9,7 +9,6 @@ int take_args(int a, ...) {
 // CHECK: call void @llvm.va_start
 
   emptyvar = __builtin_va_arg(l, Empty);
-// CHECK: load ptr, ptr
 // CHECK-NOT: getelementptr
 
   // It's conceivable that EMPTY_PTR may not actually be a valid pointer

>From e5c734ec4a1048eff8e68cb10c28ac4144f1685f Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Fri, 14 Jun 2024 08:28:29 -0700
Subject: [PATCH 10/10] Return Slot.asRValue() for sparc and adjust the test

---
 clang/lib/CodeGen/Targets/Sparc.cpp  | 6 +-----
 clang/test/CodeGen/aarch64-varargs.c | 2 ++
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index 36e4a890e28f4..da8c7219be263 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -325,11 +325,7 @@ RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
     break;
 
   case ABIArgInfo::Ignore:
-    return CGF.EmitLoadOfAnyValue(
-        CGF.MakeAddrLValue(
-            Address(llvm::UndefValue::get(ArgPtrTy), ArgTy, TypeInfo.Align),
-            Ty),
-        Slot);
+    return Slot.asRValue();
   }
 
   // Update VAList.
diff --git a/clang/test/CodeGen/aarch64-varargs.c b/clang/test/CodeGen/aarch64-varargs.c
index 56fcff8ef0a6a..5166b87ecc2df 100644
--- a/clang/test/CodeGen/aarch64-varargs.c
+++ b/clang/test/CodeGen/aarch64-varargs.c
@@ -833,5 +833,7 @@ void check_start(int n, ...) {
 typedef struct {} empty;
 empty empty_record_test(void) {
 // CHECK-LABEL: define{{.*}} void @empty_record_test()
+// CHECK: entry
+// CHECK-NEXT: ret void
   return va_arg(the_list, empty);
 }



More information about the cfe-commits mailing list