diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 918e5d45cedf..40f8730e61af 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1519,12 +1519,38 @@ void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, void MicrosoftCXXNameMangler::mangleType(const VectorType *T, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this vector type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + const BuiltinType *ET = T->getElementType()->getAs(); + assert(ET && "vectors with non-builtin elements are unsupported"); + uint64_t Width = getASTContext().getTypeSize(T); + // Pattern match exactly the typedefs in our intrinsic headers. Anything that + // doesn't match the Intel types uses a custom mangling below. + bool IntelVector = true; + if (Width == 64 && ET->getKind() == BuiltinType::LongLong) { + Out << "T__m64"; + } else if (Width == 128 || Width == 256) { + if (ET->getKind() == BuiltinType::Float) + Out << "T__m" << Width; + else if (ET->getKind() == BuiltinType::LongLong) + Out << "T__m" << Width << 'i'; + else if (ET->getKind() == BuiltinType::Double) + Out << "U__m" << Width << 'd'; + else + IntelVector = false; + } else { + IntelVector = false; + } + + if (!IntelVector) { + // The MS ABI doesn't have a special mangling for vector types, so we define + // our own mangling to handle uses of __vector_size__ on user-specified + // types, and for extensions like __v4sf. + Out << "T__clang_vec" << T->getNumElements() << '_'; + mangleType(ET, Range); + } + + Out << "@@"; } + void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); diff --git a/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp b/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp new file mode 100644 index 000000000000..64cb7250a41f --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fms-extensions -ffreestanding -target-feature +avx -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s + +#include +#include +#include + +void foo64(__m64) {} +// CHECK: define void @"\01?foo64@@YAXT__m64@@@Z" + +void foo128(__m128) {} +// CHECK: define void @"\01?foo128@@YAXT__m128@@@Z" + +void foo128d(__m128d) {} +// CHECK: define void @"\01?foo128d@@YAXU__m128d@@@Z" + +void foo128i(__m128i) {} +// CHECK: define void @"\01?foo128i@@YAXT__m128i@@@Z" + +void foo256(__m256) {} +// CHECK: define void @"\01?foo256@@YAXT__m256@@@Z" + +void foo256d(__m256d) {} +// CHECK: define void @"\01?foo256d@@YAXU__m256d@@@Z" + +void foo256i(__m256i) {} +// CHECK: define void @"\01?foo256i@@YAXT__m256i@@@Z" + +// We have a custom mangling for vector types not standardized by Intel. +void foov8hi(__v8hi) {} +// CHECK: define void @"\01?foov8hi@@YAXT__clang_vec8_F@@@Z" + +// Clang does not support vectors of complex types, so we can't test the +// mangling of them.