From c6a8dee17a0a2eeb3420e04fb445a633dfbee920 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Fri, 2 Aug 2024 13:58:37 -0400 Subject: [PATCH 01/16] [PowerPC] Fix codegen for transparent_union function params Update codegen for func param with transparent_union attr to be that of the first union member. --- clang/lib/CodeGen/ABIInfoImpl.cpp | 7 ++ clang/lib/CodeGen/ABIInfoImpl.h | 4 ++ clang/lib/CodeGen/Targets/PPC.cpp | 26 +++++-- .../test/CodeGen/PowerPC/transparent_union.c | 54 +++++++++++++++ .../test/CodeGen/PowerPC/transparent_union.ll | 67 +++++++++++++++++++ 5 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/PowerPC/transparent_union.c create mode 100644 llvm/test/CodeGen/PowerPC/transparent_union.ll diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 35e8f79ba1bac7b..d73b7e882fe654c 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -143,13 +143,20 @@ bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, } QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) { + bool IsTransparentUnion; + return useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); +} + +QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty, bool &TU) { if (const RecordType *UT = Ty->getAsUnionType()) { const RecordDecl *UD = UT->getDecl(); if (UD->hasAttr()) { assert(!UD->field_empty() && "sema created an empty transparent union"); + TU = true; return UD->field_begin()->getType(); } } + TU = false; return Ty; } diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h index 2a3ef6b8a6c9610..95e48ee49d5a4ec 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.h +++ b/clang/lib/CodeGen/ABIInfoImpl.h @@ -65,6 +65,10 @@ CGCXXABI::RecordArgABI getRecordArgABI(QualType T, CGCXXABI &CXXABI); bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info); +// For transparent union types, return the type of the first element. +// Set reference TU to true if Ty given was a transparent union. +QualType useFirstFieldIfTransparentUnion(QualType Ty, bool &TU); + /// Pass transparent unions as if they were the type of the first element. Sema /// should ensure that all elements of the union have the same "machine type". QualType useFirstFieldIfTransparentUnion(QualType Ty); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index e4155810963eb81..d2a3abbe2486141 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -196,7 +196,8 @@ ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const { } ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { - Ty = useFirstFieldIfTransparentUnion(Ty); + bool IsTransparentUnion; + Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -217,8 +218,14 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { /*Realign*/ TyAlign > CCAlign); } - return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) - : ABIArgInfo::getDirect()); + if (isPromotableTypeForABI(Ty)) + return (IsTransparentUnion ? + ABIArgInfo::getExtend(Ty, + llvm::IntegerType::get(getVMContext(), + getContext().getTypeSize(Ty))) + : ABIArgInfo::getExtend(Ty)); + + return (ABIArgInfo::getDirect()); } CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const { @@ -822,7 +829,8 @@ bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough( ABIArgInfo PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { - Ty = useFirstFieldIfTransparentUnion(Ty); + bool IsTransparentUnion; + Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -891,8 +899,14 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { /*Realign=*/TyAlign > ABIAlign); } - return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) - : ABIArgInfo::getDirect()); + if (isPromotableTypeForABI(Ty)) + return (IsTransparentUnion ? + ABIArgInfo::getExtend(Ty, + llvm::IntegerType::get(getVMContext(), + getContext().getTypeSize(Ty))) + : ABIArgInfo::getExtend(Ty)); + + return ABIArgInfo::getDirect(); } ABIArgInfo diff --git a/clang/test/CodeGen/PowerPC/transparent_union.c b/clang/test/CodeGen/PowerPC/transparent_union.c new file mode 100644 index 000000000000000..6c61ce553ba7d7f --- /dev/null +++ b/clang/test/CodeGen/PowerPC/transparent_union.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr7 \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr7 \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-AIX-32 + +typedef union tu_c { + char a; + char b; +} tu_c_t __attribute__((transparent_union)); + +typedef union tu_s { + short a; +} tu_s_t __attribute__((transparent_union)); + +typedef union tu_us { + unsigned short a; +} tu_us_t __attribute__((transparent_union)); + +typedef union tu_l { + long a; +} tu_l_t __attribute__((transparent_union)); + +// CHECK-LABEL: define{{.*}} void @ftest0( +// CHECK-SAME: i8 noundef signext [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret void +void ftest0(tu_c_t uc) { } + +// CHECK-LABEL: define{{.*}} void @ftest1( +// CHECK-SAME: i16 noundef signext [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret void +void ftest1(tu_s_t uc) { } + +// CHECK-LABEL: define{{.*}} void @ftest2( +// CHECK-SAME: i16 noundef zeroext [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret void +void ftest2(tu_us_t uc) { } + +// CHECK-64-LABEL: define{{.*}} void @ftest3( +// CHECK-64-SAME: i64 [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-64-NEXT: [[ENTRY:.*:]] +// CHECK-64-NEXT: ret void +// +// CHECK-AIX-32-LABEL: define void @ftest3( +// CHECK-AIX-32-SAME: i32 [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-AIX-32-NEXT: [[ENTRY:.*:]] +// CHECK-AIX-32-NEXT: ret void +void ftest3(tu_l_t uc) { } diff --git a/llvm/test/CodeGen/PowerPC/transparent_union.ll b/llvm/test/CodeGen/PowerPC/transparent_union.ll new file mode 100644 index 000000000000000..d04a010737421f1 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/transparent_union.ll @@ -0,0 +1,67 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux -mcpu=pwr7 \ +; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux -mcpu=pwr7 \ +; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr7 \ +; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix -mcpu=pwr7 \ +; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-AIX-32 + +%union.tu_c = type { i8 } +%union.tu_s = type { i16 } +%union.tu_us = type { i16 } +%union.tu_l = type { i64 } + +define void @ftest0(i8 noundef zeroext %uc.coerce) { +; CHECK-LABEL: ftest0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stb 3, -1(1) +; CHECK-NEXT: blr +entry: + %uc = alloca %union.tu_c, align 1 + %coerce.dive = getelementptr inbounds %union.tu_c, ptr %uc, i32 0, i32 0 + store i8 %uc.coerce, ptr %coerce.dive, align 1 + ret void +} + +define void @ftest1(i16 noundef signext %uc.coerce) { +; CHECK-LABEL: ftest1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sth 3, -2(1) +; CHECK-NEXT: blr +entry: + %uc = alloca %union.tu_s, align 2 + %coerce.dive = getelementptr inbounds %union.tu_s, ptr %uc, i32 0, i32 0 + store i16 %uc.coerce, ptr %coerce.dive, align 2 + ret void +} + +define void @ftest2(i16 noundef zeroext %uc.coerce) { +; CHECK-LABEL: ftest2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sth 3, -2(1) +; CHECK-NEXT: blr +entry: + %uc = alloca %union.tu_us, align 2 + %coerce.dive = getelementptr inbounds %union.tu_us, ptr %uc, i32 0, i32 0 + store i16 %uc.coerce, ptr %coerce.dive, align 2 + ret void +} + +define void @ftest3(i64 %uc.coerce) { +; CHECK-64-LABEL: ftest3: +; CHECK-64: # %bb.0: # %entry +; CHECK-64-NEXT: std 3, -8(1) +; CHECK-64-NEXT: blr +; +; CHECK-AIX-32-LABEL: ftest3: +; CHECK-AIX-32: # %bb.0: # %entry +; CHECK-AIX-32-NEXT: stw 4, -4(1) +; CHECK-AIX-32-NEXT: stw 3, -8(1) +; CHECK-AIX-32-NEXT: blr +entry: + %uc = alloca %union.tu_l, align 8 + %coerce.dive = getelementptr inbounds %union.tu_l, ptr %uc, i32 0, i32 0 + store i64 %uc.coerce, ptr %coerce.dive, align 8 + ret void +} From 242510de36e16bf0e1f2c8af73e712d1100f434b Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Fri, 2 Aug 2024 17:11:07 -0400 Subject: [PATCH 02/16] apply clang format suggestions --- clang/lib/CodeGen/Targets/PPC.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index d2a3abbe2486141..eab2cfdcbe307b2 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -219,11 +219,11 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { } if (isPromotableTypeForABI(Ty)) - return (IsTransparentUnion ? - ABIArgInfo::getExtend(Ty, - llvm::IntegerType::get(getVMContext(), - getContext().getTypeSize(Ty))) - : ABIArgInfo::getExtend(Ty)); + return (IsTransparentUnion + ? ABIArgInfo::getExtend( + Ty, llvm::IntegerType::get(getVMContext(), + getContext().getTypeSize(Ty))) + : ABIArgInfo::getExtend(Ty)); return (ABIArgInfo::getDirect()); } @@ -900,11 +900,11 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { } if (isPromotableTypeForABI(Ty)) - return (IsTransparentUnion ? - ABIArgInfo::getExtend(Ty, - llvm::IntegerType::get(getVMContext(), - getContext().getTypeSize(Ty))) - : ABIArgInfo::getExtend(Ty)); + return (IsTransparentUnion + ? ABIArgInfo::getExtend( + Ty, llvm::IntegerType::get(getVMContext(), + getContext().getTypeSize(Ty))) + : ABIArgInfo::getExtend(Ty)); return ABIArgInfo::getDirect(); } From 9ca3b7dfc05162c687fb0687e80992876309ad38 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 13:13:20 -0400 Subject: [PATCH 03/16] add ppc32bit run line --- clang/test/CodeGen/PowerPC/transparent_union.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/clang/test/CodeGen/PowerPC/transparent_union.c b/clang/test/CodeGen/PowerPC/transparent_union.c index 6c61ce553ba7d7f..d64067204558ff8 100644 --- a/clang/test/CodeGen/PowerPC/transparent_union.c +++ b/clang/test/CodeGen/PowerPC/transparent_union.c @@ -1,11 +1,13 @@ -// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr7 \ +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -O2 -target-cpu pwr7 \ // RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 -// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr7 \ +// RUN: %clang_cc1 -triple powerpc64-unknown-linux -O2 -target-cpu pwr7 \ // RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: %clang_cc1 -triple powerpc-unknown-linux -O2 -target-cpu pwr7 \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 // RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \ // RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 // RUN: %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \ -// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-AIX-32 +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 typedef union tu_c { char a; @@ -47,8 +49,8 @@ void ftest2(tu_us_t uc) { } // CHECK-64-NEXT: [[ENTRY:.*:]] // CHECK-64-NEXT: ret void // -// CHECK-AIX-32-LABEL: define void @ftest3( -// CHECK-AIX-32-SAME: i32 [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { -// CHECK-AIX-32-NEXT: [[ENTRY:.*:]] -// CHECK-AIX-32-NEXT: ret void +// CHECK-32-LABEL: define{{.*}} void @ftest3( +// CHECK-32-SAME: i32 [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-32-NEXT: [[ENTRY:.*:]] +// CHECK-32-NEXT: ret void void ftest3(tu_l_t uc) { } From 2cf8131bbba260bfdb7f03c9dc7cc8a425324422 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 13:38:13 -0400 Subject: [PATCH 04/16] add transparent union handling to ppc 32bit arg handling --- clang/lib/CodeGen/Targets/PPC.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index eab2cfdcbe307b2..704d7c84560fcb5 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -344,6 +344,7 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo { IsRetSmallStructInRegABI(RetSmallStructInRegABI) {} ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType Ty) const; void computeInfo(CGFunctionInfo &FI) const override { if (!getCXXABI().classifyReturnType(FI)) @@ -400,6 +401,18 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { + bool IsTransparentUnion; + Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); + + if (IsTransparentUnion && isPromotableIntegerTypeForABI(Ty)) + return (ABIArgInfo::getExtend( + Ty, + llvm::IntegerType::get(getVMContext(), getContext().getTypeSize(Ty)))); + + return DefaultABIInfo::classifyArgumentType(Ty); +} + ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { uint64_t Size; From 49d3d02c65203164a8594b7c6083ff9f71e7e5e5 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 16:07:54 -0400 Subject: [PATCH 05/16] add support for 32bit enum handling --- clang/lib/CodeGen/ABIInfoImpl.h | 2 +- clang/lib/CodeGen/Targets/PPC.cpp | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h index 95e48ee49d5a4ec..e0657675e915d9a 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.h +++ b/clang/lib/CodeGen/ABIInfoImpl.h @@ -66,7 +66,7 @@ bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info); // For transparent union types, return the type of the first element. -// Set reference TU to true if Ty given was a transparent union. +// Set TU to true if Ty given was a transparent union and to false otherwise. QualType useFirstFieldIfTransparentUnion(QualType Ty, bool &TU); /// Pass transparent unions as if they were the type of the first element. Sema diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 704d7c84560fcb5..c670031a7ba60a6 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -343,6 +343,8 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo { : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI), IsRetSmallStructInRegABI(RetSmallStructInRegABI) {} + bool isPromotableTypeForABI(QualType Ty) const; + ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType Ty) const; @@ -401,11 +403,30 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 32 bits. +bool +PPC32_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) + Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (isPromotableIntegerTypeForABI(Ty)) + return true; + + if (const auto *EIT = Ty->getAs()) + if (EIT->getNumBits() < 32) + return true; + + return false; +} + ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { bool IsTransparentUnion; Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); - if (IsTransparentUnion && isPromotableIntegerTypeForABI(Ty)) + if (IsTransparentUnion && isPromotableTypeForABI(Ty)) return (ABIArgInfo::getExtend( Ty, llvm::IntegerType::get(getVMContext(), getContext().getTypeSize(Ty)))); From 254e16d3abe399a12ffcb31726c5f6f629600301 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 16:50:02 -0400 Subject: [PATCH 06/16] add enum transparent union clang test --- clang/test/CodeGen/PowerPC/transparent_union.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/clang/test/CodeGen/PowerPC/transparent_union.c b/clang/test/CodeGen/PowerPC/transparent_union.c index d64067204558ff8..812c36a70e7a182 100644 --- a/clang/test/CodeGen/PowerPC/transparent_union.c +++ b/clang/test/CodeGen/PowerPC/transparent_union.c @@ -54,3 +54,19 @@ void ftest2(tu_us_t uc) { } // CHECK-32-NEXT: [[ENTRY:.*:]] // CHECK-32-NEXT: ret void void ftest3(tu_l_t uc) { } + +typedef union etest { + enum flag {red, yellow, blue} fl; + enum weekend {sun, sat} b; +} etest_t __attribute__((transparent_union)); + +// CHECK-64-LABEL: define{{.*}} void @test( +// CHECK-64-SAME: i32 noundef zeroext [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-64-NEXT: [[ENTRY:.*:]] +// CHECK-64-NEXT: ret void +// +// CHECK-32-LABEL: define{{.*}} void @test( +// CHECK-32-SAME: i32 [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-32-NEXT: [[ENTRY:.*:]] +// CHECK-32-NEXT: ret void +void test(etest_t a) {} From f0ce1bb40d07781c5c2f9b9deb28492a9acddf07 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 16:54:24 -0400 Subject: [PATCH 07/16] add enum IR test --- .../test/CodeGen/PowerPC/transparent_union.ll | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/llvm/test/CodeGen/PowerPC/transparent_union.ll b/llvm/test/CodeGen/PowerPC/transparent_union.ll index d04a010737421f1..1d981addbbe9f2d 100644 --- a/llvm/test/CodeGen/PowerPC/transparent_union.ll +++ b/llvm/test/CodeGen/PowerPC/transparent_union.ll @@ -11,6 +11,7 @@ %union.tu_s = type { i16 } %union.tu_us = type { i16 } %union.tu_l = type { i64 } +%union.etest = type { i32 } define void @ftest0(i8 noundef zeroext %uc.coerce) { ; CHECK-LABEL: ftest0: @@ -65,3 +66,27 @@ entry: store i64 %uc.coerce, ptr %coerce.dive, align 8 ret void } + +define dso_local void @ftest4(i32 %a.coerce) { +; CHECK-LABEL: ftest4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stw 3, -4(1) +; CHECK-NEXT: blr +entry: + %a = alloca %union.etest, align 4 + %coerce.dive = getelementptr inbounds %union.etest, ptr %a, i32 0, i32 0 + store i32 %a.coerce, ptr %coerce.dive, align 4 + ret void +} + +define dso_local void @test5(i32 noundef zeroext %a.coerce) { +; CHECK-LABEL: test5: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stw 3, -4(1) +; CHECK-NEXT: blr +entry: + %a = alloca %union.etest, align 4 + %coerce.dive = getelementptr inbounds %union.etest, ptr %a, i32 0, i32 0 + store i32 %a.coerce, ptr %coerce.dive, align 4 + ret void +} From 761648ddd58954da9bb7fd0477479e80ad732822 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 17:23:47 -0400 Subject: [PATCH 08/16] add -fshort-enum option to clang tests --- .../test/CodeGen/PowerPC/transparent_union.c | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/clang/test/CodeGen/PowerPC/transparent_union.c b/clang/test/CodeGen/PowerPC/transparent_union.c index 812c36a70e7a182..8ebc51d4e8d1f9b 100644 --- a/clang/test/CodeGen/PowerPC/transparent_union.c +++ b/clang/test/CodeGen/PowerPC/transparent_union.c @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -triple powerpc64le-unknown-linux -O2 -target-cpu pwr7 \ -// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: -emit-llvm -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 // RUN: %clang_cc1 -triple powerpc64-unknown-linux -O2 -target-cpu pwr7 \ -// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: -emit-llvm -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 // RUN: %clang_cc1 -triple powerpc-unknown-linux -O2 -target-cpu pwr7 \ -// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 +// RUN: -emit-llvm -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 // RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \ -// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 +// RUN: -emit-llvm -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64 // RUN: %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \ -// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 +// RUN: -emit-llvm -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 typedef union tu_c { char a; @@ -60,13 +60,8 @@ typedef union etest { enum weekend {sun, sat} b; } etest_t __attribute__((transparent_union)); -// CHECK-64-LABEL: define{{.*}} void @test( -// CHECK-64-SAME: i32 noundef zeroext [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// CHECK-64-NEXT: [[ENTRY:.*:]] -// CHECK-64-NEXT: ret void -// -// CHECK-32-LABEL: define{{.*}} void @test( -// CHECK-32-SAME: i32 [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// CHECK-32-NEXT: [[ENTRY:.*:]] -// CHECK-32-NEXT: ret void -void test(etest_t a) {} +// CHECK-LABEL: define{{.*}} void @ftest4( +// CHECK-SAME: i8 noundef zeroext [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret void +void ftest4(etest_t a) {} From 8c57ecb4b826f10bff9cda7544fa241360d65389 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 5 Aug 2024 17:27:34 -0400 Subject: [PATCH 09/16] udpate IR code for short enums --- .../test/CodeGen/PowerPC/transparent_union.ll | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/llvm/test/CodeGen/PowerPC/transparent_union.ll b/llvm/test/CodeGen/PowerPC/transparent_union.ll index 1d981addbbe9f2d..6a340d2cd95cc4a 100644 --- a/llvm/test/CodeGen/PowerPC/transparent_union.ll +++ b/llvm/test/CodeGen/PowerPC/transparent_union.ll @@ -11,7 +11,7 @@ %union.tu_s = type { i16 } %union.tu_us = type { i16 } %union.tu_l = type { i64 } -%union.etest = type { i32 } +%union.etest = type { i8 } define void @ftest0(i8 noundef zeroext %uc.coerce) { ; CHECK-LABEL: ftest0: @@ -67,26 +67,14 @@ entry: ret void } -define dso_local void @ftest4(i32 %a.coerce) { +define dso_local void @ftest4(i8 noundef zeroext %a.coerce) #0 { ; CHECK-LABEL: ftest4: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: stw 3, -4(1) -; CHECK-NEXT: blr -entry: - %a = alloca %union.etest, align 4 - %coerce.dive = getelementptr inbounds %union.etest, ptr %a, i32 0, i32 0 - store i32 %a.coerce, ptr %coerce.dive, align 4 - ret void -} - -define dso_local void @test5(i32 noundef zeroext %a.coerce) { -; CHECK-LABEL: test5: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: stw 3, -4(1) +; CHECK-NEXT: stb 3, -1(1) ; CHECK-NEXT: blr entry: - %a = alloca %union.etest, align 4 + %a = alloca %union.etest, align 1 %coerce.dive = getelementptr inbounds %union.etest, ptr %a, i32 0, i32 0 - store i32 %a.coerce, ptr %coerce.dive, align 4 + store i8 %a.coerce, ptr %coerce.dive, align 1 ret void } From a7351d8a7f8cd0fddfd326d58441fec17fc4581d Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Tue, 6 Aug 2024 10:22:15 -0400 Subject: [PATCH 10/16] add IR test for ppc 32bit --- .../test/CodeGen/PowerPC/transparent_union.ll | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/llvm/test/CodeGen/PowerPC/transparent_union.ll b/llvm/test/CodeGen/PowerPC/transparent_union.ll index 6a340d2cd95cc4a..d13d4aeb1b8c889 100644 --- a/llvm/test/CodeGen/PowerPC/transparent_union.ll +++ b/llvm/test/CodeGen/PowerPC/transparent_union.ll @@ -2,6 +2,8 @@ ; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux -mcpu=pwr7 \ ; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux -mcpu=pwr7 \ +; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK-32 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr7 \ ; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 ; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix -mcpu=pwr7 \ @@ -18,6 +20,14 @@ define void @ftest0(i8 noundef zeroext %uc.coerce) { ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: stb 3, -1(1) ; CHECK-NEXT: blr +; +; CHECK-32-LABEL: ftest0: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: stwu 1, -16(1) +; CHECK-32-NEXT: .cfi_def_cfa_offset 16 +; CHECK-32-NEXT: stb 3, 15(1) +; CHECK-32-NEXT: addi 1, 1, 16 +; CHECK-32-NEXT: blr entry: %uc = alloca %union.tu_c, align 1 %coerce.dive = getelementptr inbounds %union.tu_c, ptr %uc, i32 0, i32 0 @@ -30,6 +40,14 @@ define void @ftest1(i16 noundef signext %uc.coerce) { ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: sth 3, -2(1) ; CHECK-NEXT: blr +; +; CHECK-32-LABEL: ftest1: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: stwu 1, -16(1) +; CHECK-32-NEXT: .cfi_def_cfa_offset 16 +; CHECK-32-NEXT: sth 3, 14(1) +; CHECK-32-NEXT: addi 1, 1, 16 +; CHECK-32-NEXT: blr entry: %uc = alloca %union.tu_s, align 2 %coerce.dive = getelementptr inbounds %union.tu_s, ptr %uc, i32 0, i32 0 @@ -42,6 +60,14 @@ define void @ftest2(i16 noundef zeroext %uc.coerce) { ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: sth 3, -2(1) ; CHECK-NEXT: blr +; +; CHECK-32-LABEL: ftest2: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: stwu 1, -16(1) +; CHECK-32-NEXT: .cfi_def_cfa_offset 16 +; CHECK-32-NEXT: sth 3, 14(1) +; CHECK-32-NEXT: addi 1, 1, 16 +; CHECK-32-NEXT: blr entry: %uc = alloca %union.tu_us, align 2 %coerce.dive = getelementptr inbounds %union.tu_us, ptr %uc, i32 0, i32 0 @@ -60,6 +86,15 @@ define void @ftest3(i64 %uc.coerce) { ; CHECK-AIX-32-NEXT: stw 4, -4(1) ; CHECK-AIX-32-NEXT: stw 3, -8(1) ; CHECK-AIX-32-NEXT: blr +; +; CHECK-32-LABEL: ftest3: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: stwu 1, -16(1) +; CHECK-32-NEXT: .cfi_def_cfa_offset 16 +; CHECK-32-NEXT: stw 4, 12(1) +; CHECK-32-NEXT: stw 3, 8(1) +; CHECK-32-NEXT: addi 1, 1, 16 +; CHECK-32-NEXT: blr entry: %uc = alloca %union.tu_l, align 8 %coerce.dive = getelementptr inbounds %union.tu_l, ptr %uc, i32 0, i32 0 @@ -72,6 +107,14 @@ define dso_local void @ftest4(i8 noundef zeroext %a.coerce) #0 { ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: stb 3, -1(1) ; CHECK-NEXT: blr +; +; CHECK-32-LABEL: ftest4: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: stwu 1, -16(1) +; CHECK-32-NEXT: .cfi_def_cfa_offset 16 +; CHECK-32-NEXT: stb 3, 15(1) +; CHECK-32-NEXT: addi 1, 1, 16 +; CHECK-32-NEXT: blr entry: %a = alloca %union.etest, align 1 %coerce.dive = getelementptr inbounds %union.etest, ptr %a, i32 0, i32 0 From d431df9558c588f516c13b0a498be8a1f74592fe Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Wed, 7 Aug 2024 13:14:06 -0400 Subject: [PATCH 11/16] move code to generate transparent coerce type to useFirstFieldIfTransparentUnion() --- clang/lib/CodeGen/ABIInfoImpl.cpp | 27 +++++++++---- clang/lib/CodeGen/ABIInfoImpl.h | 6 ++- clang/lib/CodeGen/Targets/PPC.cpp | 64 +++++-------------------------- 3 files changed, 33 insertions(+), 64 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index d73b7e882fe654c..80caa81b3546162 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -15,7 +15,9 @@ using namespace clang::CodeGen; DefaultABIInfo::~DefaultABIInfo() = default; ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { - Ty = useFirstFieldIfTransparentUnion(Ty); + llvm::Type *CoerceTy = nullptr; + Ty = useFirstFieldIfTransparentUnion(Ty, getContext(), getVMContext(), + &CoerceTy); if (isAggregateTypeForABI(Ty)) { // Records with non-trivial destructors/copy-constructors should not be @@ -38,7 +40,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { : Context.LongLongTy)) return getNaturalAlignIndirect(Ty); - return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) + return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CoerceTy) : ABIArgInfo::getDirect()); } @@ -143,20 +145,29 @@ bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, } QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) { - bool IsTransparentUnion; - return useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); + if (const RecordType *UT = Ty->getAsUnionType()) { + const RecordDecl *UD = UT->getDecl(); + if (UD->hasAttr()) { + assert(!UD->field_empty() && "sema created an empty transparent union"); + return UD->field_begin()->getType(); + } + } + return Ty; } -QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty, bool &TU) { +QualType +CodeGen::useFirstFieldIfTransparentUnion(QualType Ty, ASTContext &Context, + llvm::LLVMContext &LLVMContext, + llvm::Type **CTy) { if (const RecordType *UT = Ty->getAsUnionType()) { const RecordDecl *UD = UT->getDecl(); if (UD->hasAttr()) { assert(!UD->field_empty() && "sema created an empty transparent union"); - TU = true; - return UD->field_begin()->getType(); + QualType UTy = UD->field_begin()->getType(); + *CTy = llvm::IntegerType::get(LLVMContext, Context.getTypeSize(UTy)); + return UTy; } } - TU = false; return Ty; } diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h index e0657675e915d9a..d961eb6af76c668 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.h +++ b/clang/lib/CodeGen/ABIInfoImpl.h @@ -66,8 +66,10 @@ bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info); // For transparent union types, return the type of the first element. -// Set TU to true if Ty given was a transparent union and to false otherwise. -QualType useFirstFieldIfTransparentUnion(QualType Ty, bool &TU); +// Set CoerceType to the integer type of the first union element. +QualType useFirstFieldIfTransparentUnion(QualType Ty, ASTContext &Context, + llvm::LLVMContext &LLVMContext, + llvm::Type **CoerceType); /// Pass transparent unions as if they were the type of the first element. Sema /// should ensure that all elements of the union have the same "machine type". diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index c670031a7ba60a6..5a0a896988f427a 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -196,8 +196,9 @@ ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const { } ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { - bool IsTransparentUnion; - Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); + llvm::Type *CoerceTy = nullptr; + Ty = useFirstFieldIfTransparentUnion(Ty, getContext(), getVMContext(), + &CoerceTy); if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -218,14 +219,8 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { /*Realign*/ TyAlign > CCAlign); } - if (isPromotableTypeForABI(Ty)) - return (IsTransparentUnion - ? ABIArgInfo::getExtend( - Ty, llvm::IntegerType::get(getVMContext(), - getContext().getTypeSize(Ty))) - : ABIArgInfo::getExtend(Ty)); - - return (ABIArgInfo::getDirect()); + return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CoerceTy) + : ABIArgInfo::getDirect()); } CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const { @@ -343,10 +338,7 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo { : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI), IsRetSmallStructInRegABI(RetSmallStructInRegABI) {} - bool isPromotableTypeForABI(QualType Ty) const; - ABIArgInfo classifyReturnType(QualType RetTy) const; - ABIArgInfo classifyArgumentType(QualType Ty) const; void computeInfo(CGFunctionInfo &FI) const override { if (!getCXXABI().classifyReturnType(FI)) @@ -403,37 +395,6 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } -// Return true if the ABI requires Ty to be passed sign- or zero- -// extended to 32 bits. -bool -PPC32_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { - // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); - - // Promotable integer types are required to be promoted by the ABI. - if (isPromotableIntegerTypeForABI(Ty)) - return true; - - if (const auto *EIT = Ty->getAs()) - if (EIT->getNumBits() < 32) - return true; - - return false; -} - -ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { - bool IsTransparentUnion; - Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); - - if (IsTransparentUnion && isPromotableTypeForABI(Ty)) - return (ABIArgInfo::getExtend( - Ty, - llvm::IntegerType::get(getVMContext(), getContext().getTypeSize(Ty)))); - - return DefaultABIInfo::classifyArgumentType(Ty); -} - ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { uint64_t Size; @@ -863,8 +824,9 @@ bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough( ABIArgInfo PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { - bool IsTransparentUnion; - Ty = useFirstFieldIfTransparentUnion(Ty, IsTransparentUnion); + llvm::Type *CoerceType = nullptr; + Ty = useFirstFieldIfTransparentUnion(Ty, getContext(), getVMContext(), + &CoerceType); if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -933,14 +895,8 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { /*Realign=*/TyAlign > ABIAlign); } - if (isPromotableTypeForABI(Ty)) - return (IsTransparentUnion - ? ABIArgInfo::getExtend( - Ty, llvm::IntegerType::get(getVMContext(), - getContext().getTypeSize(Ty))) - : ABIArgInfo::getExtend(Ty)); - - return ABIArgInfo::getDirect(); + return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CoerceType) + : ABIArgInfo::getDirect()); } ABIArgInfo From 9f4d9e2c98ac0b3ec540df6255f7bfb177701406 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Wed, 7 Aug 2024 16:15:49 -0400 Subject: [PATCH 12/16] apply clang-format --- clang/lib/CodeGen/ABIInfoImpl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 80caa81b3546162..016d806955ff7ce 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -40,8 +40,9 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { : Context.LongLongTy)) return getNaturalAlignIndirect(Ty); - return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CoerceTy) - : ABIArgInfo::getDirect()); + return (isPromotableIntegerTypeForABI(Ty) + ? ABIArgInfo::getExtend(Ty, CoerceTy) + : ABIArgInfo::getDirect()); } ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { From 0fb7cf8068fb862c6c4ce95484d6509d75793b92 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Thu, 15 Aug 2024 20:02:17 -0400 Subject: [PATCH 13/16] update to use CGT.ConvertType(Ty) instead --- clang/lib/CodeGen/ABIInfoImpl.cpp | 22 ++-------------------- clang/lib/CodeGen/ABIInfoImpl.h | 6 ------ clang/lib/CodeGen/Targets/PPC.cpp | 12 ++++-------- 3 files changed, 6 insertions(+), 34 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 016d806955ff7ce..be91b85e3a816f8 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -15,9 +15,7 @@ using namespace clang::CodeGen; DefaultABIInfo::~DefaultABIInfo() = default; ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { - llvm::Type *CoerceTy = nullptr; - Ty = useFirstFieldIfTransparentUnion(Ty, getContext(), getVMContext(), - &CoerceTy); + Ty = useFirstFieldIfTransparentUnion(Ty); if (isAggregateTypeForABI(Ty)) { // Records with non-trivial destructors/copy-constructors should not be @@ -41,7 +39,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { return getNaturalAlignIndirect(Ty); return (isPromotableIntegerTypeForABI(Ty) - ? ABIArgInfo::getExtend(Ty, CoerceTy) + ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) : ABIArgInfo::getDirect()); } @@ -156,22 +154,6 @@ QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) { return Ty; } -QualType -CodeGen::useFirstFieldIfTransparentUnion(QualType Ty, ASTContext &Context, - llvm::LLVMContext &LLVMContext, - llvm::Type **CTy) { - if (const RecordType *UT = Ty->getAsUnionType()) { - const RecordDecl *UD = UT->getDecl(); - if (UD->hasAttr()) { - assert(!UD->field_empty() && "sema created an empty transparent union"); - QualType UTy = UD->field_begin()->getType(); - *CTy = llvm::IntegerType::get(LLVMContext, Context.getTypeSize(UTy)); - return UTy; - } - } - return Ty; -} - llvm::Value *CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction &CGF, llvm::Value *Ptr, CharUnits Align) { diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h index d961eb6af76c668..2a3ef6b8a6c9610 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.h +++ b/clang/lib/CodeGen/ABIInfoImpl.h @@ -65,12 +65,6 @@ CGCXXABI::RecordArgABI getRecordArgABI(QualType T, CGCXXABI &CXXABI); bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info); -// For transparent union types, return the type of the first element. -// Set CoerceType to the integer type of the first union element. -QualType useFirstFieldIfTransparentUnion(QualType Ty, ASTContext &Context, - llvm::LLVMContext &LLVMContext, - llvm::Type **CoerceType); - /// Pass transparent unions as if they were the type of the first element. Sema /// should ensure that all elements of the union have the same "machine type". QualType useFirstFieldIfTransparentUnion(QualType Ty); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 5a0a896988f427a..3fcee6443d23315 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -196,9 +196,7 @@ ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const { } ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { - llvm::Type *CoerceTy = nullptr; - Ty = useFirstFieldIfTransparentUnion(Ty, getContext(), getVMContext(), - &CoerceTy); + Ty = useFirstFieldIfTransparentUnion(Ty); if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -219,7 +217,7 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { /*Realign*/ TyAlign > CCAlign); } - return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CoerceTy) + return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) : ABIArgInfo::getDirect()); } @@ -824,9 +822,7 @@ bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough( ABIArgInfo PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { - llvm::Type *CoerceType = nullptr; - Ty = useFirstFieldIfTransparentUnion(Ty, getContext(), getVMContext(), - &CoerceType); + Ty = useFirstFieldIfTransparentUnion(Ty); if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -895,7 +891,7 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { /*Realign=*/TyAlign > ABIAlign); } - return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CoerceType) + return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) : ABIArgInfo::getDirect()); } From a50d3dad85bd1cbc445cda904b1702885cff7dee Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Fri, 16 Aug 2024 09:45:40 -0400 Subject: [PATCH 14/16] apply clang-format --- clang/lib/CodeGen/Targets/PPC.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 3fcee6443d23315..989e46f4b66a7d6 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -217,8 +217,9 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { /*Realign*/ TyAlign > CCAlign); } - return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) - : ABIArgInfo::getDirect()); + return (isPromotableTypeForABI(Ty) + ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) + : ABIArgInfo::getDirect()); } CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const { @@ -891,8 +892,9 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { /*Realign=*/TyAlign > ABIAlign); } - return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) - : ABIArgInfo::getDirect()); + return (isPromotableTypeForABI(Ty) + ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) + : ABIArgInfo::getDirect()); } ABIArgInfo From 54b237e04f45ecb0cb625d09fef876bd3f9968c4 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 19 Aug 2024 09:41:12 -0400 Subject: [PATCH 15/16] apply Hubert's suggestion --- clang/test/CodeGen/PowerPC/transparent_union.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/test/CodeGen/PowerPC/transparent_union.c b/clang/test/CodeGen/PowerPC/transparent_union.c index 8ebc51d4e8d1f9b..968a385c0ee45fe 100644 --- a/clang/test/CodeGen/PowerPC/transparent_union.c +++ b/clang/test/CodeGen/PowerPC/transparent_union.c @@ -10,20 +10,20 @@ // RUN: -emit-llvm -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32 typedef union tu_c { - char a; - char b; + signed char a; + signed char b; } tu_c_t __attribute__((transparent_union)); typedef union tu_s { - short a; + short a; } tu_s_t __attribute__((transparent_union)); typedef union tu_us { - unsigned short a; + unsigned short a; } tu_us_t __attribute__((transparent_union)); typedef union tu_l { - long a; + long a; } tu_l_t __attribute__((transparent_union)); // CHECK-LABEL: define{{.*}} void @ftest0( From 87286fb1d4842bcfb038d8a98f680240cb1299d0 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Mon, 19 Aug 2024 09:47:15 -0400 Subject: [PATCH 16/16] remove IR test as I have verified Hubert's comment is correct. --- .../test/CodeGen/PowerPC/transparent_union.ll | 123 ------------------ 1 file changed, 123 deletions(-) delete mode 100644 llvm/test/CodeGen/PowerPC/transparent_union.ll diff --git a/llvm/test/CodeGen/PowerPC/transparent_union.ll b/llvm/test/CodeGen/PowerPC/transparent_union.ll deleted file mode 100644 index d13d4aeb1b8c889..000000000000000 --- a/llvm/test/CodeGen/PowerPC/transparent_union.ll +++ /dev/null @@ -1,123 +0,0 @@ -; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux -mcpu=pwr7 \ -; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 -; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux -mcpu=pwr7 \ -; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 -; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux -mcpu=pwr7 \ -; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK-32 -; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr7 \ -; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-64 -; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix -mcpu=pwr7 \ -; RUN: -O2 -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-AIX-32 - -%union.tu_c = type { i8 } -%union.tu_s = type { i16 } -%union.tu_us = type { i16 } -%union.tu_l = type { i64 } -%union.etest = type { i8 } - -define void @ftest0(i8 noundef zeroext %uc.coerce) { -; CHECK-LABEL: ftest0: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: stb 3, -1(1) -; CHECK-NEXT: blr -; -; CHECK-32-LABEL: ftest0: -; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: stwu 1, -16(1) -; CHECK-32-NEXT: .cfi_def_cfa_offset 16 -; CHECK-32-NEXT: stb 3, 15(1) -; CHECK-32-NEXT: addi 1, 1, 16 -; CHECK-32-NEXT: blr -entry: - %uc = alloca %union.tu_c, align 1 - %coerce.dive = getelementptr inbounds %union.tu_c, ptr %uc, i32 0, i32 0 - store i8 %uc.coerce, ptr %coerce.dive, align 1 - ret void -} - -define void @ftest1(i16 noundef signext %uc.coerce) { -; CHECK-LABEL: ftest1: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: sth 3, -2(1) -; CHECK-NEXT: blr -; -; CHECK-32-LABEL: ftest1: -; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: stwu 1, -16(1) -; CHECK-32-NEXT: .cfi_def_cfa_offset 16 -; CHECK-32-NEXT: sth 3, 14(1) -; CHECK-32-NEXT: addi 1, 1, 16 -; CHECK-32-NEXT: blr -entry: - %uc = alloca %union.tu_s, align 2 - %coerce.dive = getelementptr inbounds %union.tu_s, ptr %uc, i32 0, i32 0 - store i16 %uc.coerce, ptr %coerce.dive, align 2 - ret void -} - -define void @ftest2(i16 noundef zeroext %uc.coerce) { -; CHECK-LABEL: ftest2: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: sth 3, -2(1) -; CHECK-NEXT: blr -; -; CHECK-32-LABEL: ftest2: -; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: stwu 1, -16(1) -; CHECK-32-NEXT: .cfi_def_cfa_offset 16 -; CHECK-32-NEXT: sth 3, 14(1) -; CHECK-32-NEXT: addi 1, 1, 16 -; CHECK-32-NEXT: blr -entry: - %uc = alloca %union.tu_us, align 2 - %coerce.dive = getelementptr inbounds %union.tu_us, ptr %uc, i32 0, i32 0 - store i16 %uc.coerce, ptr %coerce.dive, align 2 - ret void -} - -define void @ftest3(i64 %uc.coerce) { -; CHECK-64-LABEL: ftest3: -; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: std 3, -8(1) -; CHECK-64-NEXT: blr -; -; CHECK-AIX-32-LABEL: ftest3: -; CHECK-AIX-32: # %bb.0: # %entry -; CHECK-AIX-32-NEXT: stw 4, -4(1) -; CHECK-AIX-32-NEXT: stw 3, -8(1) -; CHECK-AIX-32-NEXT: blr -; -; CHECK-32-LABEL: ftest3: -; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: stwu 1, -16(1) -; CHECK-32-NEXT: .cfi_def_cfa_offset 16 -; CHECK-32-NEXT: stw 4, 12(1) -; CHECK-32-NEXT: stw 3, 8(1) -; CHECK-32-NEXT: addi 1, 1, 16 -; CHECK-32-NEXT: blr -entry: - %uc = alloca %union.tu_l, align 8 - %coerce.dive = getelementptr inbounds %union.tu_l, ptr %uc, i32 0, i32 0 - store i64 %uc.coerce, ptr %coerce.dive, align 8 - ret void -} - -define dso_local void @ftest4(i8 noundef zeroext %a.coerce) #0 { -; CHECK-LABEL: ftest4: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: stb 3, -1(1) -; CHECK-NEXT: blr -; -; CHECK-32-LABEL: ftest4: -; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: stwu 1, -16(1) -; CHECK-32-NEXT: .cfi_def_cfa_offset 16 -; CHECK-32-NEXT: stb 3, 15(1) -; CHECK-32-NEXT: addi 1, 1, 16 -; CHECK-32-NEXT: blr -entry: - %a = alloca %union.etest, align 1 - %coerce.dive = getelementptr inbounds %union.etest, ptr %a, i32 0, i32 0 - store i8 %a.coerce, ptr %coerce.dive, align 1 - ret void -}