[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