Index: lib/CodeGen/ABIInfo.h =================================================================== --- lib/CodeGen/ABIInfo.h +++ lib/CodeGen/ABIInfo.h @@ -85,6 +85,8 @@ CodeGen::Address VAListAddr, QualType Ty) const = 0; + bool isAndroid() const; + /// Emit the target dependent code to load a value of /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -117,6 +117,8 @@ return CGT.getTarget(); } +bool ABIInfo:: isAndroid() const { return getTarget().getTriple().isAndroid(); } + bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { return false; } @@ -4316,6 +4318,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(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); @@ -4800,11 +4807,6 @@ } } - bool isAndroid() const { - return (getTarget().getTriple().getEnvironment() == - llvm::Triple::Android); - } - ABIKind getABIKind() const { return Kind; } private: Index: test/CodeGen/arm64-abi-vector.c =================================================================== --- test/CodeGen/arm64-abi-vector.c +++ test/CodeGen/arm64-abi-vector.c @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-android -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s #include +typedef __attribute__(( ext_vector_type(2) )) char __char2; typedef __attribute__(( ext_vector_type(3) )) char __char3; typedef __attribute__(( ext_vector_type(4) )) char __char4; typedef __attribute__(( ext_vector_type(5) )) char __char5; @@ -13,6 +15,26 @@ typedef __attribute__(( ext_vector_type(5) )) int __int5; typedef __attribute__(( ext_vector_type(3) )) double __double3; +// 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); +} + double varargs_vec_3c(int fixed, ...) { // CHECK: varargs_vec_3c // CHECK: alloca <3 x i8>, align 4