[clang] e9bf0a7 - [CodeGen] Store the return value of the target function call to the

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 10 17:24:35 PDT 2020


Author: Akira Hatanaka
Date: 2020-07-10T17:24:13-07:00
New Revision: e9bf0a710c993b932fa69c95ef6d0130fd721115

URL: https://github.com/llvm/llvm-project/commit/e9bf0a710c993b932fa69c95ef6d0130fd721115
DIFF: https://github.com/llvm/llvm-project/commit/e9bf0a710c993b932fa69c95ef6d0130fd721115.diff

LOG: [CodeGen] Store the return value of the target function call to the
thunk's return value slot directly when the return type is an aggregate
instead of doing so via a temporary

This fixes PR45997 (https://bugs.llvm.org/show_bug.cgi?id=45997), which
is caused by a bug that has existed since we started passing and
returning C++ structs with ObjC strong pointer members (see
https://reviews.llvm.org/D44908) or structs annotated with trivial_abi
directly.

rdar://problem/63740936

Differential Revision: https://reviews.llvm.org/D82513

Added: 
    

Modified: 
    clang/lib/CodeGen/CGCXXABI.cpp
    clang/lib/CodeGen/CGVTables.cpp
    clang/test/CodeGenCXX/trivial_abi.cpp
    clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 928fbaea8278..3d65c0ea805e 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -156,6 +156,7 @@ void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) {
 
 void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
                                    RValue RV, QualType ResultType) {
+  assert(!hasAggregateEvaluationKind(ResultType) && "cannot handle aggregates");
   CGF.EmitReturnOfRValue(RV, ResultType);
 }
 

diff  --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 276993581117..65b3b0c5f53d 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -363,7 +363,8 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
                                   : FPT->getReturnType();
   ReturnValueSlot Slot;
   if (!ResultType->isVoidType() &&
-      CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect)
+      (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect ||
+       hasAggregateEvaluationKind(ResultType)))
     Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified(),
                            /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
 

diff  --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp
index e7e7f840944d..cb9b9dfeb4bd 100644
--- a/clang/test/CodeGenCXX/trivial_abi.cpp
+++ b/clang/test/CodeGenCXX/trivial_abi.cpp
@@ -43,6 +43,31 @@ struct HasNonTrivial {
   NonTrivial m;
 };
 
+struct B0 {
+  virtual Small m0();
+};
+
+struct B1 {
+  virtual Small m0();
+};
+
+struct D0 : B0, B1 {
+  Small m0() override;
+};
+
+// CHECK-LABEL: define i64 @_ZThn8_N2D02m0Ev(
+// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_SMALL]], align 8
+// CHECK: %[[CALL:.*]] = tail call i64 @_ZN2D02m0Ev(
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[RETVAL]], i32 0, i32 0
+// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i32*
+// CHECK: store i32* %[[COERCE_VAL_IP]], i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[COERCE_DIVE2:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[RETVAL]], i32 0, i32 0
+// CHECK: %[[V3:.*]] = load i32*, i32** %[[COERCE_DIVE2]], align 8
+// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i32* %[[V3]] to i64
+// CHECK: ret i64 %[[COERCE_VAL_PI]]
+
+Small D0::m0() { return {}; }
+
 // CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
 // CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0

diff  --git a/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm b/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm
index 7a7781f68891..d19534f6922d 100644
--- a/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm
+++ b/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm
@@ -178,3 +178,32 @@ void testParamContainsNonTrivial(ContainsNonTrivial a) {
 void testCallContainsNonTrivial(ContainsNonTrivial *a) {
   testParamContainsNonTrivial(*a);
 }
+
+namespace testThunk {
+
+// CHECK-LABEL: define i64 @_ZThn8_N9testThunk2D02m0Ev(
+// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8
+// CHECK: %[[CALL:.*]] = tail call i64 @_ZN9testThunk2D02m0Ev(
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0
+// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i8*
+// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8
+// CHECK: %[[COERCE_DIVE2:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0
+// CHECK: %[[V3:.*]] = load i8*, i8** %[[COERCE_DIVE2]], align 8
+// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V3]] to i64
+// CHECK: ret i64 %[[COERCE_VAL_PI]]
+
+struct B0 {
+  virtual Strong m0();
+};
+
+struct B1 {
+  virtual Strong m0();
+};
+
+struct D0 : B0, B1 {
+  Strong m0() override;
+};
+
+Strong D0::m0() { return {}; }
+
+}


        


More information about the cfe-commits mailing list