[Clang][MIPS] Send correct architecture for MinGW toolchains (#121042)
[llvm-project.git] / llvm / unittests / Target / SPIRV / SPIRVAPITest.cpp
blob27ea8b8cf06e8d3ce9c52b24eda76a003bacd989
1 //===- llvm/unittest/CodeGen/SPIRVAPITest.cpp -----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Test that SPIR-V Backend provides an API call that translates LLVM IR Module
11 /// into SPIR-V.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/AsmParser/Parser.h"
16 #include "llvm/BinaryFormat/Magic.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "gtest/gtest.h"
20 #include <gmock/gmock.h>
21 #include <string>
22 #include <utility>
24 using ::testing::StartsWith;
26 namespace llvm {
28 extern "C" bool
29 SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg,
30 const std::vector<std::string> &AllowExtNames,
31 const std::vector<std::string> &Opts);
33 class SPIRVAPITest : public testing::Test {
34 protected:
35 bool toSpirv(StringRef Assembly, std::string &Result, std::string &ErrMsg,
36 const std::vector<std::string> &AllowExtNames,
37 const std::vector<std::string> &Opts) {
38 SMDiagnostic ParseError;
39 M = parseAssemblyString(Assembly, ParseError, Context);
40 if (!M) {
41 ParseError.print("IR parsing failed: ", errs());
42 report_fatal_error("Can't parse input assembly.");
44 bool Status =
45 SPIRVTranslateModule(M.get(), Result, ErrMsg, AllowExtNames, Opts);
46 if (!Status)
47 errs() << ErrMsg;
48 return Status;
51 LLVMContext Context;
52 std::unique_ptr<Module> M;
54 static constexpr StringRef ExtensionAssembly = R"(
55 define dso_local spir_func void @test1() {
56 entry:
57 %res1 = tail call spir_func i32 @_Z26__spirv_GroupBitwiseAndKHR(i32 2, i32 0, i32 0)
58 ret void
61 declare dso_local spir_func i32 @_Z26__spirv_GroupBitwiseAndKHR(i32, i32, i32)
62 )";
63 static constexpr StringRef OkAssembly = R"(
64 %struct = type { [1 x i64] }
66 define spir_kernel void @foo(ptr noundef byval(%struct) %arg) {
67 entry:
68 call spir_func void @bar(<2 x i32> noundef <i32 0, i32 1>)
69 ret void
72 define spir_func void @bar(<2 x i32> noundef) {
73 entry:
74 ret void
76 )";
79 TEST_F(SPIRVAPITest, checkTranslateOk) {
80 StringRef Assemblies[] = {"", OkAssembly};
81 // Those command line arguments that overlap with registered by llc/codegen
82 // are to be started with the ' ' symbol.
83 std::vector<std::string> SetOfOpts[] = {
84 {}, {"- mtriple=spirv32-unknown-unknown"}};
85 for (const auto &Opts : SetOfOpts) {
86 for (StringRef &Assembly : Assemblies) {
87 std::string Result, Error;
88 bool Status = toSpirv(Assembly, Result, Error, {}, Opts);
89 EXPECT_TRUE(Status && Error.empty() && !Result.empty());
90 EXPECT_EQ(identify_magic(Result), file_magic::spirv_object);
95 TEST_F(SPIRVAPITest, checkTranslateError) {
96 std::string Result, Error;
97 bool Status = toSpirv(OkAssembly, Result, Error, {},
98 {"-mtriple=spirv32-unknown-unknown"});
99 EXPECT_FALSE(Status);
100 EXPECT_TRUE(Result.empty());
101 EXPECT_THAT(Error,
102 StartsWith("SPIRVTranslateModule: Unknown command line argument "
103 "'-mtriple=spirv32-unknown-unknown'"));
104 Status = toSpirv(OkAssembly, Result, Error, {}, {"- O 5"});
105 EXPECT_FALSE(Status);
106 EXPECT_TRUE(Result.empty());
107 EXPECT_EQ(Error, "Invalid optimization level!");
110 TEST_F(SPIRVAPITest, checkTranslateSupportExtensionByOpts) {
111 std::string Result, Error;
112 std::vector<std::string> Opts{
113 "--spirv-ext=+SPV_KHR_uniform_group_instructions"};
114 bool Status = toSpirv(ExtensionAssembly, Result, Error, {}, Opts);
115 EXPECT_TRUE(Status && Error.empty() && !Result.empty());
116 EXPECT_EQ(identify_magic(Result), file_magic::spirv_object);
119 TEST_F(SPIRVAPITest, checkTranslateSupportExtensionByArg) {
120 std::string Result, Error;
121 std::vector<std::string> ExtNames{"SPV_KHR_uniform_group_instructions"};
122 bool Status = toSpirv(ExtensionAssembly, Result, Error, ExtNames, {});
123 EXPECT_TRUE(Status && Error.empty() && !Result.empty());
124 EXPECT_EQ(identify_magic(Result), file_magic::spirv_object);
127 TEST_F(SPIRVAPITest, checkTranslateSupportExtensionByArgList) {
128 std::string Result, Error;
129 std::vector<std::string> ExtNames{"SPV_KHR_subgroup_rotate",
130 "SPV_KHR_uniform_group_instructions",
131 "SPV_KHR_subgroup_rotate"};
132 bool Status = toSpirv(ExtensionAssembly, Result, Error, ExtNames, {});
133 EXPECT_TRUE(Status && Error.empty() && !Result.empty());
134 EXPECT_EQ(identify_magic(Result), file_magic::spirv_object);
137 TEST_F(SPIRVAPITest, checkTranslateAllExtensions) {
138 std::string Result, Error;
139 std::vector<std::string> Opts{"--spirv-ext=all"};
140 bool Status = toSpirv(ExtensionAssembly, Result, Error, {}, Opts);
141 EXPECT_TRUE(Status && Error.empty() && !Result.empty());
142 EXPECT_EQ(identify_magic(Result), file_magic::spirv_object);
145 TEST_F(SPIRVAPITest, checkTranslateUnknownExtensionByArg) {
146 std::string Result, Error;
147 std::vector<std::string> ExtNames{"SPV_XYZ_my_unknown_extension"};
148 bool Status = toSpirv(ExtensionAssembly, Result, Error, ExtNames, {});
149 EXPECT_FALSE(Status);
150 EXPECT_TRUE(Result.empty());
151 EXPECT_EQ(Error, "Unknown SPIR-V extension: SPV_XYZ_my_unknown_extension");
154 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
155 TEST_F(SPIRVAPITest, checkTranslateExtensionError) {
156 std::string Result, Error;
157 std::vector<std::string> Opts;
158 EXPECT_DEATH_IF_SUPPORTED(
159 { toSpirv(ExtensionAssembly, Result, Error, {}, Opts); },
160 "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the "
161 "following SPIR-V extension: SPV_KHR_uniform_group_instructions");
164 TEST_F(SPIRVAPITest, checkTranslateUnknownExtensionByOpts) {
165 std::string Result, Error;
166 std::vector<std::string> Opts{"--spirv-ext=+SPV_XYZ_my_unknown_extension"};
167 EXPECT_DEATH_IF_SUPPORTED(
168 { toSpirv(ExtensionAssembly, Result, Error, {}, Opts); },
169 "SPIRVTranslateModule: for the --spirv-ext option: Unknown SPIR-V");
172 TEST_F(SPIRVAPITest, checkTranslateWrongExtensionByOpts) {
173 std::string Result, Error;
174 std::vector<std::string> Opts{"--spirv-ext=+SPV_KHR_subgroup_rotate"};
175 EXPECT_DEATH_IF_SUPPORTED(
176 { toSpirv(ExtensionAssembly, Result, Error, {}, Opts); },
177 "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the "
178 "following SPIR-V extension: SPV_KHR_uniform_group_instructions");
181 TEST_F(SPIRVAPITest, checkTranslateWrongExtensionByArg) {
182 std::string Result, Error;
183 std::vector<std::string> ExtNames{"SPV_KHR_subgroup_rotate"};
184 EXPECT_DEATH_IF_SUPPORTED(
185 { toSpirv(ExtensionAssembly, Result, Error, ExtNames, {}); },
186 "LLVM ERROR: __spirv_GroupBitwiseAndKHR: the builtin requires the "
187 "following SPIR-V extension: SPV_KHR_uniform_group_instructions");
189 #endif
191 } // end namespace llvm