[clang] [llvm] [PowerPC] Fix codegen for transparent_union function params (PR #101738)

Lei Huang via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 06:41:31 PDT 2024


https://github.com/lei137 updated https://github.com/llvm/llvm-project/pull/101738

>From f25e4ab65ed16a1e1a3bde91efe24bd0d52e0e74 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 2 Aug 2024 13:58:37 -0400
Subject: [PATCH 01/15] [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 35e8f79ba1bac7..d73b7e882fe654 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<TransparentUnionAttr>()) {
       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 2a3ef6b8a6c961..95e48ee49d5a4e 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 e4155810963eb8..d2a3abbe248614 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 00000000000000..6c61ce553ba7d7
--- /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 00000000000000..d04a010737421f
--- /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 e0e521bb7863ab1b11129448931e107a4b0f291b Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 2 Aug 2024 17:11:07 -0400
Subject: [PATCH 02/15] 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 d2a3abbe248614..eab2cfdcbe307b 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 682f31e65dd4b13e5a6ab91822ed4aa14aef6cba Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 13:13:20 -0400
Subject: [PATCH 03/15] 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 6c61ce553ba7d7..d64067204558ff 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 fcde96ab9f64c84b6a050d40b09c55e212843eb8 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 13:38:13 -0400
Subject: [PATCH 04/15] 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 eab2cfdcbe307b..704d7c84560fcb 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 ce81490bc3dc1958558aa404b48876908e570dea Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 16:07:54 -0400
Subject: [PATCH 05/15] 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 95e48ee49d5a4e..e0657675e915d9 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 704d7c84560fcb..c670031a7ba60a 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<EnumType>())
+    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<BitIntType>())
+    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 616ea70f5ddaa7f3188f6642ceabbdc6eb9dc850 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 16:50:02 -0400
Subject: [PATCH 06/15] 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 d64067204558ff..812c36a70e7a18 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 670b9efb64da1ef3587a5ce6e801d9b513887eb0 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 16:54:24 -0400
Subject: [PATCH 07/15] 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 d04a010737421f..1d981addbbe9f2 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 d46eefa46a210824e5f903c825ecb69edde73331 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 17:23:47 -0400
Subject: [PATCH 08/15] 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 812c36a70e7a18..8ebc51d4e8d1f9 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 a2f5f4af82bd8fc27687b33ae5fd21b4808aed83 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 5 Aug 2024 17:27:34 -0400
Subject: [PATCH 09/15] 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 1d981addbbe9f2..6a340d2cd95cc4 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 ac6e9c0f51c6c5819c27aad03f864b0f5292d0aa Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 6 Aug 2024 10:22:15 -0400
Subject: [PATCH 10/15] 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 6a340d2cd95cc4..d13d4aeb1b8c88 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 bea2cad0f582b37ed52c3dab2d38f6a8dcafef3d Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 7 Aug 2024 13:14:06 -0400
Subject: [PATCH 11/15] 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 d73b7e882fe654..80caa81b354616 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<TransparentUnionAttr>()) {
+      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<TransparentUnionAttr>()) {
       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 e0657675e915d9..d961eb6af76c66 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 c670031a7ba60a..5a0a896988f427 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<EnumType>())
-    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<BitIntType>())
-    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 6ac02c19a39396611a7437a874b5573fe0459912 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 7 Aug 2024 16:15:49 -0400
Subject: [PATCH 12/15] 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 80caa81b354616..016d806955ff7c 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 3b6c8036dd41190a4c15255070ce08ffe8f6ea73 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Thu, 15 Aug 2024 20:02:17 -0400
Subject: [PATCH 13/15] 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 016d806955ff7c..be91b85e3a816f 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<TransparentUnionAttr>()) {
-      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 d961eb6af76c66..2a3ef6b8a6c961 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 5a0a896988f427..3fcee6443d2331 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 7b98fa5348e0cd19c6e792f33d53910dedea49e1 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 16 Aug 2024 09:45:40 -0400
Subject: [PATCH 14/15] 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 3fcee6443d2331..989e46f4b66a7d 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 ff0d4706ef03525d8219d3ed2b14affc680991e9 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 19 Aug 2024 09:41:12 -0400
Subject: [PATCH 15/15] 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 8ebc51d4e8d1f9..968a385c0ee45f 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(



More information about the llvm-commits mailing list