1 // Copyright (c) 2021 The Khronos Group Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Tests for OpExtension validator rules.
16 
17 #include <string>
18 #include <vector>
19 
20 #include "gmock/gmock.h"
21 #include "source/spirv_target_env.h"
22 #include "test/unit_spirv.h"
23 #include "test/val/val_fixtures.h"
24 
25 namespace spvtools {
26 namespace val {
27 namespace {
28 
29 using ::testing::HasSubstr;
30 using ::testing::Values;
31 using ::testing::ValuesIn;
32 
33 using ValidateSpvKHRBitInstructions = spvtest::ValidateBase<bool>;
34 
TEST_F(ValidateSpvKHRBitInstructions, Valid)35 TEST_F(ValidateSpvKHRBitInstructions, Valid) {
36   const std::string str = R"(
37     OpCapability Kernel
38     OpCapability Addresses
39     OpCapability BitInstructions
40     OpExtension "SPV_KHR_bit_instructions"
41     OpMemoryModel Physical32 OpenCL
42     OpEntryPoint Kernel %main "main"
43 
44     %void    = OpTypeVoid
45     %void_fn = OpTypeFunction %void
46     %u32 = OpTypeInt 32 0
47     %u32_1 = OpConstant %u32 1
48 
49     %main = OpFunction %void None %void_fn
50     %entry = OpLabel
51     %unused = OpBitReverse %u32 %u32_1
52     OpReturn
53     OpFunctionEnd
54 )";
55   CompileSuccessfully(str.c_str());
56   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
57 }
58 
TEST_F(ValidateSpvKHRBitInstructions, RequiresExtension)59 TEST_F(ValidateSpvKHRBitInstructions, RequiresExtension) {
60   const std::string str = R"(
61     OpCapability Kernel
62     OpCapability Addresses
63     OpCapability BitInstructions
64     OpMemoryModel Physical32 OpenCL
65     OpEntryPoint Kernel %main "main"
66 
67     %void    = OpTypeVoid
68     %void_fn = OpTypeFunction %void
69     %u32 = OpTypeInt 32 0
70     %u32_1 = OpConstant %u32 1
71 
72     %main = OpFunction %void None %void_fn
73     %entry = OpLabel
74     %unused = OpBitReverse %u32 %u32_1
75     OpReturn
76     OpFunctionEnd
77 )";
78   CompileSuccessfully(str.c_str());
79   EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
80   EXPECT_THAT(
81       getDiagnosticString(),
82       HasSubstr("1st operand of Capability: operand BitInstructions(6025) "
83                 "requires one of these extensions: SPV_KHR_bit_instructions"));
84 }
85 
TEST_F(ValidateSpvKHRBitInstructions, RequiresCapability)86 TEST_F(ValidateSpvKHRBitInstructions, RequiresCapability) {
87   const std::string str = R"(
88     OpCapability Kernel
89     OpCapability Addresses
90     OpExtension "SPV_KHR_bit_instructions"
91     OpMemoryModel Physical32 OpenCL
92     OpEntryPoint Kernel %main "main"
93 
94     %void    = OpTypeVoid
95     %void_fn = OpTypeFunction %void
96     %u32 = OpTypeInt 32 0
97     %u32_1 = OpConstant %u32 1
98 
99     %main = OpFunction %void None %void_fn
100     %entry = OpLabel
101     %unused = OpBitReverse %u32 %u32_1
102     OpReturn
103     OpFunctionEnd
104 )";
105   CompileSuccessfully(str.c_str());
106   EXPECT_NE(SPV_SUCCESS, ValidateInstructions());
107   EXPECT_THAT(getDiagnosticString(),
108               HasSubstr("Opcode BitReverse requires one of these capabilities: "
109                         "Shader BitInstructions"));
110 }
111 
112 }  // namespace
113 }  // namespace val
114 }  // namespace spvtools
115