[clang] 7f5d91d - [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 19 08:01:11 PDT 2020
Author: jasonliu
Date: 2020-05-19T15:00:48Z
New Revision: 7f5d91d3ffedf89823f36a5eba5ec586bc885545
URL: https://github.com/llvm/llvm-project/commit/7f5d91d3ffedf89823f36a5eba5ec586bc885545
DIFF: https://github.com/llvm/llvm-project/commit/7f5d91d3ffedf89823f36a5eba5ec586bc885545.diff
LOG: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX
Summary:
Created AIXABIInfo and AIXTargetCodeGenInfo for AIX ABI.
Reviewed By: Xiangling_L, ZarkoCA
Differential Revision: https://reviews.llvm.org/D79035
Added:
clang/test/CodeGen/aix-complex.c
clang/test/CodeGen/aix-return.c
clang/test/CodeGen/aix-struct-arg.c
clang/test/CodeGen/aix-vaargs.c
clang/test/CodeGen/aix-vector.c
clang/test/CodeGen/ppc32-and-aix-struct-return.c
clang/test/CodeGen/ppc32-dwarf.c
clang/test/Frontend/aix-unsupported.c
Modified:
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/CodeGen/ppc64-dwarf.c
Removed:
clang/test/CodeGen/ppc32-struct-return.c
################################################################################
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index a4ca0b07da9e..e1fe1330695c 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -1544,11 +1544,11 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
: ABIArgInfo::getDirect());
}
-static bool isSSEVectorType(ASTContext &Context, QualType Ty) {
+static bool isSIMDVectorType(ASTContext &Context, QualType Ty) {
return Ty->getAs<VectorType>() && Context.getTypeSize(Ty) == 128;
}
-static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) {
+static bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) {
const RecordType *RT = Ty->getAs<RecordType>();
if (!RT)
return 0;
@@ -1557,16 +1557,16 @@ static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) {
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
for (const auto &I : CXXRD->bases())
- if (!isRecordWithSSEVectorType(Context, I.getType()))
+ if (!isRecordWithSIMDVectorType(Context, I.getType()))
return false;
for (const auto *i : RD->fields()) {
QualType FT = i->getType();
- if (isSSEVectorType(Context, FT))
+ if (isSIMDVectorType(Context, FT))
return true;
- if (isRecordWithSSEVectorType(Context, FT))
+ if (isRecordWithSIMDVectorType(Context, FT))
return true;
}
@@ -1587,8 +1587,8 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty,
}
// Otherwise, if the type contains an SSE vector type, the alignment is 16.
- if (Align >= 16 && (isSSEVectorType(getContext(), Ty) ||
- isRecordWithSSEVectorType(getContext(), Ty)))
+ if (Align >= 16 && (isSIMDVectorType(getContext(), Ty) ||
+ isRecordWithSIMDVectorType(getContext(), Ty)))
return 16;
return MinABIStackAlignInBytes;
@@ -4247,6 +4247,224 @@ Address WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
/*allowHigherAlign*/ false);
}
+static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *Address, bool Is64Bit,
+ bool IsAIX) {
+ // This is calculated from the LLVM and GCC tables and verified
+ // against gcc output. AFAIK all PPC ABIs use the same encoding.
+
+ CodeGen::CGBuilderTy &Builder = CGF.Builder;
+
+ llvm::IntegerType *i8 = CGF.Int8Ty;
+ llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+ llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
+ llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
+
+ // 0-31: r0-31, the 4-byte or 8-byte general-purpose registers
+ AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 0, 31);
+
+ // 32-63: fp0-31, the 8-byte floating-point registers
+ AssignToArrayRange(Builder, Address, Eight8, 32, 63);
+
+ // 64-67 are various 4-byte or 8-byte special-purpose registers:
+ // 64: mq
+ // 65: lr
+ // 66: ctr
+ // 67: ap
+ AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 64, 67);
+
+ // 68-76 are various 4-byte special-purpose registers:
+ // 68-75 cr0-7
+ // 76: xer
+ AssignToArrayRange(Builder, Address, Four8, 68, 76);
+
+ // 77-108: v0-31, the 16-byte vector registers
+ AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
+
+ // 109: vrsave
+ // 110: vscr
+ AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 109, 110);
+
+ // AIX does not utilize the rest of the registers.
+ if (IsAIX)
+ return false;
+
+ // 111: spe_acc
+ // 112: spefscr
+ // 113: sfp
+ AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 111, 113);
+
+ if (!Is64Bit)
+ return false;
+
+ // TODO: Need to verify if these registers are used on 64 bit AIX with Power8
+ // or above CPU.
+ // 64-bit only registers:
+ // 114: tfhar
+ // 115: tfiar
+ // 116: texasr
+ AssignToArrayRange(Builder, Address, Eight8, 114, 116);
+
+ return false;
+}
+
+// AIX
+namespace {
+/// AIXABIInfo - The AIX XCOFF ABI information.
+class AIXABIInfo : public ABIInfo {
+ const bool Is64Bit;
+ const unsigned PtrByteSize;
+ CharUnits getParamTypeAlignment(QualType Ty) const;
+
+public:
+ AIXABIInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit)
+ : ABIInfo(CGT), Is64Bit(Is64Bit), PtrByteSize(Is64Bit ? 8 : 4) {}
+
+ bool isPromotableTypeForABI(QualType Ty) const;
+
+ ABIArgInfo classifyReturnType(QualType RetTy) const;
+ ABIArgInfo classifyArgumentType(QualType Ty) const;
+
+ void computeInfo(CGFunctionInfo &FI) const override {
+ if (!getCXXABI().classifyReturnType(FI))
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+ for (auto &I : FI.arguments())
+ I.info = classifyArgumentType(I.type);
+ }
+
+ Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+ QualType Ty) const override;
+};
+
+class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
+ const bool Is64Bit;
+
+public:
+ AIXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit)
+ : TargetCodeGenInfo(std::make_unique<AIXABIInfo>(CGT, Is64Bit)),
+ Is64Bit(Is64Bit) {}
+ int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
+ return 1; // r1 is the dedicated stack pointer
+ }
+
+ bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *Address) const override;
+};
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 32/64 bits.
+bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const {
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ Ty = EnumTy->getDecl()->getIntegerType();
+
+ // Promotable integer types are required to be promoted by the ABI.
+ if (Ty->isPromotableIntegerType())
+ return true;
+
+ if (!Is64Bit)
+ return false;
+
+ // For 64 bit mode, in addition to the usual promotable integer types, we also
+ // need to extend all 32-bit types, since the ABI requires promotion to 64
+ // bits.
+ if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+ switch (BT->getKind()) {
+ case BuiltinType::Int:
+ case BuiltinType::UInt:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const {
+ if (RetTy->isAnyComplexType())
+ llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+ if (RetTy->isVectorType())
+ llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+ if (RetTy->isVoidType())
+ return ABIArgInfo::getIgnore();
+
+ // TODO: Evaluate if AIX power alignment rule would have an impact on the
+ // alignment here.
+ if (isAggregateTypeForABI(RetTy))
+ return getNaturalAlignIndirect(RetTy);
+
+ return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect());
+}
+
+ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const {
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
+ if (Ty->isAnyComplexType())
+ llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+ if (Ty->isVectorType())
+ llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+ // TODO: Evaluate if AIX power alignment rule would have an impact on the
+ // alignment here.
+ 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, RAA == CGCXXABI::RAA_DirectInMemory);
+
+ CharUnits CCAlign = getParamTypeAlignment(Ty);
+ CharUnits TyAlign = getContext().getTypeAlignInChars(Ty);
+
+ return ABIArgInfo::getIndirect(CCAlign, /*ByVal*/ true,
+ /*Realign*/ TyAlign > CCAlign);
+ }
+
+ return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
+}
+
+CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const {
+ if (Ty->isAnyComplexType())
+ llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+ if (Ty->isVectorType())
+ llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+ // If the structure contains a vector type, the alignment is 16.
+ if (isRecordWithSIMDVectorType(getContext(), Ty))
+ return CharUnits::fromQuantity(16);
+
+ return CharUnits::fromQuantity(PtrByteSize);
+}
+
+Address AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+ QualType Ty) const {
+ if (Ty->isAnyComplexType())
+ llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+ if (Ty->isVectorType())
+ llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+ auto TypeInfo = getContext().getTypeInfoInChars(Ty);
+ TypeInfo.second = getParamTypeAlignment(Ty);
+
+ CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize);
+
+ return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
+ SlotSize, /*AllowHigher*/ true);
+}
+
+bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable(
+ CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const {
+ return PPC_initDwarfEHRegSizeTable(CGF, Address, Is64Bit, /*IsAIX*/ true);
+}
+
// PowerPC-32
namespace {
/// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
@@ -4524,42 +4742,8 @@ bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
bool
PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const {
- // This is calculated from the LLVM and GCC tables and verified
- // against gcc output. AFAIK all ABIs use the same encoding.
-
- CodeGen::CGBuilderTy &Builder = CGF.Builder;
-
- llvm::IntegerType *i8 = CGF.Int8Ty;
- llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
- llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
- llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
-
- // 0-31: r0-31, the 4-byte general-purpose registers
- AssignToArrayRange(Builder, Address, Four8, 0, 31);
-
- // 32-63: fp0-31, the 8-byte floating-point registers
- AssignToArrayRange(Builder, Address, Eight8, 32, 63);
-
- // 64-76 are various 4-byte special-purpose registers:
- // 64: mq
- // 65: lr
- // 66: ctr
- // 67: ap
- // 68-75 cr0-7
- // 76: xer
- AssignToArrayRange(Builder, Address, Four8, 64, 76);
-
- // 77-108: v0-31, the 16-byte vector registers
- AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
-
- // 109: vrsave
- // 110: vscr
- // 111: spe_acc
- // 112: spefscr
- // 113: sfp
- AssignToArrayRange(Builder, Address, Four8, 109, 113);
-
- return false;
+ return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ false,
+ /*IsAIX*/ false);
}
// PowerPC-64
@@ -5106,66 +5290,19 @@ Address PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
TypeInfo, SlotSize, /*AllowHigher*/ true);
}
-static bool
-PPC64_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
- llvm::Value *Address) {
- // This is calculated from the LLVM and GCC tables and verified
- // against gcc output. AFAIK all ABIs use the same encoding.
-
- CodeGen::CGBuilderTy &Builder = CGF.Builder;
-
- llvm::IntegerType *i8 = CGF.Int8Ty;
- llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
- llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
- llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
-
- // 0-31: r0-31, the 8-byte general-purpose registers
- AssignToArrayRange(Builder, Address, Eight8, 0, 31);
-
- // 32-63: fp0-31, the 8-byte floating-point registers
- AssignToArrayRange(Builder, Address, Eight8, 32, 63);
-
- // 64-67 are various 8-byte special-purpose registers:
- // 64: mq
- // 65: lr
- // 66: ctr
- // 67: ap
- AssignToArrayRange(Builder, Address, Eight8, 64, 67);
-
- // 68-76 are various 4-byte special-purpose registers:
- // 68-75 cr0-7
- // 76: xer
- AssignToArrayRange(Builder, Address, Four8, 68, 76);
-
- // 77-108: v0-31, the 16-byte vector registers
- AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
-
- // 109: vrsave
- // 110: vscr
- // 111: spe_acc
- // 112: spefscr
- // 113: sfp
- // 114: tfhar
- // 115: tfiar
- // 116: texasr
- AssignToArrayRange(Builder, Address, Eight8, 109, 116);
-
- return false;
-}
-
bool
PPC64_SVR4_TargetCodeGenInfo::initDwarfEHRegSizeTable(
CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const {
-
- return PPC64_initDwarfEHRegSizeTable(CGF, Address);
+ return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true,
+ /*IsAIX*/ false);
}
bool
PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const {
-
- return PPC64_initDwarfEHRegSizeTable(CGF, Address);
+ return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true,
+ /*IsAIX*/ false);
}
//===----------------------------------------------------------------------===//
@@ -10492,6 +10629,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
}
case llvm::Triple::ppc: {
+ if (Triple.isOSAIX())
+ return SetCGInfo(new AIXTargetCodeGenInfo(Types, /*Is64Bit*/ false));
+
bool IsSoftFloat =
CodeGenOpts.FloatABI == "soft" || getTarget().hasFeature("spe");
bool RetSmallStructInRegABI =
@@ -10500,6 +10640,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
new PPC32TargetCodeGenInfo(Types, IsSoftFloat, RetSmallStructInRegABI));
}
case llvm::Triple::ppc64:
+ if (Triple.isOSAIX())
+ return SetCGInfo(new AIXTargetCodeGenInfo(Types, /*Is64Bit*/ true));
+
if (Triple.isOSBinFormatELF()) {
PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
if (getTarget().getABI() == "elfv2")
@@ -10509,8 +10652,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
return SetCGInfo(new PPC64_SVR4_TargetCodeGenInfo(Types, Kind, HasQPX,
IsSoftFloat));
- } else
- return SetCGInfo(new PPC64TargetCodeGenInfo(Types));
+ }
+ return SetCGInfo(new PPC64TargetCodeGenInfo(Types));
case llvm::Triple::ppc64le: {
assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!");
PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv2;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index a30cb2add048..94ba0dd8e598 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1298,6 +1298,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
if (Arg *A =
Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
OPT_maix_struct_return, OPT_msvr4_struct_return)) {
+ // TODO: We might want to consider enabling these options on AIX in the
+ // future.
+ if (T.isOSAIX())
+ Diags.Report(diag::err_drv_unsupported_opt_for_target)
+ << A->getSpelling() << T.str();
+
const Option &O = A->getOption();
if (O.matches(OPT_fpcc_struct_return) ||
O.matches(OPT_maix_struct_return)) {
diff --git a/clang/test/CodeGen/aix-complex.c b/clang/test/CodeGen/aix-complex.c
new file mode 100644
index 000000000000..62ab481a9156
--- /dev/null
+++ b/clang/test/CodeGen/aix-complex.c
@@ -0,0 +1,10 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc-unknown-aix \
+// RUN: -emit-llvm -o - %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN: -emit-llvm -o - %s 2>&1 | FileCheck %s
+
+// CHECK: fatal error: error in backend: complex type is not supported on AIX yet
+_Complex float foo_float(_Complex float x) {
+ return x;
+}
diff --git a/clang/test/CodeGen/aix-return.c b/clang/test/CodeGen/aix-return.c
new file mode 100644
index 000000000000..87a2b85d4e94
--- /dev/null
+++ b/clang/test/CodeGen/aix-return.c
@@ -0,0 +1,34 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefixes=AIX,AIX32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefixes=AIX,AIX64
+
+// AIX-LABEL: define void @retVoid()
+void retVoid(void) {}
+
+// AIX-LABEL: define signext i8 @retChar(i8 signext %x)
+char retChar(char x) { return x; }
+
+// AIX-LABEL: define signext i16 @retShort(i16 signext %x)
+short retShort(short x) { return x; }
+
+// AIX32-LABEL: define i32 @retInt(i32 %x)
+// AIX64-LABEL: define signext i32 @retInt(i32 signext %x)
+int retInt(int x) { return 1; }
+
+// AIX-LABEL: define i64 @retLongLong(i64 %x)
+long long retLongLong(long long x) { return x; }
+
+// AIX-LABEL: define signext i8 @retEnumChar(i8 signext %x)
+enum EnumChar : char { IsChar };
+enum EnumChar retEnumChar(enum EnumChar x) {
+ return x;
+}
+
+// AIX32-LABEL: define i32 @retEnumInt(i32 %x)
+// AIX64-LABEL: define signext i32 @retEnumInt(i32 signext %x)
+enum EnumInt : int { IsInt };
+enum EnumInt retEnumInt(enum EnumInt x) {
+ return x;
+}
diff --git a/clang/test/CodeGen/aix-struct-arg.c b/clang/test/CodeGen/aix-struct-arg.c
new file mode 100644
index 000000000000..9524bef9eaa1
--- /dev/null
+++ b/clang/test/CodeGen/aix-struct-arg.c
@@ -0,0 +1,89 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -target-feature +altivec \
+// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=AIX32 %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-feature +altivec \
+// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=AIX64 %s
+
+typedef struct {
+} Zero;
+typedef struct {
+ char c;
+} One;
+typedef struct {
+ short s;
+} Two;
+typedef struct {
+ char c[3];
+} Three;
+typedef struct {
+ float f;
+} Four;
+typedef struct {
+ char c[5];
+} Five;
+typedef struct {
+ short s[3];
+} Six;
+typedef struct {
+ char c[7];
+} Seven;
+typedef struct {
+ long long l;
+} Eight;
+typedef struct {
+ int i;
+} __attribute__((aligned(32))) OverAligned;
+typedef struct {
+ int i;
+ vector signed int vsi;
+} StructVector;
+
+// AIX32-LABEL: define void @arg0(%struct.Zero* byval(%struct.Zero) align 4 %x)
+// AIX64-LABEL: define void @arg0(%struct.Zero* byval(%struct.Zero) align 8 %x)
+void arg0(Zero x) {}
+
+// AIX32-LABEL: define void @arg1(%struct.One* byval(%struct.One) align 4 %x)
+// AIX64-LABEL: define void @arg1(%struct.One* byval(%struct.One) align 8 %x)
+void arg1(One x) {}
+
+// AIX32-LABEL: define void @arg2(%struct.Two* byval(%struct.Two) align 4 %x)
+// AIX64-LABEL: define void @arg2(%struct.Two* byval(%struct.Two) align 8 %x)
+void arg2(Two x) {}
+
+// AIX32-LABEL: define void @arg3(%struct.Three* byval(%struct.Three) align 4 %x)
+// AIX64-LABEL: define void @arg3(%struct.Three* byval(%struct.Three) align 8 %x)
+void arg3(Three x) {}
+
+// AIX32-LABEL: define void @arg4(%struct.Four* byval(%struct.Four) align 4 %x)
+// AIX64-LABEL: define void @arg4(%struct.Four* byval(%struct.Four) align 8 %x)
+void arg4(Four x) {}
+
+// AIX32-LABEL: define void @arg5(%struct.Five* byval(%struct.Five) align 4 %x)
+// AIX64-LABEL: define void @arg5(%struct.Five* byval(%struct.Five) align 8 %x)
+void arg5(Five x) {}
+
+// AIX32-LABEL: define void @arg6(%struct.Six* byval(%struct.Six) align 4 %x)
+// AIX64-LABEL: define void @arg6(%struct.Six* byval(%struct.Six) align 8 %x)
+void arg6(Six x) {}
+
+// AIX32-LABEL: define void @arg7(%struct.Seven* byval(%struct.Seven) align 4 %x)
+// AIX64-LABEL: define void @arg7(%struct.Seven* byval(%struct.Seven) align 8 %x)
+void arg7(Seven x) {}
+
+// AIX32-LABEL: define void @arg8(%struct.Eight* byval(%struct.Eight) align 4 %0)
+// AIX32: %x = alloca %struct.Eight, align 8
+// AIX32: call void @llvm.memcpy.p0i8.p0i8.i32
+// AIX64-LABEL: define void @arg8(%struct.Eight* byval(%struct.Eight) align 8 %x)
+void arg8(Eight x) {}
+
+// AIX32-LABEL: define void @arg9(%struct.OverAligned* byval(%struct.OverAligned) align 4 %0)
+// AIX32: %x = alloca %struct.OverAligned, align 32
+// AIX32: call void @llvm.memcpy.p0i8.p0i8.i32
+// AIX64-LABEL: define void @arg9(%struct.OverAligned* byval(%struct.OverAligned) align 8 %0)
+// AIX64: %x = alloca %struct.OverAligned, align 32
+// AIX64: call void @llvm.memcpy.p0i8.p0i8.i64
+void arg9(OverAligned x) {}
+
+// AIX32-LABEL: define void @arg10(%struct.StructVector* byval(%struct.StructVector) align 16 %x)
+// AIX64-LABEL: define void @arg10(%struct.StructVector* byval(%struct.StructVector) align 16 %x)
+void arg10(StructVector x) {}
diff --git a/clang/test/CodeGen/aix-vaargs.c b/clang/test/CodeGen/aix-vaargs.c
new file mode 100644
index 000000000000..23e7a9d65e2c
--- /dev/null
+++ b/clang/test/CodeGen/aix-vaargs.c
@@ -0,0 +1,85 @@
+// REQUIRES: powerpc-registered-target
+// REQUIRES: asserts
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,AIX32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,AIX64
+
+struct x {
+ double b;
+ long a;
+};
+
+void testva (int n, ...) {
+ __builtin_va_list ap;
+ __builtin_va_start(ap, n);
+ struct x t = __builtin_va_arg(ap, struct x);
+ __builtin_va_list ap2;
+ __builtin_va_copy(ap2, ap);
+ int v = __builtin_va_arg(ap2, int);
+ __builtin_va_end(ap2);
+ __builtin_va_end(ap);
+}
+
+// AIX32: define void @testva(i32 %n, ...)
+// AIX64: define void @testva(i32 signext %n, ...)
+
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %n.addr = alloca i32, align 4
+
+// AIX32-NEXT: %ap = alloca i8*, align 4
+// AIX64-NEXT: %ap = alloca i8*, align 8
+
+// CHECK-NEXT: %t = alloca %struct.x, align 8
+
+// AIX32-NEXT: %ap2 = alloca i8*, align 4
+// AIX64-NEXT: %ap2 = alloca i8*, align 8
+
+// CHECK-NEXT: %v = alloca i32, align 4
+// CHECK-NEXT: store i32 %n, i32* %n.addr, align 4
+// CHECK-NEXT: %ap1 = bitcast i8** %ap to i8*
+// CHECK-NEXT: call void @llvm.va_start(i8* %ap1)
+
+// AIX32-NEXT: %argp.cur = load i8*, i8** %ap, align 4
+// AIX32-NEXT: %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 16
+// AIX32-NEXT: store i8* %argp.next, i8** %ap, align 4
+// AIX64-NEXT: %argp.cur = load i8*, i8** %ap, align 8
+// AIX64-NEXT: %argp.next = getelementptr inbounds i8, i8* %argp.cur, i64 16
+// AIX64-NEXT: store i8* %argp.next, i8** %ap, align 8
+
+// CHECK-NEXT: %0 = bitcast i8* %argp.cur to %struct.x*
+// CHECK-NEXT: %1 = bitcast %struct.x* %t to i8*
+// CHECK-NEXT: %2 = bitcast %struct.x* %0 to i8*
+
+// AIX32-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 4 %2, i32 16, i1 false)
+// AIX64-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %1, i8* align 8 %2, i64 16, i1 false)
+
+// CHECK-NEXT: %3 = bitcast i8** %ap2 to i8*
+// CHECK-NEXT: %4 = bitcast i8** %ap to i8*
+// CHECK-NEXT: call void @llvm.va_copy(i8* %3, i8* %4)
+
+// AIX32-NEXT: %argp.cur2 = load i8*, i8** %ap2, align 4
+// AIX32-NEXT: %argp.next3 = getelementptr inbounds i8, i8* %argp.cur2, i32 4
+// AIX32-NEXT: store i8* %argp.next3, i8** %ap2, align 4
+// AIX32-NEXT: %5 = bitcast i8* %argp.cur2 to i32*
+// AIX32-NEXT: %6 = load i32, i32* %5, align 4
+// AIX32-NEXT: store i32 %6, i32* %v, align 4
+// AIX64-NEXT: %argp.cur2 = load i8*, i8** %ap2, align 8
+// AIX64-NEXT: %argp.next3 = getelementptr inbounds i8, i8* %argp.cur2, i64 8
+// AIX64-NEXT: store i8* %argp.next3, i8** %ap2, align 8
+// AIX64-NEXT: %5 = getelementptr inbounds i8, i8* %argp.cur2, i64 4
+// AIX64-NEXT: %6 = bitcast i8* %5 to i32*
+// AIX64-NEXT: %7 = load i32, i32* %6, align 4
+// AIX64-NEXT: store i32 %7, i32* %v, align 4
+
+// CHECK-NEXT: %ap24 = bitcast i8** %ap2 to i8*
+// CHECK-NEXT: call void @llvm.va_end(i8* %ap24)
+// CHECK-NEXT: %ap5 = bitcast i8** %ap to i8*
+// CHECK-NEXT: call void @llvm.va_end(i8* %ap5)
+// CHECK-NEXT: ret void
+
+// CHECK: declare void @llvm.va_start(i8*)
+
+// AIX32: declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg)
+// AIX64: declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg)
+
+// CHECK: declare void @llvm.va_copy(i8*, i8*)
+// CHECK: declare void @llvm.va_end(i8*)
diff --git a/clang/test/CodeGen/aix-vector.c b/clang/test/CodeGen/aix-vector.c
new file mode 100644
index 000000000000..79a1fe4344db
--- /dev/null
+++ b/clang/test/CodeGen/aix-vector.c
@@ -0,0 +1,10 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc-unknown-aix -target-feature +altivec \
+// RUN: -emit-llvm -o - %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-aix -target-feature +altivec \
+// RUN: -emit-llvm -o - %s 2>&1 | FileCheck %s
+
+// CHECK: fatal error: error in backend: vector type is not supported on AIX yet
+vector signed int retVector(vector signed int x) {
+ return x;
+}
diff --git a/clang/test/CodeGen/ppc32-struct-return.c b/clang/test/CodeGen/ppc32-and-aix-struct-return.c
similarity index 72%
rename from clang/test/CodeGen/ppc32-struct-return.c
rename to clang/test/CodeGen/ppc32-and-aix-struct-return.c
index 30a6a26820b0..1e0fb9283c96 100644
--- a/clang/test/CodeGen/ppc32-struct-return.c
+++ b/clang/test/CodeGen/ppc32-and-aix-struct-return.c
@@ -1,6 +1,10 @@
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc-unknown-freebsd \
// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
// RUN: %clang_cc1 -triple powerpc-unknown-linux \
// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
// RUN: %clang_cc1 -triple powerpc-unknown-linux -maix-struct-return \
@@ -47,42 +51,42 @@ typedef struct {
char c[9];
} Nine;
-// CHECK-AIX-LABEL: define void @ret0(%struct.Zero* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret0(%struct.Zero* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define void @ret0()
Zero ret0(void) { return (Zero){}; }
-// CHECK-AIX-LABEL: define void @ret1(%struct.One* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret1(%struct.One* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i8 @ret1()
One ret1(void) { return (One){'a'}; }
-// CHECK-AIX-LABEL: define void @ret2(%struct.Two* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret2(%struct.Two* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i16 @ret2()
Two ret2(void) { return (Two){123}; }
-// CHECK-AIX-LABEL: define void @ret3(%struct.Three* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret3(%struct.Three* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i24 @ret3()
Three ret3(void) { return (Three){"abc"}; }
-// CHECK-AIX-LABEL: define void @ret4(%struct.Four* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret4(%struct.Four* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i32 @ret4()
Four ret4(void) { return (Four){0.4}; }
-// CHECK-AIX-LABEL: define void @ret5(%struct.Five* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret5(%struct.Five* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i40 @ret5()
Five ret5(void) { return (Five){"abcde"}; }
-// CHECK-AIX-LABEL: define void @ret6(%struct.Six* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret6(%struct.Six* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i48 @ret6()
Six ret6(void) { return (Six){12, 34, 56}; }
-// CHECK-AIX-LABEL: define void @ret7(%struct.Seven* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret7(%struct.Seven* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i56 @ret7()
Seven ret7(void) { return (Seven){"abcdefg"}; }
-// CHECK-AIX-LABEL: define void @ret8(%struct.Eight* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret8(%struct.Eight* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define i64 @ret8()
Eight ret8(void) { return (Eight){123, 'a'}; }
-// CHECK-AIX-LABEL: define void @ret9(%struct.Nine* noalias sret {{[^,]*}})
+// CHECK-AIX-LABEL: define void @ret9(%struct.Nine* noalias sret {{[^,]*}})
// CHECK-SVR4-LABEL: define void @ret9(%struct.Nine* noalias sret {{[^,]*}})
Nine ret9(void) { return (Nine){"abcdefghi"}; }
diff --git a/clang/test/CodeGen/ppc32-dwarf.c b/clang/test/CodeGen/ppc32-dwarf.c
new file mode 100644
index 000000000000..65a3b3a2ea9b
--- /dev/null
+++ b/clang/test/CodeGen/ppc32-dwarf.c
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
+static unsigned char dwarf_reg_size_table[1024];
+
+int test() {
+ __builtin_init_dwarf_reg_size_table(dwarf_reg_size_table);
+
+ return __builtin_dwarf_sp_column();
+}
+
+// CHECK-LABEL: define i32 @test()
+// CHECK: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 0), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 1), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 2), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 3), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 4), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 5), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 6), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 7), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 8), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 9), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 10), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 11), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 12), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 13), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 14), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 15), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 16), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 17), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 18), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 19), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 20), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 21), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 22), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 23), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 24), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 25), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 26), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 27), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 28), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 29), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 30), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 31), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 32), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 33), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 34), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 35), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 36), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 37), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 38), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 39), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 40), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 41), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 42), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 43), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 44), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 45), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 46), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 47), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 48), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 49), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 50), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 51), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 52), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 53), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 54), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 55), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 56), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 57), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 58), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 59), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 60), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 61), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 62), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 63), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 64), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 65), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 66), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 67), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 68), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 69), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 70), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 71), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 72), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 73), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 74), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 75), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 76), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 77), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 78), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 79), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 80), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 81), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 82), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 83), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 84), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 85), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 86), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 87), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 88), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 89), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 90), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 91), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 92), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 93), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 94), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 95), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 96), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 97), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 98), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 99), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 100), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 101), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 102), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 103), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 104), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 105), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 106), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 107), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 108), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 109), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 110), align 1
+// PPC32-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 111), align 1
+// PPC32-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 112), align 1
+// PPC32-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 113), align 1
+// PPC32-NEXT: ret i32 1
diff --git a/clang/test/CodeGen/ppc64-dwarf.c b/clang/test/CodeGen/ppc64-dwarf.c
index fc815c68988e..aa72a622cc3a 100644
--- a/clang/test/CodeGen/ppc64-dwarf.c
+++ b/clang/test/CodeGen/ppc64-dwarf.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
static unsigned char dwarf_reg_size_table[1024];
int test() {
@@ -119,10 +120,10 @@ int test() {
// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 108), align 1
// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 109), align 1
// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 110), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 111), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 112), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 113), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 114), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 115), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 116), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 111), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 112), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 113), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 114), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 115), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 116), align 1
// CHECK-NEXT: ret i32 1
diff --git a/clang/test/Frontend/aix-unsupported.c b/clang/test/Frontend/aix-unsupported.c
new file mode 100644
index 000000000000..5cc731f69de1
--- /dev/null
+++ b/clang/test/Frontend/aix-unsupported.c
@@ -0,0 +1,10 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc-unknown-aix -maix-struct-return \
+// RUN: -c %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc-unknown-aix -msvr4-struct-return \
+// RUN: -c %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-aix -maix-struct-return \
+// RUN: -c %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-aix -msvr4-struct-return \
+// RUN: -c %s 2>&1 | FileCheck %s
+// CHECK: unsupported option
More information about the cfe-commits
mailing list