diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -1544,11 +1544,11 @@ : ABIArgInfo::getDirect()); } -static bool isSSEVectorType(ASTContext &Context, QualType Ty) { +static bool isSIMDVectorType(ASTContext &Context, QualType Ty) { return Ty->getAs() && Context.getTypeSize(Ty) == 128; } -static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) { +static bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) { const RecordType *RT = Ty->getAs(); if (!RT) return 0; @@ -1557,16 +1557,16 @@ // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(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 @@ } // 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 @@ /*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(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()) + 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()) + 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::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 @@ 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 @@ } 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 @@ 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 @@ 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 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1298,6 +1298,12 @@ 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 --- /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 --- /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 --- /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 --- /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 --- /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 rename from clang/test/CodeGen/ppc32-struct-return.c rename to clang/test/CodeGen/ppc32-and-aix-struct-return.c --- 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 @@ 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 --- /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 --- 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 @@ // 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 --- /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