[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 5 13:54:37 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 1/7] [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 35e8f79ba1bac..d73b7e882fe65 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 2a3ef6b8a6c96..95e48ee49d5a4 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 e4155810963eb..d2a3abbe24861 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 0000000000000..6c61ce553ba7d
--- /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 0000000000000..d04a010737421
--- /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 2/7] 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 d2a3abbe24861..eab2cfdcbe307 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 3/7] 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 6c61ce553ba7d..d64067204558f 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 4/7] 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 eab2cfdcbe307..704d7c84560fc 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 5/7] 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 95e48ee49d5a4..e0657675e915d 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 704d7c84560fc..c670031a7ba60 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 6/7] 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 d64067204558f..812c36a70e7a1 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 7/7] 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 d04a010737421..1d981addbbe9f 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
+}



More information about the llvm-commits mailing list