[clang] [PowerPC] make `_Complex` ABI GCC-compatible (PR #208917)
Folkert de Vries via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 21 07:04:32 PDT 2026
https://github.com/folkertdev updated https://github.com/llvm/llvm-project/pull/208917
>From d394d5763d08aa4c49fcb7df06e810cece6fb287 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 13:27:46 +0200
Subject: [PATCH 01/12] inline `ABIArgInfo::classifyArgumentType`
---
clang/lib/CodeGen/Targets/PPC.cpp | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index a87f8410636500..6d1cc80f0a781e 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -371,6 +371,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))
@@ -427,6 +428,36 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
return CharUnits::fromQuantity(4);
}
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
+ if (isAggregateTypeForABI(Ty)) {
+ // Records with non-trivial destructors/copy-constructors should not be
+ // passed by value.
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+ return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
+ RAA == CGCXXABI::RAA_DirectInMemory);
+
+ return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
+ }
+
+ // Treat an enum type as its underlying type.
+ if (const auto *ED = Ty->getAsEnumDecl())
+ Ty = ED->getIntegerType();
+
+ ASTContext &Context = getContext();
+ if (const auto *EIT = Ty->getAs<BitIntType>())
+ if (EIT->getNumBits() >
+ Context.getTypeSize(Context.getTargetInfo().hasInt128Type()
+ ? Context.Int128Ty
+ : Context.LongLongTy))
+ return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
+
+ return (isPromotableIntegerTypeForABI(Ty)
+ ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
+ : ABIArgInfo::getDirect());
+}
+
ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
uint64_t Size;
>From f0fbc2f3f7580394449145e3b3ed17df98a7f105 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 13:29:53 +0200
Subject: [PATCH 02/12] add `isComplexGnuABI`
---
clang/lib/CodeGen/Targets/PPC.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 6d1cc80f0a781e..2ca1bbd2ccf77d 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -362,6 +362,12 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
bool IsSoftFloatABI;
bool IsRetSmallStructInRegABI;
+ bool isComplexGnuABI() const {
+ return !getTarget().getTriple().isOSDarwin() &&
+ !getContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver22);
+ }
+
CharUnits getParamTypeAlignment(QualType Ty) const;
public:
>From ad08be82e550cc379207a2a86f171fda36777c31 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 13:36:43 +0200
Subject: [PATCH 03/12] add `ArgGPRsLeft` parameter to `classifyArgumentType`
---
clang/lib/CodeGen/Targets/PPC.cpp | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 2ca1bbd2ccf77d..a0a480bd6d2e6f 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -362,6 +362,10 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
bool IsSoftFloatABI;
bool IsRetSmallStructInRegABI;
+ // Number of GPRs (r3..=r10) available for passing arguments, and their width.
+ static const int NumArgGPRs = 8;
+ static const unsigned GPRBits = 32;
+
bool isComplexGnuABI() const {
return !getTarget().getTriple().isOSDarwin() &&
!getContext().getLangOpts().isCompatibleWith(
@@ -377,13 +381,15 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
ABIArgInfo classifyReturnType(QualType RetTy) const;
- ABIArgInfo classifyArgumentType(QualType Ty) const;
+ ABIArgInfo classifyArgumentType(QualType Ty, int &ArgGPRsLeft) const;
void computeInfo(CGFunctionInfo &FI) const override {
if (!getCXXABI().classifyReturnType(FI))
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+ int ArgGPRsLeft = NumArgGPRs;
for (auto &I : FI.arguments())
- I.info = classifyArgumentType(I.type);
+ I.info = classifyArgumentType(I.type, ArgGPRsLeft);
}
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
@@ -434,7 +440,9 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
return CharUnits::fromQuantity(4);
}
-ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+ int &ArgGPRsLeft) const {
+ assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
Ty = useFirstFieldIfTransparentUnion(Ty);
if (isAggregateTypeForABI(Ty)) {
@@ -501,8 +509,10 @@ RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
TI.Align = getParamTypeAlignment(Ty);
CharUnits SlotSize = CharUnits::fromQuantity(4);
+ int ArgGPRsLeft = NumArgGPRs;
return emitVoidPtrVAArg(CGF, VAList, Ty,
- classifyArgumentType(Ty).isIndirect(), TI, SlotSize,
+ classifyArgumentType(Ty, ArgGPRsLeft).isIndirect(),
+ TI, SlotSize,
/*AllowHigherAlign=*/true, Slot);
}
>From c6c6bc5f328d539284db37bc583252d53957d03e Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 14:01:32 +0200
Subject: [PATCH 04/12] add GPR budget logic
---
clang/lib/CodeGen/Targets/PPC.cpp | 50 ++++++++++++++++++-------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index a0a480bd6d2e6f..c0243dc6ee737a 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -445,31 +445,39 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
Ty = useFirstFieldIfTransparentUnion(Ty);
- if (isAggregateTypeForABI(Ty)) {
- // Records with non-trivial destructors/copy-constructors should not be
- // passed by value.
- if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
- return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
- RAA == CGCXXABI::RAA_DirectInMemory);
+ bool IsComplex = Ty->isAnyComplexType() && isComplexGnuABI();
- return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
- }
+ // Use the default implementation when this argument is not relevant for GPR
+ // budget:
+ //
+ // - floating-point types are passed in FPRs
+ // - when GPRs are already exhausted
+ //
+ // Complex types (when GNU compatible) always need custom handling.
+ if (!IsComplex && (!ArgGPRsLeft || (Ty->isFloatingType() && !IsSoftFloatABI)))
+ return DefaultABIInfo::classifyArgumentType(Ty);
- // Treat an enum type as its underlying type.
- if (const auto *ED = Ty->getAsEnumDecl())
- Ty = ED->getIntegerType();
+ uint64_t TypeSize = getContext().getTypeSize(Ty);
+ uint64_t RegsNeeded = (TypeSize + GPRBits - 1) / GPRBits;
- ASTContext &Context = getContext();
- if (const auto *EIT = Ty->getAs<BitIntType>())
- if (EIT->getNumBits() >
- Context.getTypeSize(Context.getTargetInfo().hasInt128Type()
- ? Context.Int128Ty
- : Context.LongLongTy))
- return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
+ if (IsComplex || !isAggregateTypeForABI(Ty)) {
+ // Complex values and scalars are passed in GPRs.
- return (isPromotableIntegerTypeForABI(Ty)
- ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
- : ABIArgInfo::getDirect());
+ // An 8-byte value (e.g. _Complex float, _Complex int, i64, soft-float
+ // double) must start in an even-numbered GPR, so skip an odd register to
+ // keep the pair aligned.
+ if (TypeSize == 2 * GPRBits && ArgGPRsLeft % 2 == 1)
+ ArgGPRsLeft -= 1;
+
+ if (RegsNeeded <= (uint64_t)ArgGPRsLeft) {
+ ArgGPRsLeft -= RegsNeeded;
+ }
+ } else {
+ // Other aggregates are passed indirectly, and consume one GPR.
+ ArgGPRsLeft -= 1;
+ }
+
+ return DefaultABIInfo::classifyArgumentType(Ty);
}
ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
>From 21095f7d7e13b55bfe49131d6e7ebc1c40c1ddfb Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 15:10:03 +0200
Subject: [PATCH 05/12] add `classifyComplexType`
---
clang/lib/CodeGen/Targets/PPC.cpp | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index c0243dc6ee737a..097b172777c071 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -373,6 +373,7 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
}
CharUnits getParamTypeAlignment(QualType Ty) const;
+ ABIArgInfo classifyComplexType(QualType Ty) const;
public:
PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
@@ -440,6 +441,32 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
return CharUnits::fromQuantity(4);
}
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyComplexType(QualType Ty) const {
+ uint64_t Size = getContext().getTypeSize(Ty);
+ llvm::LLVMContext &VMC = getVMContext();
+ llvm::Type *I32 = llvm::Type::getInt32Ty(VMC);
+ QualType ElemTy = Ty->castAs<ComplexType>()->getElementType();
+
+ // Work around https://github.com/llvm/llvm-project/issues/44482.
+ // This is a bug where the two halves of a ppc_fp128 are swapped.
+ // Using i128 for the ABI instead circumvents this issue.
+ if (CGT.ConvertType(ElemTy)->isPPC_FP128Ty())
+ return ABIArgInfo::getDirect(
+ llvm::ArrayType::get(llvm::Type::getInt128Ty(VMC), 2));
+
+ // Coerce to an integer for _Complex char and _Complex short.
+ if (Size <= GPRBits)
+ return ABIArgInfo::getDirect(llvm::IntegerType::get(VMC, Size));
+
+ // Coerce to a vector <N x i32> for _Complex float and _Complex int.
+ if (Size == 2 * GPRBits)
+ return ABIArgInfo::getDirect(llvm::FixedVectorType::get(I32, 2));
+
+ // Coerce to an array [N x i32] for _Complex double and similar.
+ // Using i32 gives the correct 4-byte register alignment.
+ return ABIArgInfo::getDirect(llvm::ArrayType::get(I32, Size / GPRBits));
+}
+
ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
int &ArgGPRsLeft) const {
assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
>From 1961fd16fd78a75a48f0f66c35c733ac4829c106 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 15:18:33 +0200
Subject: [PATCH 06/12] hook up new complex abi logic
---
clang/lib/CodeGen/Targets/PPC.cpp | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 097b172777c071..b824e66a005f0b 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -445,6 +445,8 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyComplexType(QualType Ty) const {
uint64_t Size = getContext().getTypeSize(Ty);
llvm::LLVMContext &VMC = getVMContext();
llvm::Type *I32 = llvm::Type::getInt32Ty(VMC);
+
+ assert(Ty->isAnyComplexType() && "not a complex type");
QualType ElemTy = Ty->castAs<ComplexType>()->getElementType();
// Work around https://github.com/llvm/llvm-project/issues/44482.
@@ -459,11 +461,12 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyComplexType(QualType Ty) const {
return ABIArgInfo::getDirect(llvm::IntegerType::get(VMC, Size));
// Coerce to a vector <N x i32> for _Complex float and _Complex int.
+ // A vector gives this the correct 8-byte register alignment.
if (Size == 2 * GPRBits)
return ABIArgInfo::getDirect(llvm::FixedVectorType::get(I32, 2));
// Coerce to an array [N x i32] for _Complex double and similar.
- // Using i32 gives the correct 4-byte register alignment.
+ // An array of i32 gives the correct 4-byte register alignment.
return ABIArgInfo::getDirect(llvm::ArrayType::get(I32, Size / GPRBits));
}
@@ -497,7 +500,28 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
ArgGPRsLeft -= 1;
if (RegsNeeded <= (uint64_t)ArgGPRsLeft) {
+ // All fits.
ArgGPRsLeft -= RegsNeeded;
+
+ // _Complex needs a type coercion to be passed correctly.
+ if (IsComplex)
+ return classifyComplexType(Ty);
+ } else if (IsComplex) {
+ // Never split a Complex value across GPRs and the stack. When a Complex
+ // value does not fit in the remaining GPRs, it is passed via the stack
+ // and the remaining GPRs are considered consumed, so any further
+ // arguments will be passed via the stack as well.
+
+ // _Complex needs a type coercion to be passed correctly.
+ llvm::Type *CoerceTy = classifyComplexType(Ty).getCoerceToType();
+
+ // Soak up the remaining GPRs with a padding argument.
+ llvm::Type *I32 = llvm::Type::getInt32Ty(getVMContext());
+ llvm::Type *Padding =
+ ArgGPRsLeft > 0 ? llvm::ArrayType::get(I32, ArgGPRsLeft) : nullptr;
+
+ ArgGPRsLeft = 0;
+ return ABIArgInfo::getDirect(CoerceTy, /*Offset=*/0, Padding);
}
} else {
// Other aggregates are passed indirectly, and consume one GPR.
@@ -510,6 +534,9 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
uint64_t Size;
+ if (RetTy->isAnyComplexType() && isComplexGnuABI())
+ return classifyComplexType(RetTy);
+
// -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI &&
(Size = getContext().getTypeSize(RetTy)) <= 64) {
>From 960975629ad7281fe9d55fb4c4098e098fdd5070 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Sat, 11 Jul 2026 16:57:51 +0200
Subject: [PATCH 07/12] fix test
---
.../PowerPC/builtins-ppc-xlcompat-cmplx.c | 360 +++++++++++-------
.../test/CodeGen/PowerPC/powerpc-c99complex.c | 92 ++++-
clang/test/CodeGen/long_double_fp128.cpp | 9 +-
.../math-libcalls-tbaa-indirect-args.c | 45 ++-
4 files changed, 337 insertions(+), 169 deletions(-)
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c
index cf03af38b37847..ae224aef66da96 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c
@@ -6,10 +6,14 @@
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=64BITLE
// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=64BITAIX
-// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \
-// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BIT
-// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu \
-// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=32BITLE
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fclang-abi-compat=22 \
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BIT-CLANG22
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fclang-abi-compat=23 \
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BIT-CLANG23
+// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu -fclang-abi-compat=22 \
+// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=32BITLE-CLANG22
+// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu -fclang-abi-compat=23 \
+// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=32BITLE-CLANG23
// RUN: %clang_cc1 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BITAIX
@@ -61,49 +65,81 @@
// 64BITAIX-NEXT: [[TMP2:%.*]] = load { double, double }, ptr [[RETVAL]], align 4
// 64BITAIX-NEXT: ret { double, double } [[TMP2]]
//
-// 32BIT-LABEL: @testcmplx(
-// 32BIT-NEXT: entry:
-// 32BIT-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
-// 32BIT-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
-// 32BIT-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
-// 32BIT-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
-// 32BIT-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
-// 32BIT-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
-// 32BIT-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
-// 32BIT-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
-// 32BIT-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
-// 32BIT-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
-// 32BIT-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
-// 32BIT-NEXT: ret void
+// 32BIT-CLANG22-LABEL: @testcmplx(
+// 32BIT-CLANG22-NEXT: entry:
+// 32BIT-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
+// 32BIT-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
+// 32BIT-CLANG22-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
+// 32BIT-CLANG22-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
+// 32BIT-CLANG22-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
+// 32BIT-CLANG22-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
+// 32BIT-CLANG22-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// 32BIT-CLANG22-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// 32BIT-CLANG22-NEXT: ret void
//
-// 32BITLE-LABEL: @testcmplx(
-// 32BITLE-NEXT: entry:
-// 32BITLE-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
-// 32BITLE-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
-// 32BITLE-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
-// 32BITLE-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
-// 32BITLE-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
-// 32BITLE-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
-// 32BITLE-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
-// 32BITLE-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
-// 32BITLE-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
-// 32BITLE-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
-// 32BITLE-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
-// 32BITLE-NEXT: ret void
+// 32BIT-CLANG23-LABEL: @testcmplx(
+// 32BIT-CLANG23-NEXT: entry:
+// 32BIT-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// 32BIT-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
+// 32BIT-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
+// 32BIT-CLANG23-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
+// 32BIT-CLANG23-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
+// 32BIT-CLANG23-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
+// 32BIT-CLANG23-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
+// 32BIT-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store double [[TMP0]], ptr [[RETVAL_REALP]], align 8
+// 32BIT-CLANG23-NEXT: store double [[TMP1]], ptr [[RETVAL_IMAGP]], align 8
+// 32BIT-CLANG23-NEXT: [[TMP2:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// 32BIT-CLANG23-NEXT: ret [4 x i32] [[TMP2]]
+//
+// 32BITLE-CLANG22-LABEL: @testcmplx(
+// 32BITLE-CLANG22-NEXT: entry:
+// 32BITLE-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
+// 32BITLE-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
+// 32BITLE-CLANG22-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
+// 32BITLE-CLANG22-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
+// 32BITLE-CLANG22-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
+// 32BITLE-CLANG22-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
+// 32BITLE-CLANG22-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// 32BITLE-CLANG22-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// 32BITLE-CLANG22-NEXT: ret void
+//
+// 32BITLE-CLANG23-LABEL: @testcmplx(
+// 32BITLE-CLANG23-NEXT: entry:
+// 32BITLE-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// 32BITLE-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
+// 32BITLE-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
+// 32BITLE-CLANG23-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
+// 32BITLE-CLANG23-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
+// 32BITLE-CLANG23-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
+// 32BITLE-CLANG23-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
+// 32BITLE-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store double [[TMP0]], ptr [[RETVAL_REALP]], align 8
+// 32BITLE-CLANG23-NEXT: store double [[TMP1]], ptr [[RETVAL_IMAGP]], align 8
+// 32BITLE-CLANG23-NEXT: [[TMP2:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// 32BITLE-CLANG23-NEXT: ret [4 x i32] [[TMP2]]
//
// 32BITAIX-LABEL: @testcmplx(
// 32BITAIX-NEXT: entry:
@@ -173,49 +209,81 @@ double _Complex testcmplx(double real, double imag) {
// 64BITAIX-NEXT: [[TMP2:%.*]] = load { float, float }, ptr [[RETVAL]], align 4
// 64BITAIX-NEXT: ret { float, float } [[TMP2]]
//
-// 32BIT-LABEL: @testcmplxf(
-// 32BIT-NEXT: entry:
-// 32BIT-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
-// 32BIT-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
-// 32BIT-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
-// 32BIT-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
-// 32BIT-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
-// 32BIT-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
-// 32BIT-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
-// 32BIT-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
-// 32BIT-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
-// 32BIT-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
-// 32BIT-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
-// 32BIT-NEXT: ret void
+// 32BIT-CLANG22-LABEL: @testcmplxf(
+// 32BIT-CLANG22-NEXT: entry:
+// 32BIT-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
+// 32BIT-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
+// 32BIT-CLANG22-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
+// 32BIT-CLANG22-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
+// 32BIT-CLANG22-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
+// 32BIT-CLANG22-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
+// 32BIT-CLANG22-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// 32BIT-CLANG22-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// 32BIT-CLANG22-NEXT: ret void
+//
+// 32BIT-CLANG23-LABEL: @testcmplxf(
+// 32BIT-CLANG23-NEXT: entry:
+// 32BIT-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// 32BIT-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
+// 32BIT-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
+// 32BIT-CLANG23-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
+// 32BIT-CLANG23-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
+// 32BIT-CLANG23-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
+// 32BIT-CLANG23-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
+// 32BIT-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store float [[TMP0]], ptr [[RETVAL_REALP]], align 4
+// 32BIT-CLANG23-NEXT: store float [[TMP1]], ptr [[RETVAL_IMAGP]], align 4
+// 32BIT-CLANG23-NEXT: [[TMP2:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// 32BIT-CLANG23-NEXT: ret <2 x i32> [[TMP2]]
//
-// 32BITLE-LABEL: @testcmplxf(
-// 32BITLE-NEXT: entry:
-// 32BITLE-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
-// 32BITLE-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
-// 32BITLE-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
-// 32BITLE-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
-// 32BITLE-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
-// 32BITLE-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
-// 32BITLE-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
-// 32BITLE-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
-// 32BITLE-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
-// 32BITLE-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
-// 32BITLE-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
-// 32BITLE-NEXT: ret void
+// 32BITLE-CLANG22-LABEL: @testcmplxf(
+// 32BITLE-CLANG22-NEXT: entry:
+// 32BITLE-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
+// 32BITLE-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
+// 32BITLE-CLANG22-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
+// 32BITLE-CLANG22-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
+// 32BITLE-CLANG22-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
+// 32BITLE-CLANG22-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
+// 32BITLE-CLANG22-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// 32BITLE-CLANG22-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// 32BITLE-CLANG22-NEXT: ret void
+//
+// 32BITLE-CLANG23-LABEL: @testcmplxf(
+// 32BITLE-CLANG23-NEXT: entry:
+// 32BITLE-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// 32BITLE-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
+// 32BITLE-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
+// 32BITLE-CLANG23-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
+// 32BITLE-CLANG23-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
+// 32BITLE-CLANG23-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
+// 32BITLE-CLANG23-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
+// 32BITLE-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store float [[TMP0]], ptr [[RETVAL_REALP]], align 4
+// 32BITLE-CLANG23-NEXT: store float [[TMP1]], ptr [[RETVAL_IMAGP]], align 4
+// 32BITLE-CLANG23-NEXT: [[TMP2:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// 32BITLE-CLANG23-NEXT: ret <2 x i32> [[TMP2]]
//
// 32BITAIX-LABEL: @testcmplxf(
// 32BITAIX-NEXT: entry:
@@ -285,49 +353,81 @@ float _Complex testcmplxf(float real, float imag) {
// 64BITAIX-NEXT: [[TMP2:%.*]] = load { double, double }, ptr [[RETVAL]], align 4
// 64BITAIX-NEXT: ret { double, double } [[TMP2]]
//
-// 32BIT-LABEL: @test_xl_cmplxl(
-// 32BIT-NEXT: entry:
-// 32BIT-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BIT-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BIT-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
-// 32BIT-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
-// 32BIT-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
-// 32BIT-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
-// 32BIT-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
-// 32BIT-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
-// 32BIT-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
-// 32BIT-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
-// 32BIT-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
-// 32BIT-NEXT: ret void
+// 32BIT-CLANG22-LABEL: @test_xl_cmplxl(
+// 32BIT-CLANG22-NEXT: entry:
+// 32BIT-CLANG22-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BIT-CLANG22-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BIT-CLANG22-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
+// 32BIT-CLANG22-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
+// 32BIT-CLANG22-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
+// 32BIT-CLANG22-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
+// 32BIT-CLANG22-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
+// 32BIT-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
+// 32BIT-CLANG22-NEXT: ret void
+//
+// 32BIT-CLANG23-LABEL: @test_xl_cmplxl(
+// 32BIT-CLANG23-NEXT: entry:
+// 32BIT-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// 32BIT-CLANG23-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BIT-CLANG23-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
+// 32BIT-CLANG23-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
+// 32BIT-CLANG23-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
+// 32BIT-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[TMP0]], ptr [[RETVAL_REALP]], align 16
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
+// 32BIT-CLANG23-NEXT: [[TMP2:%.*]] = load [2 x i128], ptr [[RETVAL]], align 16
+// 32BIT-CLANG23-NEXT: ret [2 x i128] [[TMP2]]
+//
+// 32BITLE-CLANG22-LABEL: @test_xl_cmplxl(
+// 32BITLE-CLANG22-NEXT: entry:
+// 32BITLE-CLANG22-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BITLE-CLANG22-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
+// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
+// 32BITLE-CLANG22-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
+// 32BITLE-CLANG22-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
+// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
+// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
+// 32BITLE-CLANG22-NEXT: ret void
//
-// 32BITLE-LABEL: @test_xl_cmplxl(
-// 32BITLE-NEXT: entry:
-// 32BITLE-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BITLE-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BITLE-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
-// 32BITLE-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
-// 32BITLE-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
-// 32BITLE-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
-// 32BITLE-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
-// 32BITLE-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
-// 32BITLE-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
-// 32BITLE-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
-// 32BITLE-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
-// 32BITLE-NEXT: ret void
+// 32BITLE-CLANG23-LABEL: @test_xl_cmplxl(
+// 32BITLE-CLANG23-NEXT: entry:
+// 32BITLE-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// 32BITLE-CLANG23-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BITLE-CLANG23-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
+// 32BITLE-CLANG23-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
+// 32BITLE-CLANG23-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
+// 32BITLE-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[TMP0]], ptr [[RETVAL_REALP]], align 16
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
+// 32BITLE-CLANG23-NEXT: [[TMP2:%.*]] = load [2 x i128], ptr [[RETVAL]], align 16
+// 32BITLE-CLANG23-NEXT: ret [2 x i128] [[TMP2]]
//
// 32BITAIX-LABEL: @test_xl_cmplxl(
// 32BITAIX-NEXT: entry:
diff --git a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
index 8911257741c337..b6b6832bce3df7 100644
--- a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
+++ b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
@@ -1,19 +1,37 @@
-// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOLDBL128
-// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOLDBL128
-// RUN: %clang_cc1 -triple powerpc64-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LDBL128
-// RUN: %clang_cc1 -triple ppc64le-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LDBL128
-// RUN: %clang_cc1 -triple powerpc-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-NOLDBL128,CHECK
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-NOLDBL128,CHECK
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-LDBL128,CHECK
+// RUN: %clang_cc1 -triple ppc64le-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-LDBL128,CHECK
+// RUN: %clang_cc1 -triple powerpc-unknown-linux -fclang-abi-compat=22 -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX-CLANG22
+// RUN: %clang_cc1 -triple powerpc-unknown-linux -fclang-abi-compat=23 -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX-CLANG23
_Complex float foo1(_Complex float x) {
return x;
// CHECK-LABEL: define{{.*}} { float, float } @foo1(float noundef %x.{{.*}}, float noundef %x.{{.*}}) #0 {
// CHECK: ret { float, float }
-// PPC32LNX-LABEL: define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 {
-// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 1
-// PPC32LNX-NEXT: store float %{{.*}}, ptr [[RETREAL]], align 4
-// PPC32LNX-NEXT: store float %{{.*}}, ptr [[RETIMAG]], align 4
+// PPC32LNX-CLANG22-LABEL: define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 {
+// PPC32LNX-CLANG22: [[RETREAL:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-CLANG22-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX-CLANG22-NEXT: store float %{{.*}}, ptr [[RETREAL]], align 4
+// PPC32LNX-CLANG22-NEXT: store float %{{.*}}, ptr [[RETIMAG]], align 4
+
+// PPC32LNX-CLANG23-LABEL: define dso_local <2 x i32> @foo1(
+// PPC32LNX-CLANG23-SAME: <2 x i32> noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
+// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { float, float }, align 4
+// PPC32LNX-CLANG23-NEXT: store <2 x i32> [[X_COERCE]], ptr [[X]], align 4
+// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
+// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: [[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
+// PPC32LNX-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: store float [[X_REAL]], ptr [[RETVAL_REALP]], align 4
+// PPC32LNX-CLANG23-NEXT: store float [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// PPC32LNX-CLANG23-NEXT: ret <2 x i32> [[TMP0]]
}
_Complex double foo2(_Complex double x) {
@@ -21,11 +39,28 @@ _Complex double foo2(_Complex double x) {
// CHECK-LABEL: define{{.*}} { double, double } @foo2(double noundef %x.{{.*}}, double noundef %x.{{.*}}) #0 {
// CHECK: ret { double, double }
-// PPC32LNX-LABEL: define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 {
-// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 1
-// PPC32LNX-NEXT: store double %{{.*}}, ptr [[RETREAL]], align 8
-// PPC32LNX-NEXT: store double %{{.*}}, ptr [[RETIMAG]], align 8
+// PPC32LNX-CLANG22-LABEL: define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 {
+// PPC32LNX-CLANG22: [[RETREAL:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-CLANG22-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX-CLANG22-NEXT: store double %{{.*}}, ptr [[RETREAL]], align 8
+// PPC32LNX-CLANG22-NEXT: store double %{{.*}}, ptr [[RETIMAG]], align 8
+
+// PPC32LNX-CLANG23-LABEL: define dso_local [4 x i32] @foo2(
+// PPC32LNX-CLANG23-SAME: [4 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
+// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { double, double }, align 8
+// PPC32LNX-CLANG23-NEXT: store [4 x i32] [[X_COERCE]], ptr [[X]], align 8
+// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 8
+// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: [[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 8
+// PPC32LNX-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: store double [[X_REAL]], ptr [[RETVAL_REALP]], align 8
+// PPC32LNX-CLANG23-NEXT: store double [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 8
+// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// PPC32LNX-CLANG23-NEXT: ret [4 x i32] [[TMP0]]
}
_Complex long double foo3(_Complex long double x) {
@@ -36,9 +71,26 @@ _Complex long double foo3(_Complex long double x) {
// CHECK-LDBL128-LABEL: define{{.*}} { ppc_fp128, ppc_fp128 } @foo3(ppc_fp128 noundef %x.{{.*}}, ppc_fp128 noundef %x.{{.*}}) #0 {
// CHECK-LDBL128: ret { ppc_fp128, ppc_fp128 }
-// PPC32LNX-LABEL: define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
-// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
-// PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
-// PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
+// PPC32LNX-CLANG22-LABEL: define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
+// PPC32LNX-CLANG22: [[RETREAL:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-CLANG22-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX-CLANG22-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
+// PPC32LNX-CLANG22-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
+
+// PPC32LNX-CLANG23-LABEL: define dso_local [2 x i128] @foo3(
+// PPC32LNX-CLANG23-SAME: [2 x i128] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
+// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// PPC32LNX-CLANG23-NEXT: store [2 x i128] [[X_COERCE]], ptr [[X]], align 16
+// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], align 16
+// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: [[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], align 16
+// PPC32LNX-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], align 16
+// PPC32LNX-CLANG23-NEXT: store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 16
+// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load [2 x i128], ptr [[RETVAL]], align 16
+// PPC32LNX-CLANG23-NEXT: ret [2 x i128] [[TMP0]]
}
diff --git a/clang/test/CodeGen/long_double_fp128.cpp b/clang/test/CodeGen/long_double_fp128.cpp
index a66e5c5be585fb..6b2360d724fa13 100644
--- a/clang/test/CodeGen/long_double_fp128.cpp
+++ b/clang/test/CodeGen/long_double_fp128.cpp
@@ -8,8 +8,10 @@
// RUN: | FileCheck %s --check-prefix=A32
// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm -o - %s \
// RUN: | FileCheck %s --check-prefix=G32
-// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm -o - %s \
-// RUN: | FileCheck %s --check-prefix=P32
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fclang-abi-compat=22 -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=P32-CLANG22
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fclang-abi-compat=23 -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=P32-CLANG23
// Check mangled name of long double.
// Android's gcc and llvm use fp128 for long double.
@@ -19,4 +21,5 @@ void test(long, float, double, long double, long double _Complex) { }
// P64: define{{.*}} void @_Z4testlfdgCg(i64 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, ppc_fp128 {{.*}}, ppc_fp128
// A32: define{{.*}} void @_Z4testlfdeCe(i32 noundef %0, float noundef %1, double noundef %2, double noundef %3, ptr
// G32: define{{.*}} void @_Z4testlfdeCe(i32 noundef %0, float noundef %1, double noundef %2, x86_fp80 noundef %3, ptr
-// P32: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, ptr
+// P32-CLANG22: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, ptr
+// P32-CLANG23: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, [7 x i32] {{.*}}, [2 x i128]
diff --git a/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c b/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
index 11158606a411ce..0bf6c7c1368d35 100644
--- a/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
+++ b/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
@@ -2,7 +2,8 @@
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s -check-prefixes=CHECK
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s -check-prefixes=CHECK-WIN64
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s -check-prefixes=CHECK-I686
-// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s -check-prefixes=CHECK-PPC
+// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple powerpc-unknown-unknown -fclang-abi-compat=22 -o - | FileCheck %s -check-prefixes=CHECK-PPC-CLANG22
+// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple powerpc-unknown-unknown -fclang-abi-compat=23 -o - | FileCheck %s -check-prefixes=CHECK-PPC-CLANG23
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s -check-prefixes=CHECK-ARM
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s -check-prefixes=CHECK-ARM-HF
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s -check-prefixes=CHECK-THUMB
@@ -28,9 +29,13 @@ long double powl(long double a, long double b);
// CHECK-I686-SAME: x86_fp80 noundef [[A:%.*]], x86_fp80 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-I686: [[CALL:%.*]] = tail call x86_fp80 @powl(x86_fp80 noundef [[A]], x86_fp80 noundef [[B]]) #[[ATTR5:[0-9]+]]
//
-// CHECK-PPC-LABEL: define dso_local ppc_fp128 @test_powl(
-// CHECK-PPC-SAME: ppc_fp128 noundef [[A:%.*]], ppc_fp128 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-PPC: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR4:[0-9]+]]
+// CHECK-PPC-CLANG22-LABEL: define dso_local ppc_fp128 @test_powl(
+// CHECK-PPC-CLANG22-SAME: ppc_fp128 noundef [[A:%.*]], ppc_fp128 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-PPC-CLANG22: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR4:[0-9]+]]
+//
+// CHECK-PPC-CLANG23-LABEL: define dso_local ppc_fp128 @test_powl(
+// CHECK-PPC-CLANG23-SAME: ppc_fp128 noundef [[A:%.*]], ppc_fp128 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR3:[0-9]+]]
//
// CHECK-ARM-LABEL: define dso_local double @test_powl(
// CHECK-ARM-SAME: double noundef [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
@@ -92,15 +97,19 @@ long double test_powl(long double a, long double b) {
// CHECK-I686: store x86_fp80 [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 4
// CHECK-I686: store x86_fp80 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 4
//
-// CHECK-PPC-LABEL: define dso_local void @test_cargl(
-// CHECK-PPC-SAME: ptr dead_on_unwind noalias nofree writable writeonly sret({ ppc_fp128, ppc_fp128 }) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr nofree noundef readonly byval({ ppc_fp128, ppc_fp128 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
-// CHECK-PPC: [[CLD_REAL:%.*]] = load ppc_fp128, ptr [[CLD]], align 16
-// CHECK-PPC: [[CLD_IMAG:%.*]] = load ppc_fp128, ptr [[CLD_IMAGP:%.*]], align 16
-// CHECK-PPC: store ppc_fp128 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16
-// CHECK-PPC: store ppc_fp128 [[CLD_IMAG]], ptr [[BYVAL_TEMP_IMAGP:%.*]], align 16
-// CHECK-PPC: [[CALL:%.*]] = tail call ppc_fp128 @cargl(ptr noundef nonnull byval({ ppc_fp128, ppc_fp128 }) align 16 [[BYVAL_TEMP]]) #[[ATTR4]]
-// CHECK-PPC: store ppc_fp128 [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 16
-// CHECK-PPC: store ppc_fp128 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 16
+// CHECK-PPC-CLANG22-LABEL: define dso_local void @test_cargl(
+// CHECK-PPC-CLANG22-SAME: ptr dead_on_unwind noalias nofree writable writeonly sret({ ppc_fp128, ppc_fp128 }) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr nofree noundef readonly byval({ ppc_fp128, ppc_fp128 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// CHECK-PPC-CLANG22: [[CLD_REAL:%.*]] = load ppc_fp128, ptr [[CLD]], align 16
+// CHECK-PPC-CLANG22: [[CLD_IMAG:%.*]] = load ppc_fp128, ptr [[CLD_IMAGP:%.*]], align 16
+// CHECK-PPC-CLANG22: store ppc_fp128 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16
+// CHECK-PPC-CLANG22: store ppc_fp128 [[CLD_IMAG]], ptr [[BYVAL_TEMP_IMAGP:%.*]], align 16
+// CHECK-PPC-CLANG22: [[CALL:%.*]] = tail call ppc_fp128 @cargl(ptr noundef nonnull byval({ ppc_fp128, ppc_fp128 }) align 16 [[BYVAL_TEMP]]) #[[ATTR4]]
+// CHECK-PPC-CLANG22: store ppc_fp128 [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 16
+// CHECK-PPC-CLANG22: store ppc_fp128 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 16
+//
+// CHECK-PPC-CLANG23-LABEL: define dso_local [2 x i128] @test_cargl(
+// CHECK-PPC-CLANG23-SAME: [2 x i128] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call ppc_fp128 @cargl([2 x i128] noundef [[CLD_COERCE]]) #[[ATTR3]]
//
// CHECK-ARM-LABEL: define dso_local void @test_cargl(
// CHECK-ARM-SAME: ptr dead_on_unwind noalias nofree writable writeonly sret({ double, double }) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], [2 x i64] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
@@ -164,9 +173,13 @@ int ilogbl(long double a);
// CHECK-I686-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-I686: [[CALL:%.*]] = tail call i32 @ilogbl(x86_fp80 noundef [[A]]) #[[ATTR5]]
//
-// CHECK-PPC-LABEL: define dso_local i32 @test_ilogb(
-// CHECK-PPC-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
-// CHECK-PPC: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR4]]
+// CHECK-PPC-CLANG22-LABEL: define dso_local i32 @test_ilogb(
+// CHECK-PPC-CLANG22-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-PPC-CLANG22: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR4]]
+//
+// CHECK-PPC-CLANG23-LABEL: define dso_local i32 @test_ilogb(
+// CHECK-PPC-CLANG23-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR3]]
//
// CHECK-ARM-LABEL: define dso_local i32 @test_ilogb(
// CHECK-ARM-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
>From 4070ed8855149143ab77940cadafcd62c75e99c3 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Mon, 3 Aug 2026 01:32:55 +0200
Subject: [PATCH 08/12] remove special-casing of _Complex ppcfp128, it is not
needed
---
clang/lib/CodeGen/Targets/PPC.cpp | 12 ++----------
clang/test/CodeGen/PowerPC/powerpc-c99complex.c | 10 +++++-----
2 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index b824e66a005f0b..a9f57249e14e6e 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -442,20 +442,12 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
}
ABIArgInfo PPC32_SVR4_ABIInfo::classifyComplexType(QualType Ty) const {
+ assert(Ty->isAnyComplexType() && "not a complex type");
+
uint64_t Size = getContext().getTypeSize(Ty);
llvm::LLVMContext &VMC = getVMContext();
llvm::Type *I32 = llvm::Type::getInt32Ty(VMC);
- assert(Ty->isAnyComplexType() && "not a complex type");
- QualType ElemTy = Ty->castAs<ComplexType>()->getElementType();
-
- // Work around https://github.com/llvm/llvm-project/issues/44482.
- // This is a bug where the two halves of a ppc_fp128 are swapped.
- // Using i128 for the ABI instead circumvents this issue.
- if (CGT.ConvertType(ElemTy)->isPPC_FP128Ty())
- return ABIArgInfo::getDirect(
- llvm::ArrayType::get(llvm::Type::getInt128Ty(VMC), 2));
-
// Coerce to an integer for _Complex char and _Complex short.
if (Size <= GPRBits)
return ABIArgInfo::getDirect(llvm::IntegerType::get(VMC, Size));
diff --git a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
index b6b6832bce3df7..10e10fbe38dc27 100644
--- a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
+++ b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
@@ -77,12 +77,12 @@ _Complex long double foo3(_Complex long double x) {
// PPC32LNX-CLANG22-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
// PPC32LNX-CLANG22-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
-// PPC32LNX-CLANG23-LABEL: define dso_local [2 x i128] @foo3(
-// PPC32LNX-CLANG23-SAME: [2 x i128] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32LNX-CLANG23-LABEL: define dso_local [8 x i32] @foo3(
+// PPC32LNX-CLANG23-SAME: [8 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
-// PPC32LNX-CLANG23-NEXT: store [2 x i128] [[X_COERCE]], ptr [[X]], align 16
+// PPC32LNX-CLANG23-NEXT: store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], align 16
// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
@@ -91,6 +91,6 @@ _Complex long double foo3(_Complex long double x) {
// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
// PPC32LNX-CLANG23-NEXT: store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], align 16
// PPC32LNX-CLANG23-NEXT: store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 16
-// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load [2 x i128], ptr [[RETVAL]], align 16
-// PPC32LNX-CLANG23-NEXT: ret [2 x i128] [[TMP0]]
+// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 16
+// PPC32LNX-CLANG23-NEXT: ret [8 x i32] [[TMP0]]
}
>From 87fda83754a2748fc6f320f874b590ce5b505117 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Wed, 5 Aug 2026 11:10:17 +0200
Subject: [PATCH 09/12] update for LLVM 23
---
clang/lib/CodeGen/Targets/PPC.cpp | 2 +-
.../test/CodeGen/PowerPC/powerpc-c99complex.c | 128 +++++++++---------
2 files changed, 65 insertions(+), 65 deletions(-)
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index a9f57249e14e6e..80a62f9e0d791b 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -369,7 +369,7 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
bool isComplexGnuABI() const {
return !getTarget().getTriple().isOSDarwin() &&
!getContext().getLangOpts().isCompatibleWith(
- LangOptions::ClangABI::Ver22);
+ LangOptions::ClangABI::Ver23);
}
CharUnits getParamTypeAlignment(QualType Ty) const;
diff --git a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
index 10e10fbe38dc27..b0b0224f701359 100644
--- a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
+++ b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
@@ -2,36 +2,36 @@
// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-NOLDBL128,CHECK
// RUN: %clang_cc1 -triple powerpc64-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-LDBL128,CHECK
// RUN: %clang_cc1 -triple ppc64le-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK-LDBL128,CHECK
-// RUN: %clang_cc1 -triple powerpc-unknown-linux -fclang-abi-compat=22 -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX-CLANG22
// RUN: %clang_cc1 -triple powerpc-unknown-linux -fclang-abi-compat=23 -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX-CLANG23
+// RUN: %clang_cc1 -triple powerpc-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX
_Complex float foo1(_Complex float x) {
return x;
// CHECK-LABEL: define{{.*}} { float, float } @foo1(float noundef %x.{{.*}}, float noundef %x.{{.*}}) #0 {
// CHECK: ret { float, float }
-// PPC32LNX-CLANG22-LABEL: define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 {
-// PPC32LNX-CLANG22: [[RETREAL:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-CLANG22-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 1
-// PPC32LNX-CLANG22-NEXT: store float %{{.*}}, ptr [[RETREAL]], align 4
-// PPC32LNX-CLANG22-NEXT: store float %{{.*}}, ptr [[RETIMAG]], align 4
+// PPC32LNX-CLANG23-LABEL: define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 {
+// PPC32LNX-CLANG23: [[RETREAL:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: store float %{{.*}}, ptr [[RETREAL]], align 4
+// PPC32LNX-CLANG23-NEXT: store float %{{.*}}, ptr [[RETIMAG]], align 4
-// PPC32LNX-CLANG23-LABEL: define dso_local <2 x i32> @foo1(
-// PPC32LNX-CLANG23-SAME: <2 x i32> noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
-// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
-// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
-// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { float, float }, align 4
-// PPC32LNX-CLANG23-NEXT: store <2 x i32> [[X_COERCE]], ptr [[X]], align 4
-// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 0
-// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
-// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 1
-// PPC32LNX-CLANG23-NEXT: [[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
-// PPC32LNX-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
-// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
-// PPC32LNX-CLANG23-NEXT: store float [[X_REAL]], ptr [[RETVAL_REALP]], align 4
-// PPC32LNX-CLANG23-NEXT: store float [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 4
-// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
-// PPC32LNX-CLANG23-NEXT: ret <2 x i32> [[TMP0]]
+// PPC32LNX-LABEL: define dso_local <2 x i32> @foo1(
+// PPC32LNX-SAME: <2 x i32> noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// PPC32LNX-NEXT: [[ENTRY:.*:]]
+// PPC32LNX-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// PPC32LNX-NEXT: [[X:%.*]] = alloca { float, float }, align 4
+// PPC32LNX-NEXT: store <2 x i32> [[X_COERCE]], ptr [[X]], align 4
+// PPC32LNX-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 0
+// PPC32LNX-NEXT: [[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
+// PPC32LNX-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 1
+// PPC32LNX-NEXT: [[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
+// PPC32LNX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32LNX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32LNX-NEXT: store float [[X_REAL]], ptr [[RETVAL_REALP]], align 4
+// PPC32LNX-NEXT: store float [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// PPC32LNX-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// PPC32LNX-NEXT: ret <2 x i32> [[TMP0]]
}
_Complex double foo2(_Complex double x) {
@@ -39,28 +39,28 @@ _Complex double foo2(_Complex double x) {
// CHECK-LABEL: define{{.*}} { double, double } @foo2(double noundef %x.{{.*}}, double noundef %x.{{.*}}) #0 {
// CHECK: ret { double, double }
-// PPC32LNX-CLANG22-LABEL: define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 {
-// PPC32LNX-CLANG22: [[RETREAL:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-CLANG22-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 1
-// PPC32LNX-CLANG22-NEXT: store double %{{.*}}, ptr [[RETREAL]], align 8
-// PPC32LNX-CLANG22-NEXT: store double %{{.*}}, ptr [[RETIMAG]], align 8
+// PPC32LNX-CLANG23-LABEL: define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 {
+// PPC32LNX-CLANG23: [[RETREAL:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: store double %{{.*}}, ptr [[RETREAL]], align 8
+// PPC32LNX-CLANG23-NEXT: store double %{{.*}}, ptr [[RETIMAG]], align 8
-// PPC32LNX-CLANG23-LABEL: define dso_local [4 x i32] @foo2(
-// PPC32LNX-CLANG23-SAME: [4 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
-// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
-// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
-// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { double, double }, align 8
-// PPC32LNX-CLANG23-NEXT: store [4 x i32] [[X_COERCE]], ptr [[X]], align 8
-// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 0
-// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 8
-// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 1
-// PPC32LNX-CLANG23-NEXT: [[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 8
-// PPC32LNX-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
-// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
-// PPC32LNX-CLANG23-NEXT: store double [[X_REAL]], ptr [[RETVAL_REALP]], align 8
-// PPC32LNX-CLANG23-NEXT: store double [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 8
-// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
-// PPC32LNX-CLANG23-NEXT: ret [4 x i32] [[TMP0]]
+// PPC32LNX-LABEL: define dso_local [4 x i32] @foo2(
+// PPC32LNX-SAME: [4 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32LNX-NEXT: [[ENTRY:.*:]]
+// PPC32LNX-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// PPC32LNX-NEXT: [[X:%.*]] = alloca { double, double }, align 8
+// PPC32LNX-NEXT: store [4 x i32] [[X_COERCE]], ptr [[X]], align 8
+// PPC32LNX-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 0
+// PPC32LNX-NEXT: [[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 8
+// PPC32LNX-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 1
+// PPC32LNX-NEXT: [[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 8
+// PPC32LNX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32LNX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32LNX-NEXT: store double [[X_REAL]], ptr [[RETVAL_REALP]], align 8
+// PPC32LNX-NEXT: store double [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 8
+// PPC32LNX-NEXT: [[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// PPC32LNX-NEXT: ret [4 x i32] [[TMP0]]
}
_Complex long double foo3(_Complex long double x) {
@@ -71,26 +71,26 @@ _Complex long double foo3(_Complex long double x) {
// CHECK-LDBL128-LABEL: define{{.*}} { ppc_fp128, ppc_fp128 } @foo3(ppc_fp128 noundef %x.{{.*}}, ppc_fp128 noundef %x.{{.*}}) #0 {
// CHECK-LDBL128: ret { ppc_fp128, ppc_fp128 }
-// PPC32LNX-CLANG22-LABEL: define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
-// PPC32LNX-CLANG22: [[RETREAL:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-CLANG22-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
-// PPC32LNX-CLANG22-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
-// PPC32LNX-CLANG22-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
+// PPC32LNX-CLANG23-LABEL: define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
+// PPC32LNX-CLANG23: [[RETREAL:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-CLANG23-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX-CLANG23-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
+// PPC32LNX-CLANG23-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
-// PPC32LNX-CLANG23-LABEL: define dso_local [8 x i32] @foo3(
-// PPC32LNX-CLANG23-SAME: [8 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
-// PPC32LNX-CLANG23-NEXT: [[ENTRY:.*:]]
-// PPC32LNX-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
-// PPC32LNX-CLANG23-NEXT: [[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
-// PPC32LNX-CLANG23-NEXT: store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
-// PPC32LNX-CLANG23-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
-// PPC32LNX-CLANG23-NEXT: [[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], align 16
-// PPC32LNX-CLANG23-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
-// PPC32LNX-CLANG23-NEXT: [[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], align 16
-// PPC32LNX-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
-// PPC32LNX-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
-// PPC32LNX-CLANG23-NEXT: store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], align 16
-// PPC32LNX-CLANG23-NEXT: store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 16
-// PPC32LNX-CLANG23-NEXT: [[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 16
-// PPC32LNX-CLANG23-NEXT: ret [8 x i32] [[TMP0]]
+// PPC32LNX-LABEL: define dso_local [8 x i32] @foo3(
+// PPC32LNX-SAME: [8 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32LNX-NEXT: [[ENTRY:.*:]]
+// PPC32LNX-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// PPC32LNX-NEXT: [[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// PPC32LNX-NEXT: store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// PPC32LNX-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// PPC32LNX-NEXT: [[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], align 16
+// PPC32LNX-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// PPC32LNX-NEXT: [[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], align 16
+// PPC32LNX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32LNX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32LNX-NEXT: store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], align 16
+// PPC32LNX-NEXT: store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 16
+// PPC32LNX-NEXT: [[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 16
+// PPC32LNX-NEXT: ret [8 x i32] [[TMP0]]
}
>From c7190b7e4716132f26d67129bfde0bd1db93da2c Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Wed, 5 Aug 2026 11:10:48 +0200
Subject: [PATCH 10/12] add to release notes and abiversions
---
clang/docs/ReleaseNotes.md | 3 +++
clang/include/clang/Basic/ABIVersions.def | 1 +
2 files changed, 4 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a1f24a8caedae5..8429ed5aa2b952 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -112,6 +112,9 @@ features cannot lower the translation-unit ABI level;
for homogeneous aggregate classification.
`-fclang-abi-compat=23` restores the previous behavior. (#GH218799)
+- On PowerPC (32-bit), the ABI of `_Complex` now matches GCC.
+ `-fclang-abi-compat=23` restores the previous behavior. (#GH208917)
+
### AST Dumping Potentially Breaking Changes
### Clang Frontend Potentially Breaking Changes
diff --git a/clang/include/clang/Basic/ABIVersions.def b/clang/include/clang/Basic/ABIVersions.def
index 3c434da91bfab8..cd6cdf17b49f6f 100644
--- a/clang/include/clang/Basic/ABIVersions.def
+++ b/clang/include/clang/Basic/ABIVersions.def
@@ -167,6 +167,7 @@ ABI_VER_MAJOR(22)
/// faithfully reproduces Clang 23, including its crash on aggregates such
/// as a run of `__int128` bit-fields, where skipping the unnamed field
/// leaves part of a wider access unit unclassified.)
+/// - On PowerPC (32-bit), treat `_Complex` like a struct of two scalar fields.
ABI_VER_MAJOR(23)
/// Conform to the underlying platform's C and C++ ABIs as closely as we can.
>From 4978f3d09c0b3bc38b47e7ab878e4d27ff5fa50a Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Wed, 5 Aug 2026 13:52:43 +0200
Subject: [PATCH 11/12] update remaining tests
---
.../PowerPC/builtins-ppc-xlcompat-cmplx.c | 350 +++++++++---------
clang/test/CodeGen/long_double_fp128.cpp | 8 +-
.../math-libcalls-tbaa-indirect-args.c | 46 +--
3 files changed, 202 insertions(+), 202 deletions(-)
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c
index ae224aef66da96..454c09f63be481 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cmplx.c
@@ -6,14 +6,14 @@
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=64BITLE
// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=64BITAIX
-// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fclang-abi-compat=22 \
-// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BIT-CLANG22
// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fclang-abi-compat=23 \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BIT-CLANG23
-// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu -fclang-abi-compat=22 \
-// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=32BITLE-CLANG22
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BIT
// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu -fclang-abi-compat=23 \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=32BITLE-CLANG23
+// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu \
+// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefix=32BITLE
// RUN: %clang_cc1 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix=32BITAIX
@@ -65,81 +65,81 @@
// 64BITAIX-NEXT: [[TMP2:%.*]] = load { double, double }, ptr [[RETVAL]], align 4
// 64BITAIX-NEXT: ret { double, double } [[TMP2]]
//
-// 32BIT-CLANG22-LABEL: @testcmplx(
-// 32BIT-CLANG22-NEXT: entry:
-// 32BIT-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
-// 32BIT-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
-// 32BIT-CLANG22-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
-// 32BIT-CLANG22-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
-// 32BIT-CLANG22-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
-// 32BIT-CLANG22-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
-// 32BIT-CLANG22-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
-// 32BIT-CLANG22-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
-// 32BIT-CLANG22-NEXT: ret void
-//
// 32BIT-CLANG23-LABEL: @testcmplx(
// 32BIT-CLANG23-NEXT: entry:
-// 32BIT-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// 32BIT-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
// 32BIT-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
// 32BIT-CLANG23-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
// 32BIT-CLANG23-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
// 32BIT-CLANG23-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
// 32BIT-CLANG23-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
-// 32BIT-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
-// 32BIT-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
-// 32BIT-CLANG23-NEXT: store double [[TMP0]], ptr [[RETVAL_REALP]], align 8
-// 32BIT-CLANG23-NEXT: store double [[TMP1]], ptr [[RETVAL_IMAGP]], align 8
-// 32BIT-CLANG23-NEXT: [[TMP2:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
-// 32BIT-CLANG23-NEXT: ret [4 x i32] [[TMP2]]
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
+// 32BIT-CLANG23-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// 32BIT-CLANG23-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// 32BIT-CLANG23-NEXT: ret void
//
-// 32BITLE-CLANG22-LABEL: @testcmplx(
-// 32BITLE-CLANG22-NEXT: entry:
-// 32BITLE-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
-// 32BITLE-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
-// 32BITLE-CLANG22-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
-// 32BITLE-CLANG22-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
-// 32BITLE-CLANG22-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
-// 32BITLE-CLANG22-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
-// 32BITLE-CLANG22-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
-// 32BITLE-CLANG22-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
-// 32BITLE-CLANG22-NEXT: ret void
+// 32BIT-LABEL: @testcmplx(
+// 32BIT-NEXT: entry:
+// 32BIT-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// 32BIT-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
+// 32BIT-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
+// 32BIT-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
+// 32BIT-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
+// 32BIT-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
+// 32BIT-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
+// 32BIT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// 32BIT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// 32BIT-NEXT: store double [[TMP0]], ptr [[RETVAL_REALP]], align 8
+// 32BIT-NEXT: store double [[TMP1]], ptr [[RETVAL_IMAGP]], align 8
+// 32BIT-NEXT: [[TMP2:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// 32BIT-NEXT: ret [4 x i32] [[TMP2]]
//
// 32BITLE-CLANG23-LABEL: @testcmplx(
// 32BITLE-CLANG23-NEXT: entry:
-// 32BITLE-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// 32BITLE-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
// 32BITLE-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
// 32BITLE-CLANG23-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
// 32BITLE-CLANG23-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
// 32BITLE-CLANG23-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
// 32BITLE-CLANG23-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
-// 32BITLE-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
-// 32BITLE-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
-// 32BITLE-CLANG23-NEXT: store double [[TMP0]], ptr [[RETVAL_REALP]], align 8
-// 32BITLE-CLANG23-NEXT: store double [[TMP1]], ptr [[RETVAL_IMAGP]], align 8
-// 32BITLE-CLANG23-NEXT: [[TMP2:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
-// 32BITLE-CLANG23-NEXT: ret [4 x i32] [[TMP2]]
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store double [[TMP0]], ptr [[AGG_RESULT_REALP]], align 8
+// 32BITLE-CLANG23-NEXT: store double [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 8
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// 32BITLE-CLANG23-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// 32BITLE-CLANG23-NEXT: ret void
+//
+// 32BITLE-LABEL: @testcmplx(
+// 32BITLE-NEXT: entry:
+// 32BITLE-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// 32BITLE-NEXT: [[REAL_ADDR:%.*]] = alloca double, align 8
+// 32BITLE-NEXT: [[IMAG_ADDR:%.*]] = alloca double, align 8
+// 32BITLE-NEXT: store double [[REAL:%.*]], ptr [[REAL_ADDR]], align 8
+// 32BITLE-NEXT: store double [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 8
+// 32BITLE-NEXT: [[TMP0:%.*]] = load double, ptr [[REAL_ADDR]], align 8
+// 32BITLE-NEXT: [[TMP1:%.*]] = load double, ptr [[IMAG_ADDR]], align 8
+// 32BITLE-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// 32BITLE-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// 32BITLE-NEXT: store double [[TMP0]], ptr [[RETVAL_REALP]], align 8
+// 32BITLE-NEXT: store double [[TMP1]], ptr [[RETVAL_IMAGP]], align 8
+// 32BITLE-NEXT: [[TMP2:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// 32BITLE-NEXT: ret [4 x i32] [[TMP2]]
//
// 32BITAIX-LABEL: @testcmplx(
// 32BITAIX-NEXT: entry:
@@ -209,81 +209,81 @@ double _Complex testcmplx(double real, double imag) {
// 64BITAIX-NEXT: [[TMP2:%.*]] = load { float, float }, ptr [[RETVAL]], align 4
// 64BITAIX-NEXT: ret { float, float } [[TMP2]]
//
-// 32BIT-CLANG22-LABEL: @testcmplxf(
-// 32BIT-CLANG22-NEXT: entry:
-// 32BIT-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
-// 32BIT-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
-// 32BIT-CLANG22-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
-// 32BIT-CLANG22-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
-// 32BIT-CLANG22-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
-// 32BIT-CLANG22-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
-// 32BIT-CLANG22-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
-// 32BIT-CLANG22-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
-// 32BIT-CLANG22-NEXT: ret void
-//
// 32BIT-CLANG23-LABEL: @testcmplxf(
// 32BIT-CLANG23-NEXT: entry:
-// 32BIT-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// 32BIT-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
// 32BIT-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
// 32BIT-CLANG23-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
// 32BIT-CLANG23-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
// 32BIT-CLANG23-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
// 32BIT-CLANG23-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
-// 32BIT-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
-// 32BIT-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
-// 32BIT-CLANG23-NEXT: store float [[TMP0]], ptr [[RETVAL_REALP]], align 4
-// 32BIT-CLANG23-NEXT: store float [[TMP1]], ptr [[RETVAL_IMAGP]], align 4
-// 32BIT-CLANG23-NEXT: [[TMP2:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
-// 32BIT-CLANG23-NEXT: ret <2 x i32> [[TMP2]]
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
+// 32BIT-CLANG23-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// 32BIT-CLANG23-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// 32BIT-CLANG23-NEXT: ret void
//
-// 32BITLE-CLANG22-LABEL: @testcmplxf(
-// 32BITLE-CLANG22-NEXT: entry:
-// 32BITLE-CLANG22-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
-// 32BITLE-CLANG22-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
-// 32BITLE-CLANG22-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
-// 32BITLE-CLANG22-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
-// 32BITLE-CLANG22-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
-// 32BITLE-CLANG22-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
-// 32BITLE-CLANG22-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
-// 32BITLE-CLANG22-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
-// 32BITLE-CLANG22-NEXT: ret void
+// 32BIT-LABEL: @testcmplxf(
+// 32BIT-NEXT: entry:
+// 32BIT-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// 32BIT-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
+// 32BIT-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
+// 32BIT-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
+// 32BIT-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
+// 32BIT-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
+// 32BIT-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
+// 32BIT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// 32BIT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// 32BIT-NEXT: store float [[TMP0]], ptr [[RETVAL_REALP]], align 4
+// 32BIT-NEXT: store float [[TMP1]], ptr [[RETVAL_IMAGP]], align 4
+// 32BIT-NEXT: [[TMP2:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// 32BIT-NEXT: ret <2 x i32> [[TMP2]]
//
// 32BITLE-CLANG23-LABEL: @testcmplxf(
// 32BITLE-CLANG23-NEXT: entry:
-// 32BITLE-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// 32BITLE-CLANG23-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
// 32BITLE-CLANG23-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
// 32BITLE-CLANG23-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
// 32BITLE-CLANG23-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
// 32BITLE-CLANG23-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
// 32BITLE-CLANG23-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
-// 32BITLE-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
-// 32BITLE-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
-// 32BITLE-CLANG23-NEXT: store float [[TMP0]], ptr [[RETVAL_REALP]], align 4
-// 32BITLE-CLANG23-NEXT: store float [[TMP1]], ptr [[RETVAL_IMAGP]], align 4
-// 32BITLE-CLANG23-NEXT: [[TMP2:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
-// 32BITLE-CLANG23-NEXT: ret <2 x i32> [[TMP2]]
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store float [[TMP0]], ptr [[AGG_RESULT_REALP]], align 4
+// 32BITLE-CLANG23-NEXT: store float [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 4
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// 32BITLE-CLANG23-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// 32BITLE-CLANG23-NEXT: ret void
+//
+// 32BITLE-LABEL: @testcmplxf(
+// 32BITLE-NEXT: entry:
+// 32BITLE-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// 32BITLE-NEXT: [[REAL_ADDR:%.*]] = alloca float, align 4
+// 32BITLE-NEXT: [[IMAG_ADDR:%.*]] = alloca float, align 4
+// 32BITLE-NEXT: store float [[REAL:%.*]], ptr [[REAL_ADDR]], align 4
+// 32BITLE-NEXT: store float [[IMAG:%.*]], ptr [[IMAG_ADDR]], align 4
+// 32BITLE-NEXT: [[TMP0:%.*]] = load float, ptr [[REAL_ADDR]], align 4
+// 32BITLE-NEXT: [[TMP1:%.*]] = load float, ptr [[IMAG_ADDR]], align 4
+// 32BITLE-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// 32BITLE-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// 32BITLE-NEXT: store float [[TMP0]], ptr [[RETVAL_REALP]], align 4
+// 32BITLE-NEXT: store float [[TMP1]], ptr [[RETVAL_IMAGP]], align 4
+// 32BITLE-NEXT: [[TMP2:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// 32BITLE-NEXT: ret <2 x i32> [[TMP2]]
//
// 32BITAIX-LABEL: @testcmplxf(
// 32BITAIX-NEXT: entry:
@@ -353,81 +353,81 @@ float _Complex testcmplxf(float real, float imag) {
// 64BITAIX-NEXT: [[TMP2:%.*]] = load { double, double }, ptr [[RETVAL]], align 4
// 64BITAIX-NEXT: ret { double, double } [[TMP2]]
//
-// 32BIT-CLANG22-LABEL: @test_xl_cmplxl(
-// 32BIT-CLANG22-NEXT: entry:
-// 32BIT-CLANG22-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BIT-CLANG22-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BIT-CLANG22-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
-// 32BIT-CLANG22-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
-// 32BIT-CLANG22-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
-// 32BIT-CLANG22-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
-// 32BIT-CLANG22-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BIT-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BIT-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
-// 32BIT-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
-// 32BIT-CLANG22-NEXT: ret void
-//
// 32BIT-CLANG23-LABEL: @test_xl_cmplxl(
// 32BIT-CLANG23-NEXT: entry:
-// 32BIT-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
// 32BIT-CLANG23-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
// 32BIT-CLANG23-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
// 32BIT-CLANG23-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
// 32BIT-CLANG23-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
// 32BIT-CLANG23-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
// 32BIT-CLANG23-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
-// 32BIT-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
-// 32BIT-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
-// 32BIT-CLANG23-NEXT: store ppc_fp128 [[TMP0]], ptr [[RETVAL_REALP]], align 16
-// 32BIT-CLANG23-NEXT: store ppc_fp128 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
-// 32BIT-CLANG23-NEXT: [[TMP2:%.*]] = load [2 x i128], ptr [[RETVAL]], align 16
-// 32BIT-CLANG23-NEXT: ret [2 x i128] [[TMP2]]
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BIT-CLANG23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
+// 32BIT-CLANG23-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
+// 32BIT-CLANG23-NEXT: ret void
//
-// 32BITLE-CLANG22-LABEL: @test_xl_cmplxl(
-// 32BITLE-CLANG22-NEXT: entry:
-// 32BITLE-CLANG22-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BITLE-CLANG22-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
-// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
-// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
-// 32BITLE-CLANG22-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
-// 32BITLE-CLANG22-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
-// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
-// 32BITLE-CLANG22-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
-// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
-// 32BITLE-CLANG22-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
-// 32BITLE-CLANG22-NEXT: ret void
+// 32BIT-LABEL: @test_xl_cmplxl(
+// 32BIT-NEXT: entry:
+// 32BIT-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// 32BIT-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BIT-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BIT-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
+// 32BIT-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
+// 32BIT-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
+// 32BIT-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
+// 32BIT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// 32BIT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// 32BIT-NEXT: store ppc_fp128 [[TMP0]], ptr [[RETVAL_REALP]], align 16
+// 32BIT-NEXT: store ppc_fp128 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
+// 32BIT-NEXT: [[TMP2:%.*]] = load [8 x i32], ptr [[RETVAL]], align 16
+// 32BIT-NEXT: ret [8 x i32] [[TMP2]]
//
// 32BITLE-CLANG23-LABEL: @test_xl_cmplxl(
// 32BITLE-CLANG23-NEXT: entry:
-// 32BITLE-CLANG23-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
// 32BITLE-CLANG23-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
// 32BITLE-CLANG23-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
// 32BITLE-CLANG23-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
// 32BITLE-CLANG23-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
-// 32BITLE-CLANG23-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
-// 32BITLE-CLANG23-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
-// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[TMP0]], ptr [[RETVAL_REALP]], align 16
-// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
-// 32BITLE-CLANG23-NEXT: [[TMP2:%.*]] = load [2 x i128], ptr [[RETVAL]], align 16
-// 32BITLE-CLANG23-NEXT: ret [2 x i128] [[TMP2]]
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT:%.*]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[TMP0]], ptr [[AGG_RESULT_REALP]], align 16
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[TMP1]], ptr [[AGG_RESULT_IMAGP]], align 16
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// 32BITLE-CLANG23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
+// 32BITLE-CLANG23-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
+// 32BITLE-CLANG23-NEXT: ret void
+//
+// 32BITLE-LABEL: @test_xl_cmplxl(
+// 32BITLE-NEXT: entry:
+// 32BITLE-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// 32BITLE-NEXT: [[LDA_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BITLE-NEXT: [[LDB_ADDR:%.*]] = alloca ppc_fp128, align 16
+// 32BITLE-NEXT: store ppc_fp128 [[LDA:%.*]], ptr [[LDA_ADDR]], align 16
+// 32BITLE-NEXT: store ppc_fp128 [[LDB:%.*]], ptr [[LDB_ADDR]], align 16
+// 32BITLE-NEXT: [[TMP0:%.*]] = load ppc_fp128, ptr [[LDA_ADDR]], align 16
+// 32BITLE-NEXT: [[TMP1:%.*]] = load ppc_fp128, ptr [[LDB_ADDR]], align 16
+// 32BITLE-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// 32BITLE-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// 32BITLE-NEXT: store ppc_fp128 [[TMP0]], ptr [[RETVAL_REALP]], align 16
+// 32BITLE-NEXT: store ppc_fp128 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
+// 32BITLE-NEXT: [[TMP2:%.*]] = load [8 x i32], ptr [[RETVAL]], align 16
+// 32BITLE-NEXT: ret [8 x i32] [[TMP2]]
//
// 32BITAIX-LABEL: @test_xl_cmplxl(
// 32BITAIX-NEXT: entry:
diff --git a/clang/test/CodeGen/long_double_fp128.cpp b/clang/test/CodeGen/long_double_fp128.cpp
index 6b2360d724fa13..b6c853bb48cdaa 100644
--- a/clang/test/CodeGen/long_double_fp128.cpp
+++ b/clang/test/CodeGen/long_double_fp128.cpp
@@ -8,10 +8,10 @@
// RUN: | FileCheck %s --check-prefix=A32
// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm -o - %s \
// RUN: | FileCheck %s --check-prefix=G32
-// RUN: %clang_cc1 -triple powerpc-linux-gnu -fclang-abi-compat=22 -emit-llvm -o - %s \
-// RUN: | FileCheck %s --check-prefix=P32-CLANG22
// RUN: %clang_cc1 -triple powerpc-linux-gnu -fclang-abi-compat=23 -emit-llvm -o - %s \
// RUN: | FileCheck %s --check-prefix=P32-CLANG23
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=P32
// Check mangled name of long double.
// Android's gcc and llvm use fp128 for long double.
@@ -21,5 +21,5 @@ void test(long, float, double, long double, long double _Complex) { }
// P64: define{{.*}} void @_Z4testlfdgCg(i64 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, ppc_fp128 {{.*}}, ppc_fp128
// A32: define{{.*}} void @_Z4testlfdeCe(i32 noundef %0, float noundef %1, double noundef %2, double noundef %3, ptr
// G32: define{{.*}} void @_Z4testlfdeCe(i32 noundef %0, float noundef %1, double noundef %2, x86_fp80 noundef %3, ptr
-// P32-CLANG22: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, ptr
-// P32-CLANG23: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, [7 x i32] {{.*}}, [2 x i128]
+// P32-CLANG23: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, ptr
+// P32: define{{.*}} void @_Z4testlfdgCg(i32 noundef %0, float noundef %1, double noundef %2, ppc_fp128 noundef %3, [7 x i32] {{.*}}, [8 x i32]
diff --git a/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c b/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
index 0bf6c7c1368d35..0345dc680e3af6 100644
--- a/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
+++ b/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
@@ -2,8 +2,8 @@
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s -check-prefixes=CHECK
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s -check-prefixes=CHECK-WIN64
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s -check-prefixes=CHECK-I686
-// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple powerpc-unknown-unknown -fclang-abi-compat=22 -o - | FileCheck %s -check-prefixes=CHECK-PPC-CLANG22
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple powerpc-unknown-unknown -fclang-abi-compat=23 -o - | FileCheck %s -check-prefixes=CHECK-PPC-CLANG23
+// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s -check-prefixes=CHECK-PPC
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s -check-prefixes=CHECK-ARM
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s -check-prefixes=CHECK-ARM-HF
// RUN: %clang_cc1 %s -O3 -fmath-errno -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s -check-prefixes=CHECK-THUMB
@@ -29,13 +29,13 @@ long double powl(long double a, long double b);
// CHECK-I686-SAME: x86_fp80 noundef [[A:%.*]], x86_fp80 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-I686: [[CALL:%.*]] = tail call x86_fp80 @powl(x86_fp80 noundef [[A]], x86_fp80 noundef [[B]]) #[[ATTR5:[0-9]+]]
//
-// CHECK-PPC-CLANG22-LABEL: define dso_local ppc_fp128 @test_powl(
-// CHECK-PPC-CLANG22-SAME: ppc_fp128 noundef [[A:%.*]], ppc_fp128 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-PPC-CLANG22: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR4:[0-9]+]]
-//
// CHECK-PPC-CLANG23-LABEL: define dso_local ppc_fp128 @test_powl(
// CHECK-PPC-CLANG23-SAME: ppc_fp128 noundef [[A:%.*]], ppc_fp128 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR3:[0-9]+]]
+// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR4:[0-9]+]]
+//
+// CHECK-PPC-LABEL: define dso_local ppc_fp128 @test_powl(
+// CHECK-PPC-SAME: ppc_fp128 noundef [[A:%.*]], ppc_fp128 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-PPC: [[CALL:%.*]] = tail call ppc_fp128 @powl(ppc_fp128 noundef [[A]], ppc_fp128 noundef [[B]]) #[[ATTR3:[0-9]+]]
//
// CHECK-ARM-LABEL: define dso_local double @test_powl(
// CHECK-ARM-SAME: double noundef [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
@@ -97,19 +97,19 @@ long double test_powl(long double a, long double b) {
// CHECK-I686: store x86_fp80 [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 4
// CHECK-I686: store x86_fp80 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 4
//
-// CHECK-PPC-CLANG22-LABEL: define dso_local void @test_cargl(
-// CHECK-PPC-CLANG22-SAME: ptr dead_on_unwind noalias nofree writable writeonly sret({ ppc_fp128, ppc_fp128 }) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr nofree noundef readonly byval({ ppc_fp128, ppc_fp128 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
-// CHECK-PPC-CLANG22: [[CLD_REAL:%.*]] = load ppc_fp128, ptr [[CLD]], align 16
-// CHECK-PPC-CLANG22: [[CLD_IMAG:%.*]] = load ppc_fp128, ptr [[CLD_IMAGP:%.*]], align 16
-// CHECK-PPC-CLANG22: store ppc_fp128 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16
-// CHECK-PPC-CLANG22: store ppc_fp128 [[CLD_IMAG]], ptr [[BYVAL_TEMP_IMAGP:%.*]], align 16
-// CHECK-PPC-CLANG22: [[CALL:%.*]] = tail call ppc_fp128 @cargl(ptr noundef nonnull byval({ ppc_fp128, ppc_fp128 }) align 16 [[BYVAL_TEMP]]) #[[ATTR4]]
-// CHECK-PPC-CLANG22: store ppc_fp128 [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 16
-// CHECK-PPC-CLANG22: store ppc_fp128 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 16
+// CHECK-PPC-CLANG23-LABEL: define dso_local void @test_cargl(
+// CHECK-PPC-CLANG23-SAME: ptr dead_on_unwind noalias nofree writable writeonly sret({ ppc_fp128, ppc_fp128 }) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr nofree noundef readonly byval({ ppc_fp128, ppc_fp128 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// CHECK-PPC-CLANG23: [[CLD_REAL:%.*]] = load ppc_fp128, ptr [[CLD]], align 16
+// CHECK-PPC-CLANG23: [[CLD_IMAG:%.*]] = load ppc_fp128, ptr [[CLD_IMAGP:%.*]], align 16
+// CHECK-PPC-CLANG23: store ppc_fp128 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16
+// CHECK-PPC-CLANG23: store ppc_fp128 [[CLD_IMAG]], ptr [[BYVAL_TEMP_IMAGP:%.*]], align 16
+// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call ppc_fp128 @cargl(ptr noundef nonnull byval({ ppc_fp128, ppc_fp128 }) align 16 [[BYVAL_TEMP]]) #[[ATTR4]]
+// CHECK-PPC-CLANG23: store ppc_fp128 [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 16
+// CHECK-PPC-CLANG23: store ppc_fp128 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 16
//
-// CHECK-PPC-CLANG23-LABEL: define dso_local [2 x i128] @test_cargl(
-// CHECK-PPC-CLANG23-SAME: [2 x i128] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
-// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call ppc_fp128 @cargl([2 x i128] noundef [[CLD_COERCE]]) #[[ATTR3]]
+// CHECK-PPC-LABEL: define dso_local [8 x i32] @test_cargl(
+// CHECK-PPC-SAME: [8 x i32] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// CHECK-PPC: [[CALL:%.*]] = tail call ppc_fp128 @cargl([8 x i32] noundef [[CLD_COERCE]]) #[[ATTR3]]
//
// CHECK-ARM-LABEL: define dso_local void @test_cargl(
// CHECK-ARM-SAME: ptr dead_on_unwind noalias nofree writable writeonly sret({ double, double }) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], [2 x i64] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
@@ -173,13 +173,13 @@ int ilogbl(long double a);
// CHECK-I686-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-I686: [[CALL:%.*]] = tail call i32 @ilogbl(x86_fp80 noundef [[A]]) #[[ATTR5]]
//
-// CHECK-PPC-CLANG22-LABEL: define dso_local i32 @test_ilogb(
-// CHECK-PPC-CLANG22-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
-// CHECK-PPC-CLANG22: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR4]]
-//
// CHECK-PPC-CLANG23-LABEL: define dso_local i32 @test_ilogb(
// CHECK-PPC-CLANG23-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
-// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR3]]
+// CHECK-PPC-CLANG23: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR4]]
+//
+// CHECK-PPC-LABEL: define dso_local i32 @test_ilogb(
+// CHECK-PPC-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-PPC: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR3]]
//
// CHECK-ARM-LABEL: define dso_local i32 @test_ilogb(
// CHECK-ARM-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
>From f11d5a848d181a385f5e87789ba8162dd3b74f41 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Mon, 21 Sep 2026 16:04:05 +0200
Subject: [PATCH 12/12] add ppc32 complex abi test
this locks in the behavior for all types, and also the 'soaking up' behavior when a complex value does not fit in the remaining GPRs
---
.../test/CodeGen/PowerPC/ppc32-complex-abi.c | 378 ++++++++++++++++++
1 file changed, 378 insertions(+)
create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-abi.c
diff --git a/clang/test/CodeGen/PowerPC/ppc32-complex-abi.c b/clang/test/CodeGen/PowerPC/ppc32-complex-abi.c
new file mode 100644
index 00000000000000..d75ac3f186edf8
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/ppc32-complex-abi.c
@@ -0,0 +1,378 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=PPC32
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fclang-abi-compat=23 \
+// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=COMPAT23
+
+// Test how 32-bit PowerPC passes and returns `_Complex` values.
+
+// A `_Complex` value is passed and returned packed into whole GPRs, and is never
+// split between the GPRs and the stack. Clang 23 and before instead passed it
+// byval and returned it indirectly. The new behavior matches GCC.
+
+// PPC32-LABEL: define dso_local i16 @complex_char(
+// PPC32-SAME: i16 noundef [[C_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { i8, i8 }, align 1
+// PPC32-NEXT: [[C:%.*]] = alloca { i8, i8 }, align 1
+// PPC32-NEXT: store i16 [[C_COERCE]], ptr [[C]], align 1
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load i8, ptr [[C_REALP]], align 1
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load i8, ptr [[C_IMAGP]], align 1
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store i8 [[C_REAL]], ptr [[RETVAL_REALP]], align 1
+// PPC32-NEXT: store i8 [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 1
+// PPC32-NEXT: [[TMP0:%.*]] = load i16, ptr [[RETVAL]], align 1
+// PPC32-NEXT: ret i16 [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_char(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ i8, i8 }) align 1 [[AGG_RESULT:%.*]], ptr noundef byval({ i8, i8 }) align 1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load i8, ptr [[C_REALP]], align 1
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load i8, ptr [[C_IMAGP]], align 1
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i8 [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 1
+// COMPAT23-NEXT: store i8 [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 1
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load i8, ptr [[AGG_RESULT_REALP1]], align 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load i8, ptr [[AGG_RESULT_IMAGP2]], align 1
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i8 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 1
+// COMPAT23-NEXT: store i8 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 1
+// COMPAT23-NEXT: ret void
+//
+_Complex char complex_char(_Complex char c) { return c; }
+
+// PPC32-LABEL: define dso_local i32 @complex_short(
+// PPC32-SAME: i32 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { i16, i16 }, align 2
+// PPC32-NEXT: [[C:%.*]] = alloca { i16, i16 }, align 2
+// PPC32-NEXT: store i32 [[C_COERCE]], ptr [[C]], align 2
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load i16, ptr [[C_REALP]], align 2
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load i16, ptr [[C_IMAGP]], align 2
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store i16 [[C_REAL]], ptr [[RETVAL_REALP]], align 2
+// PPC32-NEXT: store i16 [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 2
+// PPC32-NEXT: [[TMP0:%.*]] = load i32, ptr [[RETVAL]], align 2
+// PPC32-NEXT: ret i32 [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_short(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ i16, i16 }) align 2 [[AGG_RESULT:%.*]], ptr noundef byval({ i16, i16 }) align 2 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load i16, ptr [[C_REALP]], align 2
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load i16, ptr [[C_IMAGP]], align 2
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i16 [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 2
+// COMPAT23-NEXT: store i16 [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 2
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load i16, ptr [[AGG_RESULT_REALP1]], align 2
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load i16, ptr [[AGG_RESULT_IMAGP2]], align 2
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i16 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 2
+// COMPAT23-NEXT: store i16 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 2
+// COMPAT23-NEXT: ret void
+//
+_Complex short complex_short(_Complex short c) { return c; }
+
+// PPC32-LABEL: define dso_local <2 x i32> @complex_int(
+// PPC32-SAME: <2 x i32> noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { i32, i32 }, align 4
+// PPC32-NEXT: [[C:%.*]] = alloca { i32, i32 }, align 4
+// PPC32-NEXT: store <2 x i32> [[C_COERCE]], ptr [[C]], align 4
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load i32, ptr [[C_REALP]], align 4
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load i32, ptr [[C_IMAGP]], align 4
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store i32 [[C_REAL]], ptr [[RETVAL_REALP]], align 4
+// PPC32-NEXT: store i32 [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// PPC32-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// PPC32-NEXT: ret <2 x i32> [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_int(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ i32, i32 }) align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ i32, i32 }) align 4 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load i32, ptr [[C_REALP]], align 4
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load i32, ptr [[C_IMAGP]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i32 [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 4
+// COMPAT23-NEXT: store i32 [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load i32, ptr [[AGG_RESULT_REALP1]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load i32, ptr [[AGG_RESULT_IMAGP2]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i32 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// COMPAT23-NEXT: store i32 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// COMPAT23-NEXT: ret void
+//
+_Complex int complex_int(_Complex int c) { return c; }
+
+// PPC32-LABEL: define dso_local <2 x i32> @complex_long(
+// PPC32-SAME: <2 x i32> noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { i32, i32 }, align 4
+// PPC32-NEXT: [[C:%.*]] = alloca { i32, i32 }, align 4
+// PPC32-NEXT: store <2 x i32> [[C_COERCE]], ptr [[C]], align 4
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load i32, ptr [[C_REALP]], align 4
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load i32, ptr [[C_IMAGP]], align 4
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store i32 [[C_REAL]], ptr [[RETVAL_REALP]], align 4
+// PPC32-NEXT: store i32 [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// PPC32-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// PPC32-NEXT: ret <2 x i32> [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_long(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ i32, i32 }) align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ i32, i32 }) align 4 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load i32, ptr [[C_REALP]], align 4
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load i32, ptr [[C_IMAGP]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i32 [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 4
+// COMPAT23-NEXT: store i32 [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load i32, ptr [[AGG_RESULT_REALP1]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load i32, ptr [[AGG_RESULT_IMAGP2]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i32 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// COMPAT23-NEXT: store i32 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// COMPAT23-NEXT: ret void
+//
+_Complex long complex_long(_Complex long c) { return c; }
+
+// PPC32-LABEL: define dso_local [4 x i32] @complex_long_long(
+// PPC32-SAME: [4 x i32] noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { i64, i64 }, align 8
+// PPC32-NEXT: [[C:%.*]] = alloca { i64, i64 }, align 8
+// PPC32-NEXT: store [4 x i32] [[C_COERCE]], ptr [[C]], align 8
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load i64, ptr [[C_REALP]], align 8
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load i64, ptr [[C_IMAGP]], align 8
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store i64 [[C_REAL]], ptr [[RETVAL_REALP]], align 8
+// PPC32-NEXT: store i64 [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 8
+// PPC32-NEXT: [[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// PPC32-NEXT: ret [4 x i32] [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_long_long(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ i64, i64 }) align 8 [[AGG_RESULT:%.*]], ptr noundef byval({ i64, i64 }) align 8 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load i64, ptr [[C_REALP]], align 8
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load i64, ptr [[C_IMAGP]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i64 [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 8
+// COMPAT23-NEXT: store i64 [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load i64, ptr [[AGG_RESULT_REALP1]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load i64, ptr [[AGG_RESULT_IMAGP2]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store i64 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// COMPAT23-NEXT: store i64 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// COMPAT23-NEXT: ret void
+//
+_Complex long long complex_long_long(_Complex long long c) { return c; }
+
+// PPC32-LABEL: define dso_local <2 x i32> @complex_float(
+// PPC32-SAME: <2 x i32> noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// PPC32-NEXT: [[C:%.*]] = alloca { float, float }, align 4
+// PPC32-NEXT: store <2 x i32> [[C_COERCE]], ptr [[C]], align 4
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store float [[C_REAL]], ptr [[RETVAL_REALP]], align 4
+// PPC32-NEXT: store float [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// PPC32-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[RETVAL]], align 4
+// PPC32-NEXT: ret <2 x i32> [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_float(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ float, float }) align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ float, float }) align 4 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store float [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 4
+// COMPAT23-NEXT: store float [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4
+// COMPAT23-NEXT: store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4
+// COMPAT23-NEXT: ret void
+//
+_Complex float complex_float(_Complex float c) { return c; }
+
+// PPC32-LABEL: define dso_local [4 x i32] @complex_double(
+// PPC32-SAME: [4 x i32] noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// PPC32-NEXT: [[C:%.*]] = alloca { double, double }, align 8
+// PPC32-NEXT: store [4 x i32] [[C_COERCE]], ptr [[C]], align 8
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load double, ptr [[C_REALP]], align 8
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load double, ptr [[C_IMAGP]], align 8
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store double [[C_REAL]], ptr [[RETVAL_REALP]], align 8
+// PPC32-NEXT: store double [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 8
+// PPC32-NEXT: [[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 8
+// PPC32-NEXT: ret [4 x i32] [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_double(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef byval({ double, double }) align 8 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load double, ptr [[C_REALP]], align 8
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load double, ptr [[C_IMAGP]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store double [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 8
+// COMPAT23-NEXT: store double [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// COMPAT23-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// COMPAT23-NEXT: ret void
+//
+_Complex double complex_double(_Complex double c) { return c; }
+
+// PPC32-LABEL: define dso_local [8 x i32] @complex_long_double(
+// PPC32-SAME: [8 x i32] noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// PPC32-NEXT: [[C:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// PPC32-NEXT: store [8 x i32] [[C_COERCE]], ptr [[C]], align 16
+// PPC32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[C]], i32 0, i32 0
+// PPC32-NEXT: [[C_REAL:%.*]] = load ppc_fp128, ptr [[C_REALP]], align 16
+// PPC32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[C]], i32 0, i32 1
+// PPC32-NEXT: [[C_IMAG:%.*]] = load ppc_fp128, ptr [[C_IMAGP]], align 16
+// PPC32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// PPC32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// PPC32-NEXT: store ppc_fp128 [[C_REAL]], ptr [[RETVAL_REALP]], align 16
+// PPC32-NEXT: store ppc_fp128 [[C_IMAG]], ptr [[RETVAL_IMAGP]], align 16
+// PPC32-NEXT: [[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 16
+// PPC32-NEXT: ret [8 x i32] [[TMP0]]
+//
+// COMPAT23-LABEL: define dso_local void @complex_long_double(
+// COMPAT23-SAME: ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 [[AGG_RESULT:%.*]], ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 [[C:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[C]], i32 0, i32 0
+// COMPAT23-NEXT: [[C_REAL:%.*]] = load ppc_fp128, ptr [[C_REALP]], align 16
+// COMPAT23-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[C]], i32 0, i32 1
+// COMPAT23-NEXT: [[C_IMAG:%.*]] = load ppc_fp128, ptr [[C_IMAGP]], align 16
+// COMPAT23-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store ppc_fp128 [[C_REAL]], ptr [[AGG_RESULT_REALP]], align 16
+// COMPAT23-NEXT: store ppc_fp128 [[C_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 16
+// COMPAT23-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_REAL:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_REALP1]], align 16
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: [[AGG_RESULT_IMAG:%.*]] = load ppc_fp128, ptr [[AGG_RESULT_IMAGP2]], align 16
+// COMPAT23-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 0
+// COMPAT23-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr [[AGG_RESULT]], i32 0, i32 1
+// COMPAT23-NEXT: store ppc_fp128 [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 16
+// COMPAT23-NEXT: store ppc_fp128 [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 16
+// COMPAT23-NEXT: ret void
+//
+_Complex long double complex_long_double(_Complex long double c) { return c; }
+
+// A `_Complex` value that does not fit in remaining GPRs is passed entirely on
+// the stack rather than being split. The leftover GPRs are soaked up by a padding
+// argument, so `g` must be passed via the stack as well.
+
+// PPC32-LABEL: define dso_local void @split(
+// PPC32-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], [2 x i32] [[TMP0:%.*]], [4 x i32] noundef [[Z_COERCE:%.*]], i32 noundef [[G:%.*]]) #[[ATTR0]] {
+// PPC32-NEXT: [[ENTRY:.*:]]
+// PPC32-NEXT: [[Z:%.*]] = alloca { double, double }, align 8
+// PPC32-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: [[D_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: [[F_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: [[G_ADDR:%.*]] = alloca i32, align 4
+// PPC32-NEXT: store [4 x i32] [[Z_COERCE]], ptr [[Z]], align 8
+// PPC32-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
+// PPC32-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
+// PPC32-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4
+// PPC32-NEXT: store i32 [[D]], ptr [[D_ADDR]], align 4
+// PPC32-NEXT: store i32 [[E]], ptr [[E_ADDR]], align 4
+// PPC32-NEXT: store i32 [[F]], ptr [[F_ADDR]], align 4
+// PPC32-NEXT: store i32 [[G]], ptr [[G_ADDR]], align 4
+// PPC32-NEXT: ret void
+//
+// COMPAT23-LABEL: define dso_local void @split(
+// COMPAT23-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], ptr noundef byval({ double, double }) align 8 [[Z:%.*]], i32 noundef [[G:%.*]]) #[[ATTR0]] {
+// COMPAT23-NEXT: [[ENTRY:.*:]]
+// COMPAT23-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: [[D_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: [[E_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: [[F_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: [[G_ADDR:%.*]] = alloca i32, align 4
+// COMPAT23-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
+// COMPAT23-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
+// COMPAT23-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4
+// COMPAT23-NEXT: store i32 [[D]], ptr [[D_ADDR]], align 4
+// COMPAT23-NEXT: store i32 [[E]], ptr [[E_ADDR]], align 4
+// COMPAT23-NEXT: store i32 [[F]], ptr [[F_ADDR]], align 4
+// COMPAT23-NEXT: store i32 [[G]], ptr [[G_ADDR]], align 4
+// COMPAT23-NEXT: ret void
+//
+void split(int a, int b, int c, int d, int e, int f, _Complex double z, int g) {}
More information about the cfe-commits
mailing list