diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/package.json b/clang-tools-extra/clangd/clients/clangd-vscode/package.json index 05aafeb5f850c5..8abf7e743e6f25 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/package.json +++ b/clang-tools-extra/clangd/clients/clangd-vscode/package.json @@ -23,6 +23,7 @@ "activationEvents": [ "onLanguage:c", "onLanguage:cpp", + "onLanguage:cuda", "onLanguage:objective-c", "onLanguage:objective-cpp", "onCommand:clangd-vscode.activate" @@ -64,6 +65,13 @@ "**/MSVC/*/include/**" ], "firstLine": "^/[/*].*-\\*-\\s*C\\+\\+\\s*-\\*-.*" + }, + { + "id": "cuda", + "extensions": [ + ".cu", + ".cuh" + ] } ], "configuration": { diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts b/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts index 330cf7ac262ebc..1f96cffef2559e 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts +++ b/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts @@ -83,21 +83,15 @@ export function activate(context: vscode.ExtensionContext) { } const serverOptions: vscodelc.ServerOptions = clangd; - // Note that CUDA ('.cu') files are special. When opening files of all other - // extensions, VSCode would load clangd automatically. This is achieved by - // having a corresponding 'onLanguage:...' activation event in package.json. - // However, VSCode does not have CUDA as a supported language yet, so we - // cannot add a corresponding activationEvent for CUDA files and clangd will - // *not* load itself automatically on '.cu' files. - const cudaFilePattern: string = '**/*.{' + [ 'cu' ].join() + '}'; const clientOptions: vscodelc.LanguageClientOptions = { // Register the server for c-family and cuda files. documentSelector: [ { scheme: 'file', language: 'c' }, { scheme: 'file', language: 'cpp' }, + // cuda is not supported by vscode, but our extension does. + { scheme: 'file', language: 'cuda' }, { scheme: 'file', language: 'objective-c'}, - { scheme: 'file', language: 'objective-cpp'}, - { scheme: 'file', pattern: cudaFilePattern }, + { scheme: 'file', language: 'objective-cpp'} ], synchronize: !syncFileEvents ? undefined : { // FIXME: send sync file events when clangd provides implemenatations. @@ -111,10 +105,10 @@ export function activate(context: vscode.ExtensionContext) { serverOptions, clientOptions); if (getConfig('semanticHighlighting')) { const semanticHighlightingFeature = - new semanticHighlighting.SemanticHighlightingFeature(clangdClient, - context); + new semanticHighlighting.SemanticHighlightingFeature(clangdClient, + context); context.subscriptions.push( - vscode.Disposable.from(semanticHighlightingFeature)); + vscode.Disposable.from(semanticHighlightingFeature)); clangdClient.registerFeature(semanticHighlightingFeature); } console.log('Clang Language Server is now active!'); diff --git a/clang-tools-extra/test/clang-change-namespace/macro.cpp b/clang-tools-extra/test/clang-change-namespace/macro.cpp index ba47de603da81e..40c4caf0589932 100644 --- a/clang-tools-extra/test/clang-change-namespace/macro.cpp +++ b/clang-tools-extra/test/clang-change-namespace/macro.cpp @@ -1,7 +1,7 @@ // RUN: cp %S/macro.cpp %T/macro.cpp // RUN: echo "#define USING using na::nc::X" > %T/macro.h // -// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern "macro.cpp" --i %T/macro.cpp -- +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern "macro.cpp$" --i %T/macro.cpp -- // RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s // RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-HEADER %s // diff --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td index ed925a200726f0..5fa9fc008202b7 100644 --- a/clang/include/clang/Basic/arm_mve.td +++ b/clang/include/clang/Basic/arm_mve.td @@ -47,6 +47,10 @@ def vornq: Intrinsic; def vorrq: Intrinsic; def vsubq: Intrinsic; def vmulq: Intrinsic; +def vmulhq: Intrinsic $a, $b)>; +def vrmulhq: Intrinsic $a, $b)>; } let params = T.Float in { @@ -113,6 +117,12 @@ def vminq_m: Intrinsic< def vmaxq_m: Intrinsic< Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred), (IRInt<"max_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>; +def vmulhq_m: Intrinsic< + Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred), + (IRInt<"mulh_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>; +def vrmulhq_m: Intrinsic< + Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred), + (IRInt<"rmulh_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>; } // Predicated intrinsics - Float types only diff --git a/clang/include/clang/Tooling/CompilationDatabase.h b/clang/include/clang/Tooling/CompilationDatabase.h index dea046a2dc7c3a..b28a8a6d6e51cb 100644 --- a/clang/include/clang/Tooling/CompilationDatabase.h +++ b/clang/include/clang/Tooling/CompilationDatabase.h @@ -31,6 +31,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/VirtualFileSystem.h" #include #include #include @@ -219,6 +220,12 @@ std::unique_ptr std::unique_ptr inferTargetAndDriverMode(std::unique_ptr Base); +/// Returns a wrapped CompilationDatabase that will expand all rsp(response) +/// files on commandline returned by underlying database. +std::unique_ptr +expandResponseFiles(std::unique_ptr Base, + llvm::IntrusiveRefCntPtr FS); + } // namespace tooling } // namespace clang diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d35037273106a1..660be458a698aa 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6128,7 +6128,26 @@ void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) { if ((getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) && Var->hasGlobalStorage()) ImplAS = LangAS::opencl_global; + // If the original type from a decayed type is an array type and that array + // type has no address space yet, deduce it now. + if (auto DT = dyn_cast(Type)) { + auto OrigTy = DT->getOriginalType(); + if (!OrigTy.getQualifiers().hasAddressSpace() && OrigTy->isArrayType()) { + // Add the address space to the original array type and then propagate + // that to the element type through `getAsArrayType`. + OrigTy = Context.getAddrSpaceQualType(OrigTy, ImplAS); + OrigTy = QualType(Context.getAsArrayType(OrigTy), 0); + // Re-generate the decayed type. + Type = Context.getDecayedType(OrigTy); + } + } Type = Context.getAddrSpaceQualType(Type, ImplAS); + // Apply any qualifiers (including address space) from the array type to + // the element type. This implements C99 6.7.3p8: "If the specification of + // an array type includes any type qualifiers, the element type is so + // qualified, not the array type." + if (Type->isArrayType()) + Type = QualType(Context.getAsArrayType(Type), 0); Decl->setType(Type); } } diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 05061f0a10a804..59c990daaa29ff 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangTooling CommonOptionsParser.cpp CompilationDatabase.cpp Execution.cpp + ExpandResponseFilesCompilationDatabase.cpp FileMatchTrie.cpp FixIt.cpp GuessTargetAndModeCompilationDatabase.cpp diff --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp new file mode 100644 index 00000000000000..84936ba05b20f8 --- /dev/null +++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp @@ -0,0 +1,88 @@ +//===- ExpandResponseFileCompilationDataBase.cpp --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/CompilationDatabase.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/StringSaver.h" + +namespace clang { +namespace tooling { +namespace { + +class ExpandResponseFilesDatabase : public CompilationDatabase { +public: + ExpandResponseFilesDatabase( + std::unique_ptr Base, + llvm::cl::TokenizerCallback Tokenizer, + llvm::IntrusiveRefCntPtr FS) + : Base(std::move(Base)), Tokenizer(Tokenizer), FS(std::move(FS)) { + assert(this->Base != nullptr); + assert(this->Tokenizer != nullptr); + assert(this->FS != nullptr); + } + + std::vector getAllFiles() const override { + return Base->getAllFiles(); + } + + std::vector + getCompileCommands(StringRef FilePath) const override { + return expand(Base->getCompileCommands(FilePath)); + } + + std::vector getAllCompileCommands() const override { + return expand(Base->getAllCompileCommands()); + } + +private: + std::vector expand(std::vector Cmds) const { + for (auto &Cmd : Cmds) { + bool SeenRSPFile = false; + llvm::SmallVector Argv; + Argv.reserve(Cmd.CommandLine.size()); + for (auto &Arg : Cmd.CommandLine) { + Argv.push_back(Arg.c_str()); + SeenRSPFile |= Arg.front() == '@'; + } + if (!SeenRSPFile) + continue; + llvm::BumpPtrAllocator Alloc; + llvm::StringSaver Saver(Alloc); + llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, *FS, + llvm::StringRef(Cmd.Directory)); + Cmd.CommandLine.assign(Argv.begin(), Argv.end()); + } + return Cmds; + } + +private: + std::unique_ptr Base; + llvm::cl::TokenizerCallback Tokenizer; + llvm::IntrusiveRefCntPtr FS; +}; + +} // namespace + +std::unique_ptr +expandResponseFiles(std::unique_ptr Base, + llvm::IntrusiveRefCntPtr FS) { + auto Tokenizer = llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows() + ? llvm::cl::TokenizeWindowsCommandLine + : llvm::cl::TokenizeGNUCommandLine; + return std::make_unique( + std::move(Base), Tokenizer, std::move(FS)); +} + +} // namespace tooling +} // namespace clang diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp index f19a0f7550b960..04dd4dbf624842 100644 --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include @@ -168,7 +169,8 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin { auto Base = JSONCompilationDatabase::loadFromFile( JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect); return Base ? inferTargetAndDriverMode( - inferMissingCompileCommands(std::move(Base))) + inferMissingCompileCommands(expandResponseFiles( + std::move(Base), llvm::vfs::getRealFileSystem()))) : nullptr; } }; diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c new file mode 100644 index 00000000000000..63696d698c5032 --- /dev/null +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c @@ -0,0 +1,95 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s + +#include + +// CHECK-LABEL: @test_vmulhq_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.arm.mve.vmulh.v16i8(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_vmulhq_u8(uint8x16_t a, uint8x16_t b) +{ +#ifdef POLYMORPHIC + return vmulhq(a, b); +#else /* POLYMORPHIC */ + return vmulhq_u8(a, b); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vmulhq_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i16> @llvm.arm.mve.vmulh.v8i16(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// +int16x8_t test_vmulhq_s16(int16x8_t a, int16x8_t b) +{ +#ifdef POLYMORPHIC + return vmulhq(a, b); +#else /* POLYMORPHIC */ + return vmulhq_s16(a, b); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vmulhq_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.arm.mve.vmulh.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +uint32x4_t test_vmulhq_u32(uint32x4_t a, uint32x4_t b) +{ +#ifdef POLYMORPHIC + return vmulhq(a, b); +#else /* POLYMORPHIC */ + return vmulhq_u32(a, b); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vmulhq_m_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.mulh.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP2]] +// +int8x16_t test_vmulhq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p) +{ +#ifdef POLYMORPHIC + return vmulhq_m(inactive, a, b, p); +#else /* POLYMORPHIC */ + return vmulhq_m_s8(inactive, a, b, p); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vmulhq_m_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.mulh.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP2]] +// +uint16x8_t test_vmulhq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p) +{ +#ifdef POLYMORPHIC + return vmulhq_m(inactive, a, b, p); +#else /* POLYMORPHIC */ + return vmulhq_m_u16(inactive, a, b, p); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vmulhq_m_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.mulh.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP2]] +// +int32x4_t test_vmulhq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p) +{ +#ifdef POLYMORPHIC + return vmulhq_m(inactive, a, b, p); +#else /* POLYMORPHIC */ + return vmulhq_m_s32(inactive, a, b, p); +#endif /* POLYMORPHIC */ +} diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c b/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c new file mode 100644 index 00000000000000..2c8148405585b4 --- /dev/null +++ b/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c @@ -0,0 +1,95 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s + +#include + +// CHECK-LABEL: @test_vrmulhq_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.arm.mve.vrmulh.v16i8(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_vrmulhq_u8(uint8x16_t a, uint8x16_t b) +{ +#ifdef POLYMORPHIC + return vrmulhq(a, b); +#else /* POLYMORPHIC */ + return vrmulhq_u8(a, b); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vrmulhq_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i16> @llvm.arm.mve.vrmulh.v8i16(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// +int16x8_t test_vrmulhq_s16(int16x8_t a, int16x8_t b) +{ +#ifdef POLYMORPHIC + return vrmulhq(a, b); +#else /* POLYMORPHIC */ + return vrmulhq_s16(a, b); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vrmulhq_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.arm.mve.vrmulh.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +uint32x4_t test_vrmulhq_u32(uint32x4_t a, uint32x4_t b) +{ +#ifdef POLYMORPHIC + return vrmulhq(a, b); +#else /* POLYMORPHIC */ + return vrmulhq_u32(a, b); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vrmulhq_m_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.rmulh.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP2]] +// +int8x16_t test_vrmulhq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p) +{ +#ifdef POLYMORPHIC + return vrmulhq_m(inactive, a, b, p); +#else /* POLYMORPHIC */ + return vrmulhq_m_s8(inactive, a, b, p); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vrmulhq_m_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.rmulh.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP2]] +// +uint16x8_t test_vrmulhq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p) +{ +#ifdef POLYMORPHIC + return vrmulhq_m(inactive, a, b, p); +#else /* POLYMORPHIC */ + return vrmulhq_m_u16(inactive, a, b, p); +#endif /* POLYMORPHIC */ +} + +// CHECK-LABEL: @test_vrmulhq_m_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.rmulh.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP2]] +// +int32x4_t test_vrmulhq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p) +{ +#ifdef POLYMORPHIC + return vrmulhq_m(inactive, a, b, p); +#else /* POLYMORPHIC */ + return vrmulhq_m_s32(inactive, a, b, p); +#endif /* POLYMORPHIC */ +} diff --git a/clang/test/SemaOpenCL/address-spaces.cl b/clang/test/SemaOpenCL/address-spaces.cl index 55a55dc750501d..09a6dd0ba53fe7 100644 --- a/clang/test/SemaOpenCL/address-spaces.cl +++ b/clang/test/SemaOpenCL/address-spaces.cl @@ -241,3 +241,10 @@ void func_multiple_addr(void) { __private private_int_t var5; // expected-warning {{multiple identical address spaces specified for type}} __private private_int_t *var6;// expected-warning {{multiple identical address spaces specified for type}} } + +void func_with_array_param(const unsigned data[16]); + +__kernel void k() { + unsigned data[16]; + func_with_array_param(data); +} diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp index 87727fe7c90790..91685c0d0c7368 100644 --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -859,5 +859,35 @@ TEST_F(TargetAndModeTest, TargetAndMode) { "clang++ --driver-mode=g++ bar.cpp -D bar.cpp"); } +class ExpandResponseFilesTest : public MemDBTest { +public: + ExpandResponseFilesTest() : FS(new llvm::vfs::InMemoryFileSystem) {} + +protected: + void addFile(StringRef File, StringRef Content) { + ASSERT_TRUE( + FS->addFile(File, 0, llvm::MemoryBuffer::getMemBufferCopy(Content))); + } + + std::string getCommand(llvm::StringRef F) { + auto Results = expandResponseFiles(std::make_unique(Entries), FS) + ->getCompileCommands(path(F)); + if (Results.empty()) + return "none"; + return llvm::join(Results[0].CommandLine, " "); + } + + llvm::IntrusiveRefCntPtr FS; +}; + +TEST_F(ExpandResponseFilesTest, ExpandResponseFiles) { + addFile(path(StringRef("rsp1.rsp")), "-Dflag"); + + add("foo.cpp", "clang", "@rsp1.rsp"); + add("bar.cpp", "clang", "-Dflag"); + EXPECT_EQ(getCommand("foo.cpp"), "clang foo.cpp -D foo.cpp -Dflag"); + EXPECT_EQ(getCommand("bar.cpp"), "clang bar.cpp -D bar.cpp -Dflag"); +} + } // end namespace tooling } // end namespace clang diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm index 8c7393739bc688..03880ff433bd66 100644 --- a/lldb/source/Host/macosx/objcxx/Host.mm +++ b/lldb/source/Host/macosx/objcxx/Host.mm @@ -1130,7 +1130,7 @@ static Status LaunchProcessPosixSpawn(const char *exe_path, // --arch as part of the shell invocation // to do that job on OSX. - if (launch_info.GetShell() == nullptr) { + if (launch_info.GetShell() == FileSpec()) { // We don't need to do this for ARM, and we really shouldn't now that we // have multiple CPU subtypes and no posix_spawnattr call that allows us // to set which CPU subtype to launch... diff --git a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index 74718a8c5e307e..5ee632ec20773a 100644 --- a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -595,7 +595,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, } Status error = Host::RunShellCommand( command.GetData(), - NULL, // current working directory + FileSpec(), // current working directory &exit_status, // Exit status &signo, // Signal int * &command_output, // Command output diff --git a/llvm/include/llvm/IR/IntrinsicsARM.td b/llvm/include/llvm/IR/IntrinsicsARM.td index 894a4be2947c8e..c4061ea01eeec6 100644 --- a/llvm/include/llvm/IR/IntrinsicsARM.td +++ b/llvm/include/llvm/IR/IntrinsicsARM.td @@ -834,6 +834,12 @@ def int_arm_mve_sub_predicated: Intrinsic<[llvm_anyvector_ty], def int_arm_mve_mul_predicated: Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>], [IntrNoMem]>; +def int_arm_mve_mulh_predicated: Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>], + [IntrNoMem]>; +def int_arm_mve_rmulh_predicated: Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>], + [IntrNoMem]>; defm int_arm_mve_minv: IntrinsicSignSuffix<[llvm_i32_ty], [llvm_i32_ty, llvm_anyvector_ty], [IntrNoMem]>; @@ -908,6 +914,12 @@ def int_arm_mve_vadc_predicated: Intrinsic< [llvm_anyvector_ty, llvm_i32_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty, llvm_anyvector_ty], [IntrNoMem]>; +def int_arm_mve_vmulh: Intrinsic< + [llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; +def int_arm_mve_vrmulh: Intrinsic< + [llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; def int_arm_mve_vld2q: Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], [llvm_anyptr_ty], [IntrReadMem]>; def int_arm_mve_vld4q: Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [llvm_anyptr_ty], [IntrReadMem]>; diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index faef60c4e47f4c..6c0bb6c2fc3adf 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -20,6 +20,8 @@ #define LLVM_SUPPORT_COMMANDLINE_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -29,6 +31,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -1964,10 +1967,16 @@ bool readConfigFile(StringRef CfgFileName, StringSaver &Saver, /// with nullptrs in the Argv vector. /// \param [in] RelativeNames true if names of nested response files must be /// resolved relative to including file. +/// \param [in] FS File system used for all file access when running the tool. +/// \param [in] CurrentDir Path used to resolve relative rsp files. If set to +/// None, process' cwd is used instead. /// \return true if all @files were expanded successfully or there were none. -bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, - SmallVectorImpl &Argv, - bool MarkEOLs = false, bool RelativeNames = false); +bool ExpandResponseFiles( + StringSaver &Saver, TokenizerCallback Tokenizer, + SmallVectorImpl &Argv, bool MarkEOLs = false, + bool RelativeNames = false, + llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem(), + llvm::Optional CurrentDir = llvm::None); /// Mark all options not part of this category as cl::ReallyHidden. /// diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 92e0f5b2210488..1f424075d47fd0 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -24,11 +24,13 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -37,9 +39,11 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include #include +#include using namespace llvm; using namespace cl; @@ -1043,14 +1047,16 @@ static bool hasUTF8ByteOrderMark(ArrayRef S) { return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf'); } -static bool ExpandResponseFile(StringRef FName, StringSaver &Saver, - TokenizerCallback Tokenizer, - SmallVectorImpl &NewArgv, - bool MarkEOLs, bool RelativeNames) { - ErrorOr> MemBufOrErr = - MemoryBuffer::getFile(FName); +// FName must be an absolute path. +static llvm::Error ExpandResponseFile( + StringRef FName, StringSaver &Saver, TokenizerCallback Tokenizer, + SmallVectorImpl &NewArgv, bool MarkEOLs, bool RelativeNames, + llvm::vfs::FileSystem &FS) { + assert(sys::path::is_absolute(FName)); + llvm::ErrorOr> MemBufOrErr = + FS.getBufferForFile(FName); if (!MemBufOrErr) - return false; + return llvm::errorCodeToError(MemBufOrErr.getError()); MemoryBuffer &MemBuf = *MemBufOrErr.get(); StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize()); @@ -1059,7 +1065,8 @@ static bool ExpandResponseFile(StringRef FName, StringSaver &Saver, std::string UTF8Buf; if (hasUTF16ByteOrderMark(BufRef)) { if (!convertUTF16ToUTF8String(BufRef, UTF8Buf)) - return false; + return llvm::createStringError(std::errc::illegal_byte_sequence, + "Could not convert UTF16 to UTF8"); Str = StringRef(UTF8Buf); } // If we see UTF-8 BOM sequence at the beginning of a file, we shall remove @@ -1071,41 +1078,40 @@ static bool ExpandResponseFile(StringRef FName, StringSaver &Saver, // Tokenize the contents into NewArgv. Tokenizer(Str, Saver, NewArgv, MarkEOLs); + if (!RelativeNames) + return Error::success(); + llvm::StringRef BasePath = llvm::sys::path::parent_path(FName); // If names of nested response files should be resolved relative to including // file, replace the included response file names with their full paths // obtained by required resolution. - if (RelativeNames) - for (unsigned I = 0; I < NewArgv.size(); ++I) - if (NewArgv[I]) { - StringRef Arg = NewArgv[I]; - if (Arg.front() == '@') { - StringRef FileName = Arg.drop_front(); - if (llvm::sys::path::is_relative(FileName)) { - SmallString<128> ResponseFile; - ResponseFile.append(1, '@'); - if (llvm::sys::path::is_relative(FName)) { - SmallString<128> curr_dir; - llvm::sys::fs::current_path(curr_dir); - ResponseFile.append(curr_dir.str()); - } - llvm::sys::path::append( - ResponseFile, llvm::sys::path::parent_path(FName), FileName); - NewArgv[I] = Saver.save(ResponseFile.c_str()).data(); - } - } - } + for (auto &Arg : NewArgv) { + // Skip non-rsp file arguments. + if (!Arg || Arg[0] != '@') + continue; - return true; + StringRef FileName(Arg + 1); + // Skip if non-relative. + if (!llvm::sys::path::is_relative(FileName)) + continue; + + SmallString<128> ResponseFile; + ResponseFile.push_back('@'); + ResponseFile.append(BasePath); + llvm::sys::path::append(ResponseFile, FileName); + Arg = Saver.save(ResponseFile.c_str()).data(); + } + return Error::success(); } /// Expand response files on a command line recursively using the given /// StringSaver and tokenization strategy. bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, - SmallVectorImpl &Argv, - bool MarkEOLs, bool RelativeNames) { + SmallVectorImpl &Argv, bool MarkEOLs, + bool RelativeNames, llvm::vfs::FileSystem &FS, + llvm::Optional CurrentDir) { bool AllExpanded = true; struct ResponseFileRecord { - const char *File; + std::string File; size_t End; }; @@ -1139,8 +1145,31 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, } const char *FName = Arg + 1; - auto IsEquivalent = [FName](const ResponseFileRecord &RFile) { - return sys::fs::equivalent(RFile.File, FName); + // Note that CurrentDir is only used for top-level rsp files, the rest will + // always have an absolute path deduced from the containing file. + SmallString<128> CurrDir; + if (llvm::sys::path::is_relative(FName)) { + if (!CurrentDir) + llvm::sys::fs::current_path(CurrDir); + else + CurrDir = *CurrentDir; + llvm::sys::path::append(CurrDir, FName); + FName = CurrDir.c_str(); + } + auto IsEquivalent = [FName, &FS](const ResponseFileRecord &RFile) { + llvm::ErrorOr LHS = FS.status(FName); + if (!LHS) { + // TODO: The error should be propagated up the stack. + llvm::consumeError(llvm::errorCodeToError(LHS.getError())); + return false; + } + llvm::ErrorOr RHS = FS.status(RFile.File); + if (!RHS) { + // TODO: The error should be propagated up the stack. + llvm::consumeError(llvm::errorCodeToError(RHS.getError())); + return false; + } + return LHS->equivalent(*RHS); }; // Check for recursive response files. @@ -1155,10 +1184,13 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, // Replace this response file argument with the tokenization of its // contents. Nested response files are expanded in subsequent iterations. SmallVector ExpandedArgv; - if (!ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs, - RelativeNames)) { + if (llvm::Error Err = + ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs, + RelativeNames, FS)) { // We couldn't read this file, so we leave it in the argument stream and // move on. + // TODO: The error should be propagated up the stack. + llvm::consumeError(std::move(Err)); AllExpanded = false; ++I; continue; @@ -1186,9 +1218,20 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver, SmallVectorImpl &Argv) { - if (!ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv, - /*MarkEOLs*/ false, /*RelativeNames*/ true)) + SmallString<128> AbsPath; + if (sys::path::is_relative(CfgFile)) { + llvm::sys::fs::current_path(AbsPath); + llvm::sys::path::append(AbsPath, CfgFile); + CfgFile = AbsPath.str(); + } + if (llvm::Error Err = + ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv, + /*MarkEOLs*/ false, /*RelativeNames*/ true, + *llvm::vfs::getRealFileSystem())) { + // TODO: The error should be propagated up the stack. + llvm::consumeError(std::move(Err)); return false; + } return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, Argv, /*MarkEOLs*/ false, /*RelativeNames*/ true); } diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td index 15bbd365311d86..c81e60b3360a22 100644 --- a/llvm/lib/Target/ARM/ARMInstrMVE.td +++ b/llvm/lib/Target/ARM/ARMInstrMVE.td @@ -3623,8 +3623,8 @@ defm MVE_VMULLu32 : MVE_VMULL_multi<"vmull", "u32", 0b1, 0b10, "@earlyclobber $Q defm MVE_VMULLp8 : MVE_VMULL_multi<"vmull", "p8", 0b0, 0b11>; defm MVE_VMULLp16 : MVE_VMULL_multi<"vmull", "p16", 0b1, 0b11>; -class MVE_VxMULH size, - bit round, list pattern=[]> +class MVE_VxMULH size, bit round, + list pattern=[]> : MVE_qDest_qSrc { @@ -3640,19 +3640,45 @@ class MVE_VxMULH size, let Inst{0} = 0b1; } -def MVE_VMULHs8 : MVE_VxMULH<"vmulh", "s8", 0b0, 0b00, 0b0>; -def MVE_VMULHs16 : MVE_VxMULH<"vmulh", "s16", 0b0, 0b01, 0b0>; -def MVE_VMULHs32 : MVE_VxMULH<"vmulh", "s32", 0b0, 0b10, 0b0>; -def MVE_VMULHu8 : MVE_VxMULH<"vmulh", "u8", 0b1, 0b00, 0b0>; -def MVE_VMULHu16 : MVE_VxMULH<"vmulh", "u16", 0b1, 0b01, 0b0>; -def MVE_VMULHu32 : MVE_VxMULH<"vmulh", "u32", 0b1, 0b10, 0b0>; +multiclass MVE_VxMULH_m { + def "" : MVE_VxMULH; + + let Predicates = [HasMVEInt] in { + // Unpredicated multiply returning high bits + def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), + (VTI.Vec (!cast(NAME) + (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; + + // Predicated multiply returning high bits + def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), + (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), + (VTI.Vec (!cast(NAME) + (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), + ARMVCCThen, (VTI.Pred VCCR:$mask), + (VTI.Vec MQPR:$inactive)))>; + } +} -def MVE_VRMULHs8 : MVE_VxMULH<"vrmulh", "s8", 0b0, 0b00, 0b1>; -def MVE_VRMULHs16 : MVE_VxMULH<"vrmulh", "s16", 0b0, 0b01, 0b1>; -def MVE_VRMULHs32 : MVE_VxMULH<"vrmulh", "s32", 0b0, 0b10, 0b1>; -def MVE_VRMULHu8 : MVE_VxMULH<"vrmulh", "u8", 0b1, 0b00, 0b1>; -def MVE_VRMULHu16 : MVE_VxMULH<"vrmulh", "u16", 0b1, 0b01, 0b1>; -def MVE_VRMULHu32 : MVE_VxMULH<"vrmulh", "u32", 0b1, 0b10, 0b1>; +multiclass MVE_VMULT + : MVE_VxMULH_m; + +defm MVE_VMULHs8 : MVE_VMULT<"vmulh", MVE_v16s8, 0b0>; +defm MVE_VMULHs16 : MVE_VMULT<"vmulh", MVE_v8s16, 0b0>; +defm MVE_VMULHs32 : MVE_VMULT<"vmulh", MVE_v4s32, 0b0>; +defm MVE_VMULHu8 : MVE_VMULT<"vmulh", MVE_v16u8, 0b0>; +defm MVE_VMULHu16 : MVE_VMULT<"vmulh", MVE_v8u16, 0b0>; +defm MVE_VMULHu32 : MVE_VMULT<"vmulh", MVE_v4u32, 0b0>; + +defm MVE_VRMULHs8 : MVE_VMULT<"vrmulh", MVE_v16s8, 0b1>; +defm MVE_VRMULHs16 : MVE_VMULT<"vrmulh", MVE_v8s16, 0b1>; +defm MVE_VRMULHs32 : MVE_VMULT<"vrmulh", MVE_v4s32, 0b1>; +defm MVE_VRMULHu8 : MVE_VMULT<"vrmulh", MVE_v16u8, 0b1>; +defm MVE_VRMULHu16 : MVE_VMULT<"vrmulh", MVE_v8u16, 0b1>; +defm MVE_VRMULHu32 : MVE_VMULT<"vrmulh", MVE_v4u32, 0b1>; class MVE_VxMOVxN size, bit T, list pattern=[]> diff --git a/llvm/test/CodeGen/Thumb2/mve-intrinsics/vmulhq.ll b/llvm/test/CodeGen/Thumb2/mve-intrinsics/vmulhq.ll new file mode 100644 index 00000000000000..78ee17b554160c --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/mve-intrinsics/vmulhq.ll @@ -0,0 +1,92 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve.fp -verify-machineinstrs -o - %s | FileCheck %s + +define arm_aapcs_vfpcc <16 x i8> @test_vmulhq_u8(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr #0 { +; CHECK-LABEL: test_vmulhq_u8: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmulh.s8 q0, q0, q1 +; CHECK-NEXT: bx lr +entry: + %0 = tail call <16 x i8> @llvm.arm.mve.vmulh.v16i8(<16 x i8> %a, <16 x i8> %b) + ret <16 x i8> %0 +} + +declare <16 x i8> @llvm.arm.mve.vmulh.v16i8(<16 x i8>, <16 x i8>) #1 + +define arm_aapcs_vfpcc <8 x i16> @test_vmulhq_s16(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr #0 { +; CHECK-LABEL: test_vmulhq_s16: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmulh.s16 q0, q0, q1 +; CHECK-NEXT: bx lr +entry: + %0 = tail call <8 x i16> @llvm.arm.mve.vmulh.v8i16(<8 x i16> %a, <8 x i16> %b) + ret <8 x i16> %0 +} + +declare <8 x i16> @llvm.arm.mve.vmulh.v8i16(<8 x i16>, <8 x i16>) #1 + +define arm_aapcs_vfpcc <4 x i32> @test_vmulhq_u32(<4 x i32> %a, <4 x i32> %b) local_unnamed_addr #0 { +; CHECK-LABEL: test_vmulhq_u32: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmulh.s32 q0, q0, q1 +; CHECK-NEXT: bx lr +entry: + %0 = tail call <4 x i32> @llvm.arm.mve.vmulh.v4i32(<4 x i32> %a, <4 x i32> %b) + ret <4 x i32> %0 +} + +declare <4 x i32> @llvm.arm.mve.vmulh.v4i32(<4 x i32>, <4 x i32>) #1 + +define arm_aapcs_vfpcc <16 x i8> @test_vmulhq_m_s8(<16 x i8> %inactive, <16 x i8> %a, <16 x i8> %b, i16 zeroext %p) local_unnamed_addr #0 { +; CHECK-LABEL: test_vmulhq_m_s8: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmsr p0, r0 +; CHECK-NEXT: vpst +; CHECK-NEXT: vmulht.s8 q0, q1, q2 +; CHECK-NEXT: bx lr +entry: + %0 = zext i16 %p to i32 + %1 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %0) + %2 = tail call <16 x i8> @llvm.arm.mve.mulh.predicated.v16i8.v16i1(<16 x i8> %a, <16 x i8> %b, <16 x i1> %1, <16 x i8> %inactive) + ret <16 x i8> %2 +} + +declare <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32) #1 + +declare <16 x i8> @llvm.arm.mve.mulh.predicated.v16i8.v16i1(<16 x i8>, <16 x i8>, <16 x i1>, <16 x i8>) #1 + +define arm_aapcs_vfpcc <8 x i16> @test_vmulhq_m_u16(<8 x i16> %inactive, <8 x i16> %a, <8 x i16> %b, i16 zeroext %p) local_unnamed_addr #0 { +; CHECK-LABEL: test_vmulhq_m_u16: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmsr p0, r0 +; CHECK-NEXT: vpst +; CHECK-NEXT: vmulht.s16 q0, q1, q2 +; CHECK-NEXT: bx lr +entry: + %0 = zext i16 %p to i32 + %1 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %0) + %2 = tail call <8 x i16> @llvm.arm.mve.mulh.predicated.v8i16.v8i1(<8 x i16> %a, <8 x i16> %b, <8 x i1> %1, <8 x i16> %inactive) + ret <8 x i16> %2 +} + +declare <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32) #1 + +declare <8 x i16> @llvm.arm.mve.mulh.predicated.v8i16.v8i1(<8 x i16>, <8 x i16>, <8 x i1>, <8 x i16>) #1 + +define arm_aapcs_vfpcc <4 x i32> @test_vmulhq_m_s32(<4 x i32> %inactive, <4 x i32> %a, <4 x i32> %b, i16 zeroext %p) local_unnamed_addr #0 { +; CHECK-LABEL: test_vmulhq_m_s32: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmsr p0, r0 +; CHECK-NEXT: vpst +; CHECK-NEXT: vmulht.s32 q0, q1, q2 +; CHECK-NEXT: bx lr +entry: + %0 = zext i16 %p to i32 + %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0) + %2 = tail call <4 x i32> @llvm.arm.mve.mulh.predicated.v4i32.v4i1(<4 x i32> %a, <4 x i32> %b, <4 x i1> %1, <4 x i32> %inactive) + ret <4 x i32> %2 +} + +declare <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32) #1 + +declare <4 x i32> @llvm.arm.mve.mulh.predicated.v4i32.v4i1(<4 x i32>, <4 x i32>, <4 x i1>, <4 x i32>) #1 diff --git a/llvm/test/CodeGen/Thumb2/mve-intrinsics/vrmulhq.ll b/llvm/test/CodeGen/Thumb2/mve-intrinsics/vrmulhq.ll new file mode 100644 index 00000000000000..3975e4eca87274 --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/mve-intrinsics/vrmulhq.ll @@ -0,0 +1,92 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve.fp -verify-machineinstrs -o - %s | FileCheck %s + +define arm_aapcs_vfpcc <16 x i8> @test_vrmulhq_u8(<16 x i8> %a, <16 x i8> %b) local_unnamed_addr #0 { +; CHECK-LABEL: test_vrmulhq_u8: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vrmulh.s8 q0, q0, q1 +; CHECK-NEXT: bx lr +entry: + %0 = tail call <16 x i8> @llvm.arm.mve.vrmulh.v16i8(<16 x i8> %a, <16 x i8> %b) + ret <16 x i8> %0 +} + +declare <16 x i8> @llvm.arm.mve.vrmulh.v16i8(<16 x i8>, <16 x i8>) #1 + +define arm_aapcs_vfpcc <8 x i16> @test_vrmulhq_s16(<8 x i16> %a, <8 x i16> %b) local_unnamed_addr #0 { +; CHECK-LABEL: test_vrmulhq_s16: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vrmulh.s16 q0, q0, q1 +; CHECK-NEXT: bx lr +entry: + %0 = tail call <8 x i16> @llvm.arm.mve.vrmulh.v8i16(<8 x i16> %a, <8 x i16> %b) + ret <8 x i16> %0 +} + +declare <8 x i16> @llvm.arm.mve.vrmulh.v8i16(<8 x i16>, <8 x i16>) #1 + +define arm_aapcs_vfpcc <4 x i32> @test_vrmulhq_u32(<4 x i32> %a, <4 x i32> %b) local_unnamed_addr #0 { +; CHECK-LABEL: test_vrmulhq_u32: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vrmulh.s32 q0, q0, q1 +; CHECK-NEXT: bx lr +entry: + %0 = tail call <4 x i32> @llvm.arm.mve.vrmulh.v4i32(<4 x i32> %a, <4 x i32> %b) + ret <4 x i32> %0 +} + +declare <4 x i32> @llvm.arm.mve.vrmulh.v4i32(<4 x i32>, <4 x i32>) #1 + +define arm_aapcs_vfpcc <16 x i8> @test_vrmulhq_m_s8(<16 x i8> %inactive, <16 x i8> %a, <16 x i8> %b, i16 zeroext %p) local_unnamed_addr #0 { +; CHECK-LABEL: test_vrmulhq_m_s8: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmsr p0, r0 +; CHECK-NEXT: vpst +; CHECK-NEXT: vrmulht.s8 q0, q1, q2 +; CHECK-NEXT: bx lr +entry: + %0 = zext i16 %p to i32 + %1 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %0) + %2 = tail call <16 x i8> @llvm.arm.mve.rmulh.predicated.v16i8.v16i1(<16 x i8> %a, <16 x i8> %b, <16 x i1> %1, <16 x i8> %inactive) + ret <16 x i8> %2 +} + +declare <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32) #1 + +declare <16 x i8> @llvm.arm.mve.rmulh.predicated.v16i8.v16i1(<16 x i8>, <16 x i8>, <16 x i1>, <16 x i8>) #1 + +define arm_aapcs_vfpcc <8 x i16> @test_vrmulhq_m_u16(<8 x i16> %inactive, <8 x i16> %a, <8 x i16> %b, i16 zeroext %p) local_unnamed_addr #0 { +; CHECK-LABEL: test_vrmulhq_m_u16: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmsr p0, r0 +; CHECK-NEXT: vpst +; CHECK-NEXT: vrmulht.s16 q0, q1, q2 +; CHECK-NEXT: bx lr +entry: + %0 = zext i16 %p to i32 + %1 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %0) + %2 = tail call <8 x i16> @llvm.arm.mve.rmulh.predicated.v8i16.v8i1(<8 x i16> %a, <8 x i16> %b, <8 x i1> %1, <8 x i16> %inactive) + ret <8 x i16> %2 +} + +declare <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32) #1 + +declare <8 x i16> @llvm.arm.mve.rmulh.predicated.v8i16.v8i1(<8 x i16>, <8 x i16>, <8 x i1>, <8 x i16>) #1 + +define arm_aapcs_vfpcc <4 x i32> @test_vrmulhq_m_s32(<4 x i32> %inactive, <4 x i32> %a, <4 x i32> %b, i16 zeroext %p) local_unnamed_addr #0 { +; CHECK-LABEL: test_vrmulhq_m_s32: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vmsr p0, r0 +; CHECK-NEXT: vpst +; CHECK-NEXT: vrmulht.s32 q0, q1, q2 +; CHECK-NEXT: bx lr +entry: + %0 = zext i16 %p to i32 + %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0) + %2 = tail call <4 x i32> @llvm.arm.mve.rmulh.predicated.v4i32.v4i1(<4 x i32> %a, <4 x i32> %b, <4 x i1> %1, <4 x i32> %inactive) + ret <4 x i32> %2 +} + +declare <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32) #1 + +declare <4 x i32> @llvm.arm.mve.rmulh.predicated.v4i32.v4i1(<4 x i32>, <4 x i32>, <4 x i1>, <4 x i32>) #1 diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index 1948413070ae32..6adc938567633b 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -9,23 +9,33 @@ #include "llvm/Support/CommandLine.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Config/config.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Support/raw_ostream.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include #include #include +#include using namespace llvm; namespace { +MATCHER(StringEquality, "Checks if two char* are equal as strings") { + return std::string(std::get<0>(arg)) == std::string(std::get<1>(arg)); +} + class TempEnvVar { public: TempEnvVar(const char *name, const char *value) @@ -778,119 +788,90 @@ TEST(CommandLineTest, ResponseFileWindows) { } TEST(CommandLineTest, ResponseFiles) { - llvm::SmallString<128> TestDir; - std::error_code EC = - llvm::sys::fs::createUniqueDirectory("unittest", TestDir); - EXPECT_TRUE(!EC); + vfs::InMemoryFileSystem FS; + FS.setCurrentWorkingDirectory("/"); // Create included response file of first level. - llvm::SmallString<128> IncludedFileName; - llvm::sys::path::append(IncludedFileName, TestDir, "resp1"); - std::ofstream IncludedFile(IncludedFileName.c_str()); - EXPECT_TRUE(IncludedFile.is_open()); - IncludedFile << "-option_1 -option_2\n" - "@incdir/resp2\n" - "-option_3=abcd\n" - "@incdir/resp3\n" - "-option_4=efjk\n"; - IncludedFile.close(); + llvm::StringRef IncludedFileName = "resp1"; + FS.addFile(IncludedFileName, 0, + llvm::MemoryBuffer::getMemBuffer("-option_1 -option_2\n" + "@incdir/resp2\n" + "-option_3=abcd\n" + "@incdir/resp3\n" + "-option_4=efjk\n")); // Directory for included file. - llvm::SmallString<128> IncDir; - llvm::sys::path::append(IncDir, TestDir, "incdir"); - EC = llvm::sys::fs::create_directory(IncDir); - EXPECT_TRUE(!EC); + llvm::StringRef IncDir = "incdir"; // Create included response file of second level. llvm::SmallString<128> IncludedFileName2; llvm::sys::path::append(IncludedFileName2, IncDir, "resp2"); - std::ofstream IncludedFile2(IncludedFileName2.c_str()); - EXPECT_TRUE(IncludedFile2.is_open()); - IncludedFile2 << "-option_21 -option_22\n"; - IncludedFile2 << "-option_23=abcd\n"; - IncludedFile2.close(); + FS.addFile(IncludedFileName2, 0, + MemoryBuffer::getMemBuffer("-option_21 -option_22\n" + "-option_23=abcd\n")); + llvm::errs() << "Added: " << IncludedFileName2 << '\n'; // Create second included response file of second level. llvm::SmallString<128> IncludedFileName3; llvm::sys::path::append(IncludedFileName3, IncDir, "resp3"); - std::ofstream IncludedFile3(IncludedFileName3.c_str()); - EXPECT_TRUE(IncludedFile3.is_open()); - IncludedFile3 << "-option_31 -option_32\n"; - IncludedFile3 << "-option_33=abcd\n"; - IncludedFile3.close(); + FS.addFile(IncludedFileName3, 0, + MemoryBuffer::getMemBuffer("-option_31 -option_32\n" + "-option_33=abcd\n")); // Prepare 'file' with reference to response file. SmallString<128> IncRef; IncRef.append(1, '@'); - IncRef.append(IncludedFileName.c_str()); - llvm::SmallVector Argv = - { "test/test", "-flag_1", IncRef.c_str(), "-flag_2" }; + IncRef.append(IncludedFileName); + llvm::SmallVector Argv = {"test/test", "-flag_1", + IncRef.c_str(), "-flag_2"}; // Expand response files. llvm::BumpPtrAllocator A; llvm::StringSaver Saver(A); - bool Res = llvm::cl::ExpandResponseFiles( - Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true); - EXPECT_TRUE(Res); - EXPECT_EQ(Argv.size(), 13U); - EXPECT_STREQ(Argv[0], "test/test"); - EXPECT_STREQ(Argv[1], "-flag_1"); - EXPECT_STREQ(Argv[2], "-option_1"); - EXPECT_STREQ(Argv[3], "-option_2"); - EXPECT_STREQ(Argv[4], "-option_21"); - EXPECT_STREQ(Argv[5], "-option_22"); - EXPECT_STREQ(Argv[6], "-option_23=abcd"); - EXPECT_STREQ(Argv[7], "-option_3=abcd"); - EXPECT_STREQ(Argv[8], "-option_31"); - EXPECT_STREQ(Argv[9], "-option_32"); - EXPECT_STREQ(Argv[10], "-option_33=abcd"); - EXPECT_STREQ(Argv[11], "-option_4=efjk"); - EXPECT_STREQ(Argv[12], "-flag_2"); - - llvm::sys::fs::remove(IncludedFileName3); - llvm::sys::fs::remove(IncludedFileName2); - llvm::sys::fs::remove(IncDir); - llvm::sys::fs::remove(IncludedFileName); - llvm::sys::fs::remove(TestDir); + ASSERT_TRUE(llvm::cl::ExpandResponseFiles( + Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true, FS, + /*CurrentDir=*/StringRef("/"))); + EXPECT_THAT(Argv, testing::Pointwise( + StringEquality(), + {"test/test", "-flag_1", "-option_1", "-option_2", + "-option_21", "-option_22", "-option_23=abcd", + "-option_3=abcd", "-option_31", "-option_32", + "-option_33=abcd", "-option_4=efjk", "-flag_2"})); } TEST(CommandLineTest, RecursiveResponseFiles) { - SmallString<128> TestDir; - std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir); - EXPECT_TRUE(!EC); + vfs::InMemoryFileSystem FS; + FS.setCurrentWorkingDirectory("/"); - SmallString<128> SelfFilePath; - sys::path::append(SelfFilePath, TestDir, "self.rsp"); - std::string SelfFileRef = std::string("@") + SelfFilePath.c_str(); + StringRef SelfFilePath = "self.rsp"; + std::string SelfFileRef = ("@" + SelfFilePath).str(); - SmallString<128> NestedFilePath; - sys::path::append(NestedFilePath, TestDir, "nested.rsp"); - std::string NestedFileRef = std::string("@") + NestedFilePath.c_str(); + StringRef NestedFilePath = "nested.rsp"; + std::string NestedFileRef = ("@" + NestedFilePath).str(); - SmallString<128> FlagFilePath; - sys::path::append(FlagFilePath, TestDir, "flag.rsp"); - std::string FlagFileRef = std::string("@") + FlagFilePath.c_str(); + StringRef FlagFilePath = "flag.rsp"; + std::string FlagFileRef = ("@" + FlagFilePath).str(); - std::ofstream SelfFile(SelfFilePath.str()); - EXPECT_TRUE(SelfFile.is_open()); + std::string SelfFileContents; + raw_string_ostream SelfFile(SelfFileContents); SelfFile << "-option_1\n"; SelfFile << FlagFileRef << "\n"; SelfFile << NestedFileRef << "\n"; SelfFile << SelfFileRef << "\n"; - SelfFile.close(); + FS.addFile(SelfFilePath, 0, MemoryBuffer::getMemBuffer(SelfFile.str())); - std::ofstream NestedFile(NestedFilePath.str()); - EXPECT_TRUE(NestedFile.is_open()); + std::string NestedFileContents; + raw_string_ostream NestedFile(NestedFileContents); NestedFile << "-option_2\n"; NestedFile << FlagFileRef << "\n"; NestedFile << SelfFileRef << "\n"; NestedFile << NestedFileRef << "\n"; - NestedFile.close(); + FS.addFile(NestedFilePath, 0, MemoryBuffer::getMemBuffer(NestedFile.str())); - std::ofstream FlagFile(FlagFilePath.str()); - EXPECT_TRUE(FlagFile.is_open()); + std::string FlagFileContents; + raw_string_ostream FlagFile(FlagFileContents); FlagFile << "-option_x\n"; - FlagFile.close(); + FS.addFile(FlagFilePath, 0, MemoryBuffer::getMemBuffer(FlagFile.str())); // Ensure: // Recursive expansion terminates @@ -905,47 +886,42 @@ TEST(CommandLineTest, RecursiveResponseFiles) { #else cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine; #endif - bool Res = cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false); - EXPECT_FALSE(Res); - - EXPECT_EQ(Argv.size(), 9U); - EXPECT_STREQ(Argv[0], "test/test"); - EXPECT_STREQ(Argv[1], "-option_1"); - EXPECT_STREQ(Argv[2], "-option_x"); - EXPECT_STREQ(Argv[3], "-option_2"); - EXPECT_STREQ(Argv[4], "-option_x"); - EXPECT_STREQ(Argv[5], SelfFileRef.c_str()); - EXPECT_STREQ(Argv[6], NestedFileRef.c_str()); - EXPECT_STREQ(Argv[7], SelfFileRef.c_str()); - EXPECT_STREQ(Argv[8], "-option_3"); + ASSERT_FALSE(cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, FS, + /*CurrentDir=*/llvm::StringRef("/"))); + + EXPECT_THAT(Argv, + testing::Pointwise(StringEquality(), + {"test/test", "-option_1", "-option_x", + "-option_2", "-option_x", SelfFileRef.c_str(), + NestedFileRef.c_str(), SelfFileRef.c_str(), + "-option_3"})); } TEST(CommandLineTest, ResponseFilesAtArguments) { - SmallString<128> TestDir; - std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir); - EXPECT_TRUE(!EC); + vfs::InMemoryFileSystem FS; + FS.setCurrentWorkingDirectory("/"); - SmallString<128> ResponseFilePath; - sys::path::append(ResponseFilePath, TestDir, "test.rsp"); + StringRef ResponseFilePath = "test.rsp"; - std::ofstream ResponseFile(ResponseFilePath.c_str()); - EXPECT_TRUE(ResponseFile.is_open()); + std::string ResponseFileContents; + raw_string_ostream ResponseFile(ResponseFileContents); ResponseFile << "-foo" << "\n"; ResponseFile << "-bar" << "\n"; - ResponseFile.close(); + FS.addFile(ResponseFilePath, 0, + MemoryBuffer::getMemBuffer(ResponseFile.str())); // Ensure we expand rsp files after lots of non-rsp arguments starting with @. constexpr size_t NON_RSP_AT_ARGS = 64; SmallVector Argv = {"test/test"}; Argv.append(NON_RSP_AT_ARGS, "@non_rsp_at_arg"); - std::string ResponseFileRef = std::string("@") + ResponseFilePath.c_str(); + std::string ResponseFileRef = ("@" + ResponseFilePath).str(); Argv.push_back(ResponseFileRef.c_str()); BumpPtrAllocator A; StringSaver Saver(A); - bool Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv, - false, false); - EXPECT_FALSE(Res); + ASSERT_FALSE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv, + false, false, FS, + /*CurrentDir=*/StringRef("/"))); // ASSERT instead of EXPECT to prevent potential out-of-bounds access. ASSERT_EQ(Argv.size(), 1 + NON_RSP_AT_ARGS + 2); @@ -957,6 +933,28 @@ TEST(CommandLineTest, ResponseFilesAtArguments) { EXPECT_STREQ(Argv[i++], "-bar"); } +TEST(CommandLineTest, ResponseFileRelativePath) { + vfs::InMemoryFileSystem FS; + + StringRef OuterFile = "//net/dir/outer.rsp"; + StringRef OuterFileContents = "@inner.rsp"; + FS.addFile(OuterFile, 0, MemoryBuffer::getMemBuffer(OuterFileContents)); + + StringRef InnerFile = "//net/dir/inner.rsp"; + StringRef InnerFileContents = "-flag"; + FS.addFile(InnerFile, 0, MemoryBuffer::getMemBuffer(InnerFileContents)); + + SmallVector Argv = {"test/test", "@dir/outer.rsp"}; + + BumpPtrAllocator A; + StringSaver Saver(A); + ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv, + false, true, FS, + /*CurrentDir=*/StringRef("//net"))); + EXPECT_THAT(Argv, + testing::Pointwise(StringEquality(), {"test/test", "-flag"})); +} + TEST(CommandLineTest, SetDefautValue) { cl::ResetCommandLineParser(); diff --git a/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn index 8c1d5e1a030a81..5bc4241e474c04 100644 --- a/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn @@ -19,6 +19,7 @@ static_library("Tooling") { "CommonOptionsParser.cpp", "CompilationDatabase.cpp", "Execution.cpp", + "ExpandResponseFilesCompilationDatabase.cpp", "FileMatchTrie.cpp", "FixIt.cpp", "GuessTargetAndModeCompilationDatabase.cpp",