Index: clang/lib/Basic/Targets/PPC.h =================================================================== --- clang/lib/Basic/Targets/PPC.h +++ clang/lib/Basic/Targets/PPC.h @@ -369,7 +369,8 @@ } BuiltinVaListKind getBuiltinVaListKind() const override { - // This is the ELF definition, and is overridden by the Darwin sub-target + // This is the ELF definition, and is overridden by the Darwin and AIX + // sub-target. return TargetInfo::PowerABIBuiltinVaList; } }; Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -4229,7 +4229,10 @@ // DefaultABIInfo::EmitVAArg. Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, QualType Ty) const { - if (getTarget().getTriple().isOSDarwin()) { + // TODO: Add AIX ABI Info. Currently we are relying on PPC32_SVR4_ABIInfo to + // emit correct VAArg. + if (getTarget().getTriple().isOSDarwin() || + getTarget().getTriple().isOSAIX()) { auto TI = getContext().getTypeInfoInChars(Ty); TI.second = getParamTypeAlignment(Ty); Index: clang/test/CodeGen/aix-vararg.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aix-vararg.c @@ -0,0 +1,30 @@ +// REQUIRES: powerpc-registered-target +// REQUIRES: asserts +// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -emit-llvm -o - %s | FileCheck %s --check-prefix=32BIT +#include + +void aix_varg(int a, ...) { + va_list arg; + va_start(arg, a); + va_arg(arg, int); + va_end(arg); +} + +// 32BIT: define void @aix_varg(i32 %a, ...) #0 { +// 32BIT: entry: +// 32BIT-NEXT: %a.addr = alloca i32, align 4 +// 32BIT-NEXT: %arg = alloca i8*, align 4 +// 32BIT-NEXT: store i32 %a, i32* %a.addr, align 4 +// 32BIT-NEXT: %arg1 = bitcast i8** %arg to i8* +// 32BIT-NEXT: call void @llvm.va_start(i8* %arg1) +// 32BIT-NEXT: %argp.cur = load i8*, i8** %arg, align 4 +// 32BIT-NEXT: %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4 +// 32BIT-NEXT: store i8* %argp.next, i8** %arg, align 4 +// 32BIT-NEXT: %0 = bitcast i8* %argp.cur to i32* +// 32BIT-NEXT: %1 = load i32, i32* %0, align 4 +// 32BIT-NEXT: %arg2 = bitcast i8** %arg to i8* +// 32BIT-NEXT: call void @llvm.va_end(i8* %arg2) +// 32BIT-NEXT: ret void +// 32BIT-NEXT: } +// 32BIT: declare void @llvm.va_start(i8*) +// 32BIT: declare void @llvm.va_end(i8*)