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

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 6 09:11:49 PDT 2024


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

This should simplify handling of resulting value by the callers.

>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] [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]]
 }



More information about the cfe-commits mailing list