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.podchishcha...@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]] } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits