Skip to content

Commit ea92045

Browse files
authored
Fix codegen for transparent_union function params (#104816)
Update codegen for func param with transparent_union attr to be that of the first union member. This is a followup to #101738 to fix non-ppc codegen and closes #76773.
1 parent 6634d44 commit ea92045

File tree

6 files changed

+121
-79
lines changed

6 files changed

+121
-79
lines changed

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
304304
return getNaturalAlignIndirect(Ty, false);
305305

306306
return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
307-
? ABIArgInfo::getExtend(Ty)
307+
? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
308308
: ABIArgInfo::getDirect());
309309
}
310310

clang/lib/CodeGen/Targets/ARM.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,9 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
354354
if (EIT->getNumBits() > 64)
355355
return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
356356

357-
return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
358-
: ABIArgInfo::getDirect());
357+
return (isPromotableIntegerTypeForABI(Ty)
358+
? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
359+
: ABIArgInfo::getDirect());
359360
}
360361

361362
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {

clang/lib/CodeGen/Targets/RISCV.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class RISCVABIInfo : public DefaultABIInfo {
5151
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
5252
AggValueSlot Slot) const override;
5353

54-
ABIArgInfo extendType(QualType Ty) const;
54+
ABIArgInfo extendType(QualType Ty, llvm::Type *CoerceTy = nullptr) const;
5555

5656
bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
5757
CharUnits &Field1Off, llvm::Type *&Field2Ty,
@@ -439,12 +439,12 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
439439

440440
// All integral types are promoted to XLen width
441441
if (Size < XLen && Ty->isIntegralOrEnumerationType()) {
442-
return extendType(Ty);
442+
return extendType(Ty, CGT.ConvertType(Ty));
443443
}
444444

445445
if (const auto *EIT = Ty->getAs<BitIntType>()) {
446446
if (EIT->getNumBits() < XLen)
447-
return extendType(Ty);
447+
return extendType(Ty, CGT.ConvertType(Ty));
448448
if (EIT->getNumBits() > 128 ||
449449
(!getContext().getTargetInfo().hasInt128Type() &&
450450
EIT->getNumBits() > 64))
@@ -526,12 +526,12 @@ RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
526526
/*AllowHigherAlign=*/true, Slot);
527527
}
528528

529-
ABIArgInfo RISCVABIInfo::extendType(QualType Ty) const {
529+
ABIArgInfo RISCVABIInfo::extendType(QualType Ty, llvm::Type *CoerceTy) const {
530530
int TySize = getContext().getTypeSize(Ty);
531531
// RV64 ABI requires unsigned 32 bit integers to be sign extended.
532532
if (XLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
533-
return ABIArgInfo::getSignExtend(Ty);
534-
return ABIArgInfo::getExtend(Ty);
533+
return ABIArgInfo::getSignExtend(Ty, CoerceTy);
534+
return ABIArgInfo::getExtend(Ty, CoerceTy);
535535
}
536536

537537
namespace {

clang/lib/CodeGen/Targets/X86.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,8 +881,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
881881

882882
if (isPromotableIntegerTypeForABI(Ty)) {
883883
if (InReg)
884-
return ABIArgInfo::getExtendInReg(Ty);
885-
return ABIArgInfo::getExtend(Ty);
884+
return ABIArgInfo::getExtendInReg(Ty, CGT.ConvertType(Ty));
885+
return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
886886
}
887887

888888
if (const auto *EIT = Ty->getAs<BitIntType>()) {
@@ -2756,7 +2756,7 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs,
27562756

27572757
if (Ty->isIntegralOrEnumerationType() &&
27582758
isPromotableIntegerTypeForABI(Ty))
2759-
return ABIArgInfo::getExtend(Ty);
2759+
return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
27602760
}
27612761

27622762
break;

clang/test/CodeGen/PowerPC/transparent_union.c

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// RUN: %clang_cc1 -triple powerpc64le-linux -O2 -target-cpu pwr7 -emit-llvm \
2+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
3+
// RUN: %clang_cc1 -triple powerpc64-linux -O2 -target-cpu pwr7 -emit-llvm \
4+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
5+
// RUN: %clang_cc1 -triple powerpc-linux -O2 -target-cpu pwr7 -emit-llvm \
6+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32
7+
// RUN: %clang_cc1 -triple powerpc64-aix -O2 -target-cpu pwr7 -emit-llvm \
8+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
9+
// RUN: %clang_cc1 -triple powerpc-aix -O2 -target-cpu pwr7 -emit-llvm \
10+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32
11+
// RUN: %clang_cc1 -triple riscv64-linux -O2 -emit-llvm -fshort-enums \
12+
// RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
13+
// RUN: %clang_cc1 -triple riscv32-linux -O2 -emit-llvm -fshort-enums \
14+
// RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32
15+
// RUN: %clang_cc1 -triple i386-linux -O2 -emit-llvm -fshort-enums \
16+
// RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32
17+
// RUN: %clang_cc1 -triple x86_64-linux -O2 -emit-llvm -fshort-enums \
18+
// RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
19+
// RUN: %clang_cc1 -triple armv7-linux -O2 -emit-llvm -fshort-enums \
20+
// RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-32
21+
// RUN: %clang_cc1 -triple arm64 -target-abi darwinpcs -O2 -emit-llvm \
22+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
23+
// RUN: %clang_cc1 -triple aarch64 -target-abi darwinpcs -O2 -emit-llvm \
24+
// RUN: -fshort-enums %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-64
25+
26+
typedef union tu_c {
27+
signed char a;
28+
signed char b;
29+
} tu_c_t __attribute__((transparent_union));
30+
31+
typedef union tu_s {
32+
short a;
33+
} tu_s_t __attribute__((transparent_union));
34+
35+
typedef union tu_us {
36+
unsigned short a;
37+
} tu_us_t __attribute__((transparent_union));
38+
39+
typedef union tu_l {
40+
long a;
41+
} tu_l_t __attribute__((transparent_union));
42+
43+
// CHECK-LABEL: define{{.*}} void @ftest0(
44+
// CHECK-SAME: i8 noundef signext [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
45+
// CHECK-NEXT: [[ENTRY:.*:]]
46+
// CHECK-NEXT: ret void
47+
void ftest0(tu_c_t uc) { }
48+
49+
// CHECK-LABEL: define{{.*}} void @ftest1(
50+
// CHECK-SAME: i16 noundef signext [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
51+
// CHECK-NEXT: [[ENTRY:.*:]]
52+
// CHECK-NEXT: ret void
53+
void ftest1(tu_s_t uc) { }
54+
55+
// CHECK-LABEL: define{{.*}} void @ftest1b(
56+
// CHECK-SAME: ptr nocapture noundef readnone [[UC:%.*]]) local_unnamed_addr #[[ATTR0]] {
57+
// CHECK-NEXT: [[ENTRY:.*:]]
58+
// CHECK-NEXT: ret void
59+
//
60+
void ftest1b(tu_s_t *uc) { }
61+
62+
// CHECK-LABEL: define{{.*}} void @ftest2(
63+
// CHECK-SAME: i16 noundef zeroext [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
64+
// CHECK-NEXT: [[ENTRY:.*:]]
65+
// CHECK-NEXT: ret void
66+
void ftest2(tu_us_t uc) { }
67+
68+
// CHECK-64-LABEL: define{{.*}} void @ftest3(
69+
// CHECK-64-SAME: i64 [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
70+
// CHECK-64-NEXT: [[ENTRY:.*:]]
71+
// CHECK-64-NEXT: ret void
72+
//
73+
// CHECK-32-LABEL: define{{.*}} void @ftest3(
74+
// CHECK-32-SAME: i32 [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
75+
// CHECK-32-NEXT: [[ENTRY:.*:]]
76+
// CHECK-32-NEXT: ret void
77+
void ftest3(tu_l_t uc) { }
78+
79+
typedef union etest {
80+
enum flag {red, yellow, blue} fl;
81+
enum weekend {sun, sat} b;
82+
} etest_t __attribute__((transparent_union));
83+
84+
// CHECK-LABEL: define{{.*}} void @ftest4(
85+
// CHECK-SAME: i8 noundef zeroext [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
86+
// CHECK-NEXT: [[ENTRY:.*:]]
87+
// CHECK-NEXT: ret void
88+
void ftest4(etest_t a) {}
89+
90+
typedef union tu_ptr {
91+
signed char *a;
92+
unsigned short *b;
93+
int *c;
94+
} tu_ptr_t __attribute__((transparent_union));
95+
96+
// CHECK-LABEL: define{{.*}} void @ftest5(
97+
// CHECK-SAME: ptr nocapture readnone [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
98+
// CHECK-NEXT: [[ENTRY:.*:]]
99+
// CHECK-NEXT: ret void
100+
//
101+
void ftest5(tu_ptr_t uc) { }
102+
103+
// CHECK-LABEL: define{{.*}} void @ftest6(
104+
// CHECK-SAME: ptr nocapture noundef readnone [[UC:%.*]]) local_unnamed_addr #[[ATTR0]] {
105+
// CHECK-NEXT: [[ENTRY:.*:]]
106+
// CHECK-NEXT: ret void
107+
//
108+
void ftest6(tu_ptr_t *uc) { }

0 commit comments

Comments
 (0)