xref: /llvm-project/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp (revision df122fc734ce002632f3bfe8a5fc5010349dba16)
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