diff --git a/llvm/lib/Target/SPIRV/SPIRVAPI.cpp b/llvm/lib/Target/SPIRV/SPIRVAPI.cpp index 95c9b0e520060..4da9cde2c79c0 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAPI.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAPI.cpp @@ -31,6 +31,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/TargetParser/Triple.h" +#include #include #include #include @@ -47,6 +48,7 @@ static cl::opt SpirvOptLevel("spirv-O", cl::Hidden, cl::Prefix, static cl::opt SpirvTargetTriple("spirv-mtriple", cl::Hidden, cl::init("")); +std::mutex MParseOpts; // Utility to accept options in a command line style. void parseSPIRVCommandLineOptions(const std::vector &Options, raw_ostream *Errs) { @@ -55,7 +57,16 @@ void parseSPIRVCommandLineOptions(const std::vector &Options, std::vector Argv(1, Origin); for (const auto &Arg : Options) Argv.push_back(Arg.c_str()); - cl::ParseCommandLineOptions(Argv.size(), Argv.data(), Origin, Errs); + { + const std::lock_guard LParseOpts(MParseOpts); + // Reset previous run and parse in a thread-safe manner. + cl::ResetAllOptionOccurrences(); + cl::ParseCommandLineOptions(Argv.size(), Argv.data(), Origin, Errs); + } + } else { + const std::lock_guard LParseOpts(MParseOpts); + // Reset previous run. + cl::ResetAllOptionOccurrences(); } } diff --git a/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp b/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp index f0b4a2f55c151..60458f8652132 100644 --- a/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp +++ b/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp @@ -92,18 +92,29 @@ TEST_F(SPIRVAPITest, checkTranslateOk) { } TEST_F(SPIRVAPITest, checkTranslateError) { - std::string Result, Error; - bool Status = toSpirv(OkAssembly, Result, Error, {}, - {"-mtriple=spirv32-unknown-unknown"}); - EXPECT_FALSE(Status); - EXPECT_TRUE(Result.empty()); - EXPECT_THAT(Error, - StartsWith("SPIRVTranslateModule: Unknown command line argument " - "'-mtriple=spirv32-unknown-unknown'")); - Status = toSpirv(OkAssembly, Result, Error, {}, {"--spirv-O 5"}); - EXPECT_FALSE(Status); - EXPECT_TRUE(Result.empty()); - EXPECT_EQ(Error, "Invalid optimization level!"); + { + std::string Result, Error; + bool Status = toSpirv(OkAssembly, Result, Error, {}, + {"-mtriple=spirv32-unknown-unknown"}); + EXPECT_FALSE(Status); + EXPECT_TRUE(Result.empty()); + EXPECT_THAT( + Error, StartsWith("SPIRVTranslateModule: Unknown command line argument " + "'-mtriple=spirv32-unknown-unknown'")); + } + { + std::string Result, Error; + bool Status = toSpirv(OkAssembly, Result, Error, {}, {"--spirv-O 5"}); + EXPECT_FALSE(Status); + EXPECT_TRUE(Result.empty()); + EXPECT_EQ(Error, "Invalid optimization level!"); + } + { + std::string Result, Error; + bool Status = toSpirv(OkAssembly, Result, Error, {}, {}); + EXPECT_TRUE(Status && Error.empty() && !Result.empty()); + EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); + } } TEST_F(SPIRVAPITest, checkTranslateSupportExtensionByOpts) {