Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -4260,6 +4260,11 @@ public: AArch64ABIInfo(CodeGenTypes &CGT, ABIKind Kind) : ABIInfo(CGT), Kind(Kind) {} + bool isAndroid() const { + return (getTarget().getTriple().getEnvironment() == + llvm::Triple::Android); + } + private: ABIKind getABIKind() const { return Kind; } bool isDarwinPCS() const { return Kind == DarwinPCS; } @@ -4316,6 +4321,11 @@ // Handle illegal vector types here. if (isIllegalVectorType(Ty)) { uint64_t Size = getContext().getTypeSize(Ty); + // Android promotes <2 x i8> to i16, not i32 + if(AArch64ABIInfo::isAndroid() && (Size <= 16)) { + llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext()); + return ABIArgInfo::getDirect(ResType); + } if (Size <= 32) { llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext()); return ABIArgInfo::getDirect(ResType); Index: test/CodeGen/aarch64-abi-vector.c =================================================================== --- /dev/null +++ test/CodeGen/aarch64-abi-vector.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple aarch64-linux-android -emit-llvm -o - %s | tee /tmp/testout | FileCheck -check-prefix=ANDROID %s + +#include + +typedef __attribute__(( ext_vector_type(2) )) char __char2; + +// Passing legal vector types as varargs. Check that we've allocated the appropriate size +double varargs_vec_2c(int fixed, ...) { +// ANDROID: varargs_vec_2c +// ANDROID: [[VAR:%.*]] = alloca <2 x i8>, align 2 +// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8 +// ANDROID: bitcast i8* [[AP_CUR]] to <2 x i8>* + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __char2 c3 = va_arg(ap, __char2); + sum = sum + c3.x + c3.y; + va_end(ap); + return sum; +} + +double test_2c(__char2 *in) { +// ANDROID: call double (i32, ...) @varargs_vec_2c(i32 3, i16 {{%.*}}) + return varargs_vec_2c(3, *in); +}