[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