[clang] 80a1b95 - [SystemZ ABI] Allow class types in GetSingleElementType

Ulrich Weigand via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 7 10:56:58 PDT 2020


Author: Ulrich Weigand
Date: 2020-07-07T19:56:19+02:00
New Revision: 80a1b95b8e72674cef7efb39636dc73c248ae6f3

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

LOG: [SystemZ ABI] Allow class types in GetSingleElementType

The SystemZ ABI specifies that aggregate types with just a single
member of floating-point type shall be passed as if they were just
a scalar of that type.  This applies to both struct and class types
(but not unions).

However, the current ABI support code in clang only checks this
case for struct types, which means that for class types, generated
code does not adhere to the platform ABI.

Fixed by accepting both struct and class types in the
SystemZABIInfo::GetSingleElementType routine.

Added: 
    

Modified: 
    clang/lib/CodeGen/TargetInfo.cpp
    clang/test/CodeGen/systemz-abi.c
    clang/test/CodeGen/systemz-abi.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 7947aff6cc2f..801adc29acd1 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -7208,7 +7208,9 @@ bool SystemZABIInfo::isFPArgumentType(QualType Ty) const {
 }
 
 QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
-  if (const RecordType *RT = Ty->getAsStructureType()) {
+  const RecordType *RT = Ty->getAs<RecordType>();
+
+  if (RT && RT->isStructureOrClassType()) {
     const RecordDecl *RD = RT->getDecl();
     QualType Found;
 

diff  --git a/clang/test/CodeGen/systemz-abi.c b/clang/test/CodeGen/systemz-abi.c
index 35adbbe301c4..9f9cb2275bfa 100644
--- a/clang/test/CodeGen/systemz-abi.c
+++ b/clang/test/CodeGen/systemz-abi.c
@@ -155,6 +155,17 @@ struct agg_nofloat3 pass_agg_nofloat3(struct agg_nofloat3 arg) { return arg; }
 // CHECK-LABEL: define void @pass_agg_nofloat3(%struct.agg_nofloat3* noalias sret align 4 %{{.*}}, i32 %{{.*}})
 
 
+// Union types likewise are *not* float-like aggregate types
+
+union union_float { float a; };
+union union_float pass_union_float(union union_float arg) { return arg; }
+// CHECK-LABEL: define void @pass_union_float(%union.union_float* noalias sret align 4 %{{.*}}, i32 %{{.*}})
+
+union union_double { double a; };
+union union_double pass_union_double(union union_double arg) { return arg; }
+// CHECK-LABEL: define void @pass_union_double(%union.union_double* noalias sret align 8 %{{.*}}, i64 %{{.*}})
+
+
 // Accessing variable argument lists
 
 int va_int(__builtin_va_list l) { return __builtin_va_arg(l, int); }

diff  --git a/clang/test/CodeGen/systemz-abi.cpp b/clang/test/CodeGen/systemz-abi.cpp
index cb381e88dd8f..7604dea41dde 100644
--- a/clang/test/CodeGen/systemz-abi.cpp
+++ b/clang/test/CodeGen/systemz-abi.cpp
@@ -2,10 +2,24 @@
 // RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm -x c++ -o - %s -mfloat-abi soft \
 // RUN:   | FileCheck %s --check-prefix=SOFT-FLOAT
 
+// Verify that class types are also recognized as float-like aggregate types
+
+class agg_float_class { float a; };
+class agg_float_class pass_agg_float_class(class agg_float_class arg) { return arg; }
+// CHECK-LABEL: define void @_Z20pass_agg_float_class15agg_float_class(%class.agg_float_class* noalias sret align 4 %{{.*}}, float %{{.*}})
+// SOFT-FLOAT-LABEL: define void @_Z20pass_agg_float_class15agg_float_class(%class.agg_float_class* noalias sret align 4 %{{.*}}, i32 %{{.*}})
+
+class agg_double_class { double a; };
+class agg_double_class pass_agg_double_class(class agg_double_class arg) { return arg; }
+// CHECK-LABEL: define void @_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias sret align 8 %{{.*}}, double %{{.*}})
+// SOFT-FLOAT-LABEL: define void @_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias sret align 8 %{{.*}}, i64 %{{.*}})
+
+
 // For compatibility with GCC, this structure is passed in an FPR in C++,
 // but passed in a GPR in C (checked in systemz-abi.c).
 
 struct agg_float_cpp { float a; int : 0; };
 struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; }
 // CHECK-LABEL: define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret align 4 %{{.*}}, float %{{.*}})
-// SOFT-FLOAT:  define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret align 4 %{{.*}}, i32 %{{.*}})
+// SOFT-FLOAT-LABEL:  define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret align 4 %{{.*}}, i32 %{{.*}})
+


        


More information about the cfe-commits mailing list