1bca2b6d2SVyacheslav Levytskyy //===- llvm/unittest/CodeGen/SPIRVAPITest.cpp -----------------------------===// 2bca2b6d2SVyacheslav Levytskyy // 3bca2b6d2SVyacheslav Levytskyy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bca2b6d2SVyacheslav Levytskyy // See https://llvm.org/LICENSE.txt for license information. 5bca2b6d2SVyacheslav Levytskyy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bca2b6d2SVyacheslav Levytskyy // 7bca2b6d2SVyacheslav Levytskyy //===----------------------------------------------------------------------===// 8bca2b6d2SVyacheslav Levytskyy // 9bca2b6d2SVyacheslav Levytskyy /// \file 10bca2b6d2SVyacheslav Levytskyy /// Test that SPIR-V Backend provides an API call that translates LLVM IR Module 11bca2b6d2SVyacheslav Levytskyy /// into SPIR-V. 12bca2b6d2SVyacheslav Levytskyy // 13bca2b6d2SVyacheslav Levytskyy //===----------------------------------------------------------------------===// 14bca2b6d2SVyacheslav Levytskyy 15bca2b6d2SVyacheslav Levytskyy #include "llvm/AsmParser/Parser.h" 16bca2b6d2SVyacheslav Levytskyy #include "llvm/BinaryFormat/Magic.h" 17bca2b6d2SVyacheslav Levytskyy #include "llvm/IR/Module.h" 18bca2b6d2SVyacheslav Levytskyy #include "llvm/Support/SourceMgr.h" 19*df122fc7SVyacheslav Levytskyy #include "llvm/TargetParser/Triple.h" 20bca2b6d2SVyacheslav Levytskyy #include "gtest/gtest.h" 21bca2b6d2SVyacheslav Levytskyy #include <gmock/gmock.h> 22bca2b6d2SVyacheslav Levytskyy #include <string> 23bca2b6d2SVyacheslav Levytskyy #include <utility> 24bca2b6d2SVyacheslav Levytskyy 25bca2b6d2SVyacheslav Levytskyy using ::testing::StartsWith; 26bca2b6d2SVyacheslav Levytskyy 27bca2b6d2SVyacheslav Levytskyy namespace llvm { 28bca2b6d2SVyacheslav Levytskyy 29*df122fc7SVyacheslav Levytskyy extern "C" LLVM_EXTERNAL_VISIBILITY bool 30*df122fc7SVyacheslav Levytskyy SPIRVTranslate(Module *M, std::string &SpirvObj, std::string &ErrMsg, 31*df122fc7SVyacheslav Levytskyy const std::vector<std::string> &AllowExtNames, 32*df122fc7SVyacheslav Levytskyy llvm::CodeGenOptLevel OLevel, Triple TargetTriple); 33*df122fc7SVyacheslav Levytskyy 34bca2b6d2SVyacheslav Levytskyy extern "C" bool 35bca2b6d2SVyacheslav Levytskyy SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg, 36bca2b6d2SVyacheslav Levytskyy const std::vector<std::string> &AllowExtNames, 37bca2b6d2SVyacheslav Levytskyy const std::vector<std::string> &Opts); 38bca2b6d2SVyacheslav Levytskyy 39bca2b6d2SVyacheslav Levytskyy class SPIRVAPITest : public testing::Test { 40bca2b6d2SVyacheslav Levytskyy protected: 41bca2b6d2SVyacheslav Levytskyy bool toSpirv(StringRef Assembly, std::string &Result, std::string &ErrMsg, 42bca2b6d2SVyacheslav Levytskyy const std::vector<std::string> &AllowExtNames, 43*df122fc7SVyacheslav Levytskyy llvm::CodeGenOptLevel OLevel, Triple TargetTriple) { 44*df122fc7SVyacheslav Levytskyy SMDiagnostic ParseError; 45*df122fc7SVyacheslav Levytskyy LLVMContext Context; 46*df122fc7SVyacheslav Levytskyy std::unique_ptr<Module> M = 47*df122fc7SVyacheslav Levytskyy parseAssemblyString(Assembly, ParseError, Context); 48*df122fc7SVyacheslav Levytskyy if (!M) { 49*df122fc7SVyacheslav Levytskyy ParseError.print("IR parsing failed: ", errs()); 50*df122fc7SVyacheslav Levytskyy report_fatal_error("Can't parse input assembly."); 51*df122fc7SVyacheslav Levytskyy } 52*df122fc7SVyacheslav Levytskyy bool Status = SPIRVTranslate(M.get(), Result, ErrMsg, AllowExtNames, OLevel, 53*df122fc7SVyacheslav Levytskyy TargetTriple); 54*df122fc7SVyacheslav Levytskyy if (!Status) 55*df122fc7SVyacheslav Levytskyy errs() << ErrMsg; 56*df122fc7SVyacheslav Levytskyy return Status; 57*df122fc7SVyacheslav Levytskyy } 58*df122fc7SVyacheslav Levytskyy // TODO: Remove toSpirvLegacy() and related tests after existing clients 59*df122fc7SVyacheslav Levytskyy // switch into a newer implementation of SPIRVTranslate(). 60*df122fc7SVyacheslav Levytskyy bool toSpirvLegacy(StringRef Assembly, std::string &Result, 61*df122fc7SVyacheslav Levytskyy std::string &ErrMsg, 62*df122fc7SVyacheslav Levytskyy const std::vector<std::string> &AllowExtNames, 63bca2b6d2SVyacheslav Levytskyy const std::vector<std::string> &Opts) { 64bca2b6d2SVyacheslav Levytskyy SMDiagnostic ParseError; 653ff9368eSVyacheslav Levytskyy LLVMContext Context; 663ff9368eSVyacheslav Levytskyy std::unique_ptr<Module> M = 673ff9368eSVyacheslav Levytskyy parseAssemblyString(Assembly, ParseError, Context); 68bca2b6d2SVyacheslav Levytskyy if (!M) { 69bca2b6d2SVyacheslav Levytskyy ParseError.print("IR parsing failed: ", errs()); 70bca2b6d2SVyacheslav Levytskyy report_fatal_error("Can't parse input assembly."); 71bca2b6d2SVyacheslav Levytskyy } 72bca2b6d2SVyacheslav Levytskyy bool Status = 73bca2b6d2SVyacheslav Levytskyy SPIRVTranslateModule(M.get(), Result, ErrMsg, AllowExtNames, Opts); 74bca2b6d2SVyacheslav Levytskyy if (!Status) 75bca2b6d2SVyacheslav Levytskyy errs() << ErrMsg; 76bca2b6d2SVyacheslav Levytskyy return Status; 77bca2b6d2SVyacheslav Levytskyy } 78bca2b6d2SVyacheslav Levytskyy 79bca2b6d2SVyacheslav Levytskyy static constexpr StringRef ExtensionAssembly = R"( 80bca2b6d2SVyacheslav Levytskyy define dso_local spir_func void @test1() { 81bca2b6d2SVyacheslav Levytskyy entry: 82bca2b6d2SVyacheslav Levytskyy %res1 = tail call spir_func i32 @_Z26__spirv_GroupBitwiseAndKHR(i32 2, i32 0, i32 0) 83bca2b6d2SVyacheslav Levytskyy ret void 84bca2b6d2SVyacheslav Levytskyy } 85bca2b6d2SVyacheslav Levytskyy 86bca2b6d2SVyacheslav Levytskyy declare dso_local spir_func i32 @_Z26__spirv_GroupBitwiseAndKHR(i32, i32, i32) 87bca2b6d2SVyacheslav Levytskyy )"; 88bca2b6d2SVyacheslav Levytskyy static constexpr StringRef OkAssembly = R"( 89bca2b6d2SVyacheslav Levytskyy %struct = type { [1 x i64] } 90bca2b6d2SVyacheslav Levytskyy 91bca2b6d2SVyacheslav Levytskyy define spir_kernel void @foo(ptr noundef byval(%struct) %arg) { 92bca2b6d2SVyacheslav Levytskyy entry: 93bca2b6d2SVyacheslav Levytskyy call spir_func void @bar(<2 x i32> noundef <i32 0, i32 1>) 94bca2b6d2SVyacheslav Levytskyy ret void 95bca2b6d2SVyacheslav Levytskyy } 96bca2b6d2SVyacheslav Levytskyy 97bca2b6d2SVyacheslav Levytskyy define spir_func void @bar(<2 x i32> noundef) { 98bca2b6d2SVyacheslav Levytskyy entry: 99bca2b6d2SVyacheslav Levytskyy ret void 100bca2b6d2SVyacheslav Levytskyy } 101bca2b6d2SVyacheslav Levytskyy )"; 102bca2b6d2SVyacheslav Levytskyy }; 103bca2b6d2SVyacheslav Levytskyy 104bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateOk) { 105bca2b6d2SVyacheslav Levytskyy StringRef Assemblies[] = {"", OkAssembly}; 106bca2b6d2SVyacheslav Levytskyy for (StringRef &Assembly : Assemblies) { 107bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 108*df122fc7SVyacheslav Levytskyy bool Status = toSpirv(Assembly, Result, Error, {}, CodeGenOptLevel::Default, 109*df122fc7SVyacheslav Levytskyy Triple("spirv32-unknown-unknown")); 110bca2b6d2SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 111bca2b6d2SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 112bca2b6d2SVyacheslav Levytskyy } 113bca2b6d2SVyacheslav Levytskyy } 114bca2b6d2SVyacheslav Levytskyy 115bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateSupportExtensionByArg) { 116bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 117bca2b6d2SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_KHR_uniform_group_instructions"}; 118*df122fc7SVyacheslav Levytskyy bool Status = 119*df122fc7SVyacheslav Levytskyy toSpirv(ExtensionAssembly, Result, Error, ExtNames, 120*df122fc7SVyacheslav Levytskyy CodeGenOptLevel::Aggressive, Triple("spirv64-unknown-unknown")); 121bca2b6d2SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 122bca2b6d2SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 123bca2b6d2SVyacheslav Levytskyy } 124bca2b6d2SVyacheslav Levytskyy 125bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateSupportExtensionByArgList) { 126bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 127bca2b6d2SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_KHR_subgroup_rotate", 128bca2b6d2SVyacheslav Levytskyy "SPV_KHR_uniform_group_instructions", 129bca2b6d2SVyacheslav Levytskyy "SPV_KHR_subgroup_rotate"}; 130*df122fc7SVyacheslav Levytskyy bool Status = 131*df122fc7SVyacheslav Levytskyy toSpirv(ExtensionAssembly, Result, Error, ExtNames, 132*df122fc7SVyacheslav Levytskyy CodeGenOptLevel::Aggressive, Triple("spirv64-unknown-unknown")); 133bca2b6d2SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 134bca2b6d2SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 135bca2b6d2SVyacheslav Levytskyy } 136bca2b6d2SVyacheslav Levytskyy 137bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateAllExtensions) { 138bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 139*df122fc7SVyacheslav Levytskyy std::vector<std::string> ExtNames{"all"}; 140*df122fc7SVyacheslav Levytskyy bool Status = 141*df122fc7SVyacheslav Levytskyy toSpirv(ExtensionAssembly, Result, Error, ExtNames, 142*df122fc7SVyacheslav Levytskyy CodeGenOptLevel::Aggressive, Triple("spirv64-unknown-unknown")); 143bca2b6d2SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 144bca2b6d2SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 145bca2b6d2SVyacheslav Levytskyy } 146bca2b6d2SVyacheslav Levytskyy 147bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateUnknownExtensionByArg) { 148bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 149bca2b6d2SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_XYZ_my_unknown_extension"}; 150*df122fc7SVyacheslav Levytskyy bool Status = 151*df122fc7SVyacheslav Levytskyy toSpirv(ExtensionAssembly, Result, Error, ExtNames, 152*df122fc7SVyacheslav Levytskyy CodeGenOptLevel::Aggressive, Triple("spirv64-unknown-unknown")); 153bca2b6d2SVyacheslav Levytskyy EXPECT_FALSE(Status); 154bca2b6d2SVyacheslav Levytskyy EXPECT_TRUE(Result.empty()); 155bca2b6d2SVyacheslav Levytskyy EXPECT_EQ(Error, "Unknown SPIR-V extension: SPV_XYZ_my_unknown_extension"); 156bca2b6d2SVyacheslav Levytskyy } 157bca2b6d2SVyacheslav Levytskyy 158bca2b6d2SVyacheslav Levytskyy #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 159bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateExtensionError) { 160bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 161bca2b6d2SVyacheslav Levytskyy EXPECT_DEATH_IF_SUPPORTED( 162*df122fc7SVyacheslav Levytskyy { 163*df122fc7SVyacheslav Levytskyy toSpirv(ExtensionAssembly, Result, Error, {}, 164*df122fc7SVyacheslav Levytskyy CodeGenOptLevel::Aggressive, Triple("spirv64-unknown-unknown")); 165*df122fc7SVyacheslav Levytskyy }, 166bca2b6d2SVyacheslav Levytskyy "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the " 167bca2b6d2SVyacheslav Levytskyy "following SPIR-V extension: SPV_KHR_uniform_group_instructions"); 168bca2b6d2SVyacheslav Levytskyy } 169bca2b6d2SVyacheslav Levytskyy 170bca2b6d2SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateWrongExtensionByArg) { 171bca2b6d2SVyacheslav Levytskyy std::string Result, Error; 172bca2b6d2SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_KHR_subgroup_rotate"}; 173bca2b6d2SVyacheslav Levytskyy EXPECT_DEATH_IF_SUPPORTED( 174*df122fc7SVyacheslav Levytskyy { 175*df122fc7SVyacheslav Levytskyy toSpirv(ExtensionAssembly, Result, Error, ExtNames, 176*df122fc7SVyacheslav Levytskyy CodeGenOptLevel::Aggressive, Triple("spirv64-unknown-unknown")); 177*df122fc7SVyacheslav Levytskyy }, 178*df122fc7SVyacheslav Levytskyy "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the " 179*df122fc7SVyacheslav Levytskyy "following SPIR-V extension: SPV_KHR_uniform_group_instructions"); 180*df122fc7SVyacheslav Levytskyy } 181*df122fc7SVyacheslav Levytskyy #endif 182*df122fc7SVyacheslav Levytskyy 183*df122fc7SVyacheslav Levytskyy // Legacy API calls. TODO: Remove after transition into a newer API. 184*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsOk) { 185*df122fc7SVyacheslav Levytskyy StringRef Assemblies[] = {"", OkAssembly}; 186*df122fc7SVyacheslav Levytskyy std::vector<std::string> SetOfOpts[] = {{}, {"spirv32-unknown-unknown"}}; 187*df122fc7SVyacheslav Levytskyy for (const auto &Opts : SetOfOpts) { 188*df122fc7SVyacheslav Levytskyy for (StringRef &Assembly : Assemblies) { 189*df122fc7SVyacheslav Levytskyy std::string Result, Error; 190*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(Assembly, Result, Error, {}, Opts); 191*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 192*df122fc7SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 193*df122fc7SVyacheslav Levytskyy } 194*df122fc7SVyacheslav Levytskyy } 195*df122fc7SVyacheslav Levytskyy } 196*df122fc7SVyacheslav Levytskyy 197*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsError) { 198*df122fc7SVyacheslav Levytskyy std::string Result, Error; 199*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(OkAssembly, Result, Error, {}, 200*df122fc7SVyacheslav Levytskyy {"spirv64v1.6-unknown-unknown", "5"}); 201*df122fc7SVyacheslav Levytskyy EXPECT_FALSE(Status); 202*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Result.empty()); 203*df122fc7SVyacheslav Levytskyy EXPECT_EQ(Error, "Invalid optimization level!"); 204*df122fc7SVyacheslav Levytskyy } 205*df122fc7SVyacheslav Levytskyy 206*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsErrorOk) { 207*df122fc7SVyacheslav Levytskyy { 208*df122fc7SVyacheslav Levytskyy std::string Result, Error; 209*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(OkAssembly, Result, Error, {}, 210*df122fc7SVyacheslav Levytskyy {"spirv64v1.6-unknown-unknown", "5"}); 211*df122fc7SVyacheslav Levytskyy EXPECT_FALSE(Status); 212*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Result.empty()); 213*df122fc7SVyacheslav Levytskyy EXPECT_EQ(Error, "Invalid optimization level!"); 214*df122fc7SVyacheslav Levytskyy } 215*df122fc7SVyacheslav Levytskyy { 216*df122fc7SVyacheslav Levytskyy std::string Result, Error; 217*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(OkAssembly, Result, Error, {}, 218*df122fc7SVyacheslav Levytskyy {"spirv64v1.6-unknown-unknown", "3"}); 219*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 220*df122fc7SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 221*df122fc7SVyacheslav Levytskyy } 222*df122fc7SVyacheslav Levytskyy } 223*df122fc7SVyacheslav Levytskyy 224*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsSupportExtensionByArg) { 225*df122fc7SVyacheslav Levytskyy std::string Result, Error; 226*df122fc7SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_KHR_uniform_group_instructions"}; 227*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(ExtensionAssembly, Result, Error, ExtNames, {}); 228*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 229*df122fc7SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 230*df122fc7SVyacheslav Levytskyy } 231*df122fc7SVyacheslav Levytskyy 232*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsSupportExtensionByArgList) { 233*df122fc7SVyacheslav Levytskyy std::string Result, Error; 234*df122fc7SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_KHR_subgroup_rotate", 235*df122fc7SVyacheslav Levytskyy "SPV_KHR_uniform_group_instructions", 236*df122fc7SVyacheslav Levytskyy "SPV_KHR_subgroup_rotate"}; 237*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(ExtensionAssembly, Result, Error, ExtNames, {}); 238*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 239*df122fc7SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 240*df122fc7SVyacheslav Levytskyy } 241*df122fc7SVyacheslav Levytskyy 242*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsAllExtensions) { 243*df122fc7SVyacheslav Levytskyy std::string Result, Error; 244*df122fc7SVyacheslav Levytskyy std::vector<std::string> ExtNames{"all"}; 245*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(ExtensionAssembly, Result, Error, ExtNames, {}); 246*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Status && Error.empty() && !Result.empty()); 247*df122fc7SVyacheslav Levytskyy EXPECT_EQ(identify_magic(Result), file_magic::spirv_object); 248*df122fc7SVyacheslav Levytskyy } 249*df122fc7SVyacheslav Levytskyy 250*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsUnknownExtensionByArg) { 251*df122fc7SVyacheslav Levytskyy std::string Result, Error; 252*df122fc7SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_XYZ_my_unknown_extension"}; 253*df122fc7SVyacheslav Levytskyy bool Status = toSpirvLegacy(ExtensionAssembly, Result, Error, ExtNames, {}); 254*df122fc7SVyacheslav Levytskyy EXPECT_FALSE(Status); 255*df122fc7SVyacheslav Levytskyy EXPECT_TRUE(Result.empty()); 256*df122fc7SVyacheslav Levytskyy EXPECT_EQ(Error, "Unknown SPIR-V extension: SPV_XYZ_my_unknown_extension"); 257*df122fc7SVyacheslav Levytskyy } 258*df122fc7SVyacheslav Levytskyy 259*df122fc7SVyacheslav Levytskyy #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 260*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsExtensionError) { 261*df122fc7SVyacheslav Levytskyy std::string Result, Error; 262*df122fc7SVyacheslav Levytskyy EXPECT_DEATH_IF_SUPPORTED( 263*df122fc7SVyacheslav Levytskyy { toSpirvLegacy(ExtensionAssembly, Result, Error, {}, {}); }, 264*df122fc7SVyacheslav Levytskyy "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the " 265*df122fc7SVyacheslav Levytskyy "following SPIR-V extension: SPV_KHR_uniform_group_instructions"); 266*df122fc7SVyacheslav Levytskyy } 267*df122fc7SVyacheslav Levytskyy 268*df122fc7SVyacheslav Levytskyy TEST_F(SPIRVAPITest, checkTranslateStringOptsWrongExtensionByArg) { 269*df122fc7SVyacheslav Levytskyy std::string Result, Error; 270*df122fc7SVyacheslav Levytskyy std::vector<std::string> ExtNames{"SPV_KHR_subgroup_rotate"}; 271*df122fc7SVyacheslav Levytskyy EXPECT_DEATH_IF_SUPPORTED( 272*df122fc7SVyacheslav Levytskyy { toSpirvLegacy(ExtensionAssembly, Result, Error, ExtNames, {}); }, 273bca2b6d2SVyacheslav Levytskyy "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the " 274bca2b6d2SVyacheslav Levytskyy "following SPIR-V extension: SPV_KHR_uniform_group_instructions"); 275bca2b6d2SVyacheslav Levytskyy } 276bca2b6d2SVyacheslav Levytskyy #endif 277bca2b6d2SVyacheslav Levytskyy 278bca2b6d2SVyacheslav Levytskyy } // end namespace llvm 279