1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Google Inc.
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci// Tests for unique type declaration rules validator.
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include <string>
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
20fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h"
21fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h"
22fd4e5da5Sopenharmony_ci
23fd4e5da5Sopenharmony_cinamespace spvtools {
24fd4e5da5Sopenharmony_cinamespace val {
25fd4e5da5Sopenharmony_cinamespace {
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
28fd4e5da5Sopenharmony_ciusing ::testing::Not;
29fd4e5da5Sopenharmony_ci
30fd4e5da5Sopenharmony_ciusing ValidateBitwise = spvtest::ValidateBase<bool>;
31fd4e5da5Sopenharmony_ci
32fd4e5da5Sopenharmony_cistd::string GenerateShaderCode(
33fd4e5da5Sopenharmony_ci    const std::string& body,
34fd4e5da5Sopenharmony_ci    const std::string& capabilities_and_extensions = "") {
35fd4e5da5Sopenharmony_ci  const std::string capabilities =
36fd4e5da5Sopenharmony_ci      R"(
37fd4e5da5Sopenharmony_ciOpCapability Shader
38fd4e5da5Sopenharmony_ciOpCapability Int64
39fd4e5da5Sopenharmony_ciOpCapability Float64)";
40fd4e5da5Sopenharmony_ci
41fd4e5da5Sopenharmony_ci  const std::string after_extension_before_body =
42fd4e5da5Sopenharmony_ci      R"(
43fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
44fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
45fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
46fd4e5da5Sopenharmony_ci%void = OpTypeVoid
47fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
48fd4e5da5Sopenharmony_ci%bool = OpTypeBool
49fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
50fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
51fd4e5da5Sopenharmony_ci%s32 = OpTypeInt 32 1
52fd4e5da5Sopenharmony_ci%f64 = OpTypeFloat 64
53fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0
54fd4e5da5Sopenharmony_ci%s64 = OpTypeInt 64 1
55fd4e5da5Sopenharmony_ci%boolvec2 = OpTypeVector %bool 2
56fd4e5da5Sopenharmony_ci%s32vec2 = OpTypeVector %s32 2
57fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2
58fd4e5da5Sopenharmony_ci%u64vec2 = OpTypeVector %u64 2
59fd4e5da5Sopenharmony_ci%f32vec2 = OpTypeVector %f32 2
60fd4e5da5Sopenharmony_ci%f64vec2 = OpTypeVector %f64 2
61fd4e5da5Sopenharmony_ci%boolvec3 = OpTypeVector %bool 3
62fd4e5da5Sopenharmony_ci%u32vec3 = OpTypeVector %u32 3
63fd4e5da5Sopenharmony_ci%u64vec3 = OpTypeVector %u64 3
64fd4e5da5Sopenharmony_ci%s32vec3 = OpTypeVector %s32 3
65fd4e5da5Sopenharmony_ci%f32vec3 = OpTypeVector %f32 3
66fd4e5da5Sopenharmony_ci%f64vec3 = OpTypeVector %f64 3
67fd4e5da5Sopenharmony_ci%boolvec4 = OpTypeVector %bool 4
68fd4e5da5Sopenharmony_ci%u32vec4 = OpTypeVector %u32 4
69fd4e5da5Sopenharmony_ci%u64vec4 = OpTypeVector %u64 4
70fd4e5da5Sopenharmony_ci%s32vec4 = OpTypeVector %s32 4
71fd4e5da5Sopenharmony_ci%f32vec4 = OpTypeVector %f32 4
72fd4e5da5Sopenharmony_ci%f64vec4 = OpTypeVector %f64 4
73fd4e5da5Sopenharmony_ci
74fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0
75fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1
76fd4e5da5Sopenharmony_ci%f32_2 = OpConstant %f32 2
77fd4e5da5Sopenharmony_ci%f32_3 = OpConstant %f32 3
78fd4e5da5Sopenharmony_ci%f32_4 = OpConstant %f32 4
79fd4e5da5Sopenharmony_ci
80fd4e5da5Sopenharmony_ci%s32_0 = OpConstant %s32 0
81fd4e5da5Sopenharmony_ci%s32_1 = OpConstant %s32 1
82fd4e5da5Sopenharmony_ci%s32_2 = OpConstant %s32 2
83fd4e5da5Sopenharmony_ci%s32_3 = OpConstant %s32 3
84fd4e5da5Sopenharmony_ci%s32_4 = OpConstant %s32 4
85fd4e5da5Sopenharmony_ci%s32_m1 = OpConstant %s32 -1
86fd4e5da5Sopenharmony_ci
87fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0
88fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1
89fd4e5da5Sopenharmony_ci%u32_2 = OpConstant %u32 2
90fd4e5da5Sopenharmony_ci%u32_3 = OpConstant %u32 3
91fd4e5da5Sopenharmony_ci%u32_4 = OpConstant %u32 4
92fd4e5da5Sopenharmony_ci
93fd4e5da5Sopenharmony_ci%f64_0 = OpConstant %f64 0
94fd4e5da5Sopenharmony_ci%f64_1 = OpConstant %f64 1
95fd4e5da5Sopenharmony_ci%f64_2 = OpConstant %f64 2
96fd4e5da5Sopenharmony_ci%f64_3 = OpConstant %f64 3
97fd4e5da5Sopenharmony_ci%f64_4 = OpConstant %f64 4
98fd4e5da5Sopenharmony_ci
99fd4e5da5Sopenharmony_ci%s64_0 = OpConstant %s64 0
100fd4e5da5Sopenharmony_ci%s64_1 = OpConstant %s64 1
101fd4e5da5Sopenharmony_ci%s64_2 = OpConstant %s64 2
102fd4e5da5Sopenharmony_ci%s64_3 = OpConstant %s64 3
103fd4e5da5Sopenharmony_ci%s64_4 = OpConstant %s64 4
104fd4e5da5Sopenharmony_ci%s64_m1 = OpConstant %s64 -1
105fd4e5da5Sopenharmony_ci
106fd4e5da5Sopenharmony_ci%u64_0 = OpConstant %u64 0
107fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1
108fd4e5da5Sopenharmony_ci%u64_2 = OpConstant %u64 2
109fd4e5da5Sopenharmony_ci%u64_3 = OpConstant %u64 3
110fd4e5da5Sopenharmony_ci%u64_4 = OpConstant %u64 4
111fd4e5da5Sopenharmony_ci
112fd4e5da5Sopenharmony_ci%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
113fd4e5da5Sopenharmony_ci%u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
114fd4e5da5Sopenharmony_ci%u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
115fd4e5da5Sopenharmony_ci%u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
116fd4e5da5Sopenharmony_ci%u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
117fd4e5da5Sopenharmony_ci%u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
118fd4e5da5Sopenharmony_ci
119fd4e5da5Sopenharmony_ci%s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
120fd4e5da5Sopenharmony_ci%s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
121fd4e5da5Sopenharmony_ci%s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
122fd4e5da5Sopenharmony_ci%s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
123fd4e5da5Sopenharmony_ci%s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
124fd4e5da5Sopenharmony_ci%s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
125fd4e5da5Sopenharmony_ci
126fd4e5da5Sopenharmony_ci%f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
127fd4e5da5Sopenharmony_ci%f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
128fd4e5da5Sopenharmony_ci%f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
129fd4e5da5Sopenharmony_ci%f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
130fd4e5da5Sopenharmony_ci%f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
131fd4e5da5Sopenharmony_ci%f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
132fd4e5da5Sopenharmony_ci
133fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
134fd4e5da5Sopenharmony_ci%main_entry = OpLabel)";
135fd4e5da5Sopenharmony_ci
136fd4e5da5Sopenharmony_ci  const std::string after_body =
137fd4e5da5Sopenharmony_ci      R"(
138fd4e5da5Sopenharmony_ciOpReturn
139fd4e5da5Sopenharmony_ciOpFunctionEnd)";
140fd4e5da5Sopenharmony_ci
141fd4e5da5Sopenharmony_ci  return capabilities + capabilities_and_extensions +
142fd4e5da5Sopenharmony_ci         after_extension_before_body + body + after_body;
143fd4e5da5Sopenharmony_ci}
144fd4e5da5Sopenharmony_ci
145fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, ShiftAllSuccess) {
146fd4e5da5Sopenharmony_ci  const std::string body = R"(
147fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %u64 %u64_1 %s32_2
148fd4e5da5Sopenharmony_ci%val2 = OpShiftRightArithmetic %s32vec2 %s32vec2_12 %s32vec2_12
149fd4e5da5Sopenharmony_ci%val3 = OpShiftLeftLogical %u32vec2 %s32vec2_12 %u32vec2_12
150fd4e5da5Sopenharmony_ci)";
151fd4e5da5Sopenharmony_ci
152fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
153fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
154fd4e5da5Sopenharmony_ci}
155fd4e5da5Sopenharmony_ci
156fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpShiftRightLogicalWrongResultType) {
157fd4e5da5Sopenharmony_ci  const std::string body = R"(
158fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %bool %u64_1 %s32_2
159fd4e5da5Sopenharmony_ci)";
160fd4e5da5Sopenharmony_ci
161fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
162fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
163fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
164fd4e5da5Sopenharmony_ci              HasSubstr("Expected int scalar or vector type as Result Type: "
165fd4e5da5Sopenharmony_ci                        "ShiftRightLogical"));
166fd4e5da5Sopenharmony_ci}
167fd4e5da5Sopenharmony_ci
168fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpShiftRightLogicalBaseNotInt) {
169fd4e5da5Sopenharmony_ci  const std::string body = R"(
170fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %u32 %f32_1 %s32_2
171fd4e5da5Sopenharmony_ci)";
172fd4e5da5Sopenharmony_ci
173fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
174fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
175fd4e5da5Sopenharmony_ci  EXPECT_THAT(
176fd4e5da5Sopenharmony_ci      getDiagnosticString(),
177fd4e5da5Sopenharmony_ci      HasSubstr("Expected Base to be int scalar or vector: ShiftRightLogical"));
178fd4e5da5Sopenharmony_ci}
179fd4e5da5Sopenharmony_ci
180fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpShiftRightLogicalBaseWrongDimension) {
181fd4e5da5Sopenharmony_ci  const std::string body = R"(
182fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %u32 %u32vec2_12 %s32_2
183fd4e5da5Sopenharmony_ci)";
184fd4e5da5Sopenharmony_ci
185fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
186fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
187fd4e5da5Sopenharmony_ci  EXPECT_THAT(
188fd4e5da5Sopenharmony_ci      getDiagnosticString(),
189fd4e5da5Sopenharmony_ci      HasSubstr("Expected Base to have the same dimension as Result Type: "
190fd4e5da5Sopenharmony_ci                "ShiftRightLogical"));
191fd4e5da5Sopenharmony_ci}
192fd4e5da5Sopenharmony_ci
193fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpShiftRightLogicalBaseWrongBitWidth) {
194fd4e5da5Sopenharmony_ci  const std::string body = R"(
195fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %u64 %u32_1 %s32_2
196fd4e5da5Sopenharmony_ci)";
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
199fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
200fd4e5da5Sopenharmony_ci  EXPECT_THAT(
201fd4e5da5Sopenharmony_ci      getDiagnosticString(),
202fd4e5da5Sopenharmony_ci      HasSubstr("Expected Base to have the same bit width as Result Type: "
203fd4e5da5Sopenharmony_ci                "ShiftRightLogical"));
204fd4e5da5Sopenharmony_ci}
205fd4e5da5Sopenharmony_ci
206fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpShiftRightLogicalShiftNotInt) {
207fd4e5da5Sopenharmony_ci  const std::string body = R"(
208fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %u32 %u32_1 %f32_2
209fd4e5da5Sopenharmony_ci)";
210fd4e5da5Sopenharmony_ci
211fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
212fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
213fd4e5da5Sopenharmony_ci  EXPECT_THAT(
214fd4e5da5Sopenharmony_ci      getDiagnosticString(),
215fd4e5da5Sopenharmony_ci      HasSubstr(
216fd4e5da5Sopenharmony_ci          "Expected Shift to be int scalar or vector: ShiftRightLogical"));
217fd4e5da5Sopenharmony_ci}
218fd4e5da5Sopenharmony_ci
219fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpShiftRightLogicalShiftWrongDimension) {
220fd4e5da5Sopenharmony_ci  const std::string body = R"(
221fd4e5da5Sopenharmony_ci%val1 = OpShiftRightLogical %u32 %u32_1 %s32vec2_12
222fd4e5da5Sopenharmony_ci)";
223fd4e5da5Sopenharmony_ci
224fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
225fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
226fd4e5da5Sopenharmony_ci  EXPECT_THAT(
227fd4e5da5Sopenharmony_ci      getDiagnosticString(),
228fd4e5da5Sopenharmony_ci      HasSubstr("Expected Shift to have the same dimension as Result Type: "
229fd4e5da5Sopenharmony_ci                "ShiftRightLogical"));
230fd4e5da5Sopenharmony_ci}
231fd4e5da5Sopenharmony_ci
232fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, LogicAllSuccess) {
233fd4e5da5Sopenharmony_ci  const std::string body = R"(
234fd4e5da5Sopenharmony_ci%val1 = OpBitwiseOr %u64 %u64_1 %s64_0
235fd4e5da5Sopenharmony_ci%val2 = OpBitwiseAnd %s64 %s64_1 %u64_0
236fd4e5da5Sopenharmony_ci%val3 = OpBitwiseXor %s32vec2 %s32vec2_12 %u32vec2_01
237fd4e5da5Sopenharmony_ci%val4 = OpNot %s32vec2 %u32vec2_01
238fd4e5da5Sopenharmony_ci)";
239fd4e5da5Sopenharmony_ci
240fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
241fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
242fd4e5da5Sopenharmony_ci}
243fd4e5da5Sopenharmony_ci
244fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndWrongResultType) {
245fd4e5da5Sopenharmony_ci  const std::string body = R"(
246fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %bool %u64_1 %s32_2
247fd4e5da5Sopenharmony_ci)";
248fd4e5da5Sopenharmony_ci
249fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
250fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
251fd4e5da5Sopenharmony_ci  EXPECT_THAT(
252fd4e5da5Sopenharmony_ci      getDiagnosticString(),
253fd4e5da5Sopenharmony_ci      HasSubstr(
254fd4e5da5Sopenharmony_ci          "Expected int scalar or vector type as Result Type: BitwiseAnd"));
255fd4e5da5Sopenharmony_ci}
256fd4e5da5Sopenharmony_ci
257fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndLeftNotInt) {
258fd4e5da5Sopenharmony_ci  const std::string body = R"(
259fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %u32 %f32_1 %s32_2
260fd4e5da5Sopenharmony_ci)";
261fd4e5da5Sopenharmony_ci
262fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
263fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
264fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
265fd4e5da5Sopenharmony_ci              HasSubstr("Expected int scalar or vector as operand: BitwiseAnd "
266fd4e5da5Sopenharmony_ci                        "operand index 2"));
267fd4e5da5Sopenharmony_ci}
268fd4e5da5Sopenharmony_ci
269fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndRightNotInt) {
270fd4e5da5Sopenharmony_ci  const std::string body = R"(
271fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %u32 %u32_1 %f32_2
272fd4e5da5Sopenharmony_ci)";
273fd4e5da5Sopenharmony_ci
274fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
275fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
276fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
277fd4e5da5Sopenharmony_ci              HasSubstr("Expected int scalar or vector as operand: BitwiseAnd "
278fd4e5da5Sopenharmony_ci                        "operand index 3"));
279fd4e5da5Sopenharmony_ci}
280fd4e5da5Sopenharmony_ci
281fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndLeftWrongDimension) {
282fd4e5da5Sopenharmony_ci  const std::string body = R"(
283fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %u32 %u32vec2_12 %s32_2
284fd4e5da5Sopenharmony_ci)";
285fd4e5da5Sopenharmony_ci
286fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
287fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
288fd4e5da5Sopenharmony_ci  EXPECT_THAT(
289fd4e5da5Sopenharmony_ci      getDiagnosticString(),
290fd4e5da5Sopenharmony_ci      HasSubstr("Expected operands to have the same dimension as Result Type: "
291fd4e5da5Sopenharmony_ci                "BitwiseAnd operand index 2"));
292fd4e5da5Sopenharmony_ci}
293fd4e5da5Sopenharmony_ci
294fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndRightWrongDimension) {
295fd4e5da5Sopenharmony_ci  const std::string body = R"(
296fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %u32 %s32_2 %u32vec2_12
297fd4e5da5Sopenharmony_ci)";
298fd4e5da5Sopenharmony_ci
299fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
300fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
301fd4e5da5Sopenharmony_ci  EXPECT_THAT(
302fd4e5da5Sopenharmony_ci      getDiagnosticString(),
303fd4e5da5Sopenharmony_ci      HasSubstr("Expected operands to have the same dimension as Result Type: "
304fd4e5da5Sopenharmony_ci                "BitwiseAnd operand index 3"));
305fd4e5da5Sopenharmony_ci}
306fd4e5da5Sopenharmony_ci
307fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndLeftWrongBitWidth) {
308fd4e5da5Sopenharmony_ci  const std::string body = R"(
309fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %u64 %u32_1 %s64_2
310fd4e5da5Sopenharmony_ci)";
311fd4e5da5Sopenharmony_ci
312fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
313fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
314fd4e5da5Sopenharmony_ci  EXPECT_THAT(
315fd4e5da5Sopenharmony_ci      getDiagnosticString(),
316fd4e5da5Sopenharmony_ci      HasSubstr("Expected operands to have the same bit width as Result Type: "
317fd4e5da5Sopenharmony_ci                "BitwiseAnd operand index 2"));
318fd4e5da5Sopenharmony_ci}
319fd4e5da5Sopenharmony_ci
320fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitwiseAndRightWrongBitWidth) {
321fd4e5da5Sopenharmony_ci  const std::string body = R"(
322fd4e5da5Sopenharmony_ci%val1 = OpBitwiseAnd %u64 %u64_1 %s32_2
323fd4e5da5Sopenharmony_ci)";
324fd4e5da5Sopenharmony_ci
325fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
326fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
327fd4e5da5Sopenharmony_ci  EXPECT_THAT(
328fd4e5da5Sopenharmony_ci      getDiagnosticString(),
329fd4e5da5Sopenharmony_ci      HasSubstr("Expected operands to have the same bit width as Result Type: "
330fd4e5da5Sopenharmony_ci                "BitwiseAnd operand index 3"));
331fd4e5da5Sopenharmony_ci}
332fd4e5da5Sopenharmony_ci
333fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertSuccess) {
334fd4e5da5Sopenharmony_ci  const std::string body = R"(
335fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
336fd4e5da5Sopenharmony_ci%val2 = OpBitFieldInsert %s32vec2 %s32vec2_12 %s32vec2_12 %s32_1 %u32_2
337fd4e5da5Sopenharmony_ci)";
338fd4e5da5Sopenharmony_ci
339fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
340fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
341fd4e5da5Sopenharmony_ci}
342fd4e5da5Sopenharmony_ci
343fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertVulkanSuccess) {
344fd4e5da5Sopenharmony_ci  const std::string body = R"(
345fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u32 %u32_1 %u32_2 %s32_1 %s32_2
346fd4e5da5Sopenharmony_ci%val2 = OpBitFieldInsert %s32vec2 %s32vec2_12 %s32vec2_12 %s32_1 %u32_2
347fd4e5da5Sopenharmony_ci)";
348fd4e5da5Sopenharmony_ci
349fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
350fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
351fd4e5da5Sopenharmony_ci}
352fd4e5da5Sopenharmony_ci
353fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertWrongResultType) {
354fd4e5da5Sopenharmony_ci  const std::string body = R"(
355fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %bool %u64_1 %u64_2 %s32_1 %s32_2
356fd4e5da5Sopenharmony_ci)";
357fd4e5da5Sopenharmony_ci
358fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
359fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
360fd4e5da5Sopenharmony_ci  EXPECT_THAT(
361fd4e5da5Sopenharmony_ci      getDiagnosticString(),
362fd4e5da5Sopenharmony_ci      HasSubstr(
363fd4e5da5Sopenharmony_ci          "Expected Base Type to be equal to Result Type: BitFieldInsert"));
364fd4e5da5Sopenharmony_ci}
365fd4e5da5Sopenharmony_ci
366fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertWrongBaseType) {
367fd4e5da5Sopenharmony_ci  const std::string body = R"(
368fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u64 %s64_1 %u64_2 %s32_1 %s32_2
369fd4e5da5Sopenharmony_ci)";
370fd4e5da5Sopenharmony_ci
371fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
372fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
373fd4e5da5Sopenharmony_ci  EXPECT_THAT(
374fd4e5da5Sopenharmony_ci      getDiagnosticString(),
375fd4e5da5Sopenharmony_ci      HasSubstr(
376fd4e5da5Sopenharmony_ci          "Expected Base Type to be equal to Result Type: BitFieldInsert"));
377fd4e5da5Sopenharmony_ci}
378fd4e5da5Sopenharmony_ci
379fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertWrongInsertType) {
380fd4e5da5Sopenharmony_ci  const std::string body = R"(
381fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u64 %u64_1 %s64_2 %s32_1 %s32_2
382fd4e5da5Sopenharmony_ci)";
383fd4e5da5Sopenharmony_ci
384fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
385fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
386fd4e5da5Sopenharmony_ci  EXPECT_THAT(
387fd4e5da5Sopenharmony_ci      getDiagnosticString(),
388fd4e5da5Sopenharmony_ci      HasSubstr(
389fd4e5da5Sopenharmony_ci          "Expected Insert Type to be equal to Result Type: BitFieldInsert"));
390fd4e5da5Sopenharmony_ci}
391fd4e5da5Sopenharmony_ci
392fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertOffsetNotInt) {
393fd4e5da5Sopenharmony_ci  const std::string body = R"(
394fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %f32_1 %s32_2
395fd4e5da5Sopenharmony_ci)";
396fd4e5da5Sopenharmony_ci
397fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
398fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
399fd4e5da5Sopenharmony_ci  EXPECT_THAT(
400fd4e5da5Sopenharmony_ci      getDiagnosticString(),
401fd4e5da5Sopenharmony_ci      HasSubstr("Expected Offset Type to be int scalar: BitFieldInsert"));
402fd4e5da5Sopenharmony_ci}
403fd4e5da5Sopenharmony_ci
404fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertCountNotInt) {
405fd4e5da5Sopenharmony_ci  const std::string body = R"(
406fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %u32_1 %f32_2
407fd4e5da5Sopenharmony_ci)";
408fd4e5da5Sopenharmony_ci
409fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
410fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
411fd4e5da5Sopenharmony_ci  EXPECT_THAT(
412fd4e5da5Sopenharmony_ci      getDiagnosticString(),
413fd4e5da5Sopenharmony_ci      HasSubstr("Expected Count Type to be int scalar: BitFieldInsert"));
414fd4e5da5Sopenharmony_ci}
415fd4e5da5Sopenharmony_ci
416fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldInsertNot32Vulkan) {
417fd4e5da5Sopenharmony_ci  const std::string body = R"(
418fd4e5da5Sopenharmony_ci%val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
419fd4e5da5Sopenharmony_ci)";
420fd4e5da5Sopenharmony_ci
421fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
422fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
423fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
424fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-04781"));
425fd4e5da5Sopenharmony_ci  EXPECT_THAT(
426fd4e5da5Sopenharmony_ci      getDiagnosticString(),
427fd4e5da5Sopenharmony_ci      HasSubstr("Expected 32-bit int type for Base operand: BitFieldInsert"));
428fd4e5da5Sopenharmony_ci}
429fd4e5da5Sopenharmony_ci
430fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractSuccess) {
431fd4e5da5Sopenharmony_ci  const std::string body = R"(
432fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
433fd4e5da5Sopenharmony_ci%val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
434fd4e5da5Sopenharmony_ci)";
435fd4e5da5Sopenharmony_ci
436fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
437fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
438fd4e5da5Sopenharmony_ci}
439fd4e5da5Sopenharmony_ci
440fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractVulkanSuccess) {
441fd4e5da5Sopenharmony_ci  const std::string body = R"(
442fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %u32 %u32_1 %s32_1 %s32_2
443fd4e5da5Sopenharmony_ci%val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
444fd4e5da5Sopenharmony_ci)";
445fd4e5da5Sopenharmony_ci
446fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
447fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
448fd4e5da5Sopenharmony_ci}
449fd4e5da5Sopenharmony_ci
450fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractWrongResultType) {
451fd4e5da5Sopenharmony_ci  const std::string body = R"(
452fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %bool %u64_1 %s32_1 %s32_2
453fd4e5da5Sopenharmony_ci)";
454fd4e5da5Sopenharmony_ci
455fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
456fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
457fd4e5da5Sopenharmony_ci  EXPECT_THAT(
458fd4e5da5Sopenharmony_ci      getDiagnosticString(),
459fd4e5da5Sopenharmony_ci      HasSubstr(
460fd4e5da5Sopenharmony_ci          "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
461fd4e5da5Sopenharmony_ci}
462fd4e5da5Sopenharmony_ci
463fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractWrongBaseType) {
464fd4e5da5Sopenharmony_ci  const std::string body = R"(
465fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %u64 %s64_1 %s32_1 %s32_2
466fd4e5da5Sopenharmony_ci)";
467fd4e5da5Sopenharmony_ci
468fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
469fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
470fd4e5da5Sopenharmony_ci  EXPECT_THAT(
471fd4e5da5Sopenharmony_ci      getDiagnosticString(),
472fd4e5da5Sopenharmony_ci      HasSubstr(
473fd4e5da5Sopenharmony_ci          "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
474fd4e5da5Sopenharmony_ci}
475fd4e5da5Sopenharmony_ci
476fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractOffsetNotInt) {
477fd4e5da5Sopenharmony_ci  const std::string body = R"(
478fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %u64 %u64_1 %f32_1 %s32_2
479fd4e5da5Sopenharmony_ci)";
480fd4e5da5Sopenharmony_ci
481fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
482fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
483fd4e5da5Sopenharmony_ci  EXPECT_THAT(
484fd4e5da5Sopenharmony_ci      getDiagnosticString(),
485fd4e5da5Sopenharmony_ci      HasSubstr("Expected Offset Type to be int scalar: BitFieldSExtract"));
486fd4e5da5Sopenharmony_ci}
487fd4e5da5Sopenharmony_ci
488fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractCountNotInt) {
489fd4e5da5Sopenharmony_ci  const std::string body = R"(
490fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %u64 %u64_1 %u32_1 %f32_2
491fd4e5da5Sopenharmony_ci)";
492fd4e5da5Sopenharmony_ci
493fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
494fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
495fd4e5da5Sopenharmony_ci  EXPECT_THAT(
496fd4e5da5Sopenharmony_ci      getDiagnosticString(),
497fd4e5da5Sopenharmony_ci      HasSubstr("Expected Count Type to be int scalar: BitFieldSExtract"));
498fd4e5da5Sopenharmony_ci}
499fd4e5da5Sopenharmony_ci
500fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitFieldSExtractNot32Vulkan) {
501fd4e5da5Sopenharmony_ci  const std::string body = R"(
502fd4e5da5Sopenharmony_ci%val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
503fd4e5da5Sopenharmony_ci)";
504fd4e5da5Sopenharmony_ci
505fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
506fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
507fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
508fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-04781"));
509fd4e5da5Sopenharmony_ci  EXPECT_THAT(
510fd4e5da5Sopenharmony_ci      getDiagnosticString(),
511fd4e5da5Sopenharmony_ci      HasSubstr("Expected 32-bit int type for Base operand: BitFieldSExtract"));
512fd4e5da5Sopenharmony_ci}
513fd4e5da5Sopenharmony_ci
514fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitReverseSuccess) {
515fd4e5da5Sopenharmony_ci  const std::string body = R"(
516fd4e5da5Sopenharmony_ci%val1 = OpBitReverse %u64 %u64_1
517fd4e5da5Sopenharmony_ci%val2 = OpBitReverse %s32vec2 %s32vec2_12
518fd4e5da5Sopenharmony_ci)";
519fd4e5da5Sopenharmony_ci
520fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
521fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
522fd4e5da5Sopenharmony_ci}
523fd4e5da5Sopenharmony_ci
524fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitReverseVulkanSuccess) {
525fd4e5da5Sopenharmony_ci  const std::string body = R"(
526fd4e5da5Sopenharmony_ci%val1 = OpBitReverse %u32 %u32_1
527fd4e5da5Sopenharmony_ci%val2 = OpBitReverse %s32vec2 %s32vec2_12
528fd4e5da5Sopenharmony_ci)";
529fd4e5da5Sopenharmony_ci
530fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
531fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
532fd4e5da5Sopenharmony_ci}
533fd4e5da5Sopenharmony_ci
534fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitReverseWrongResultType) {
535fd4e5da5Sopenharmony_ci  const std::string body = R"(
536fd4e5da5Sopenharmony_ci%val1 = OpBitReverse %bool %u64_1
537fd4e5da5Sopenharmony_ci)";
538fd4e5da5Sopenharmony_ci
539fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
540fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
541fd4e5da5Sopenharmony_ci  EXPECT_THAT(
542fd4e5da5Sopenharmony_ci      getDiagnosticString(),
543fd4e5da5Sopenharmony_ci      HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
544fd4e5da5Sopenharmony_ci}
545fd4e5da5Sopenharmony_ci
546fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitReverseWrongBaseType) {
547fd4e5da5Sopenharmony_ci  const std::string body = R"(
548fd4e5da5Sopenharmony_ci%val1 = OpBitReverse %u64 %s64_1
549fd4e5da5Sopenharmony_ci)";
550fd4e5da5Sopenharmony_ci
551fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
552fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
553fd4e5da5Sopenharmony_ci  EXPECT_THAT(
554fd4e5da5Sopenharmony_ci      getDiagnosticString(),
555fd4e5da5Sopenharmony_ci      HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
556fd4e5da5Sopenharmony_ci}
557fd4e5da5Sopenharmony_ci
558fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitReverseNot32Vulkan) {
559fd4e5da5Sopenharmony_ci  const std::string body = R"(
560fd4e5da5Sopenharmony_ci%val1 = OpBitReverse %u64 %u64_1
561fd4e5da5Sopenharmony_ci)";
562fd4e5da5Sopenharmony_ci
563fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
564fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
565fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
566fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-04781"));
567fd4e5da5Sopenharmony_ci  EXPECT_THAT(
568fd4e5da5Sopenharmony_ci      getDiagnosticString(),
569fd4e5da5Sopenharmony_ci      HasSubstr("Expected 32-bit int type for Base operand: BitReverse"));
570fd4e5da5Sopenharmony_ci}
571fd4e5da5Sopenharmony_ci
572fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountSuccess) {
573fd4e5da5Sopenharmony_ci  const std::string body = R"(
574fd4e5da5Sopenharmony_ci%val1 = OpBitCount %s32 %u64_1
575fd4e5da5Sopenharmony_ci%val2 = OpBitCount %u32vec2 %s32vec2_12
576fd4e5da5Sopenharmony_ci%val3 = OpBitCount %s64 %s64_1
577fd4e5da5Sopenharmony_ci)";
578fd4e5da5Sopenharmony_ci
579fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
580fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
581fd4e5da5Sopenharmony_ci}
582fd4e5da5Sopenharmony_ci
583fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountVulkanSuccess) {
584fd4e5da5Sopenharmony_ci  const std::string body = R"(
585fd4e5da5Sopenharmony_ci%val1 = OpBitCount %s32 %u32_1
586fd4e5da5Sopenharmony_ci%val2 = OpBitCount %u32vec2 %s32vec2_12
587fd4e5da5Sopenharmony_ci)";
588fd4e5da5Sopenharmony_ci
589fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
590fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
591fd4e5da5Sopenharmony_ci}
592fd4e5da5Sopenharmony_ci
593fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountWrongResultType) {
594fd4e5da5Sopenharmony_ci  const std::string body = R"(
595fd4e5da5Sopenharmony_ci%val1 = OpBitCount %bool %u64_1
596fd4e5da5Sopenharmony_ci)";
597fd4e5da5Sopenharmony_ci
598fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
599fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
600fd4e5da5Sopenharmony_ci  EXPECT_THAT(
601fd4e5da5Sopenharmony_ci      getDiagnosticString(),
602fd4e5da5Sopenharmony_ci      HasSubstr("Expected int scalar or vector type as Result Type: BitCount"));
603fd4e5da5Sopenharmony_ci}
604fd4e5da5Sopenharmony_ci
605fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountBaseNotInt) {
606fd4e5da5Sopenharmony_ci  const std::string body = R"(
607fd4e5da5Sopenharmony_ci%val1 = OpBitCount %u32 %f64_1
608fd4e5da5Sopenharmony_ci)";
609fd4e5da5Sopenharmony_ci
610fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
611fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
612fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
613fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-04781"));
614fd4e5da5Sopenharmony_ci  EXPECT_THAT(
615fd4e5da5Sopenharmony_ci      getDiagnosticString(),
616fd4e5da5Sopenharmony_ci      HasSubstr(
617fd4e5da5Sopenharmony_ci          "Expected int scalar or vector type for Base operand: BitCount"));
618fd4e5da5Sopenharmony_ci}
619fd4e5da5Sopenharmony_ci
620fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountBaseWrongDimension) {
621fd4e5da5Sopenharmony_ci  const std::string body = R"(
622fd4e5da5Sopenharmony_ci%val1 = OpBitCount %u32 %u32vec2_12
623fd4e5da5Sopenharmony_ci)";
624fd4e5da5Sopenharmony_ci
625fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
626fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
627fd4e5da5Sopenharmony_ci  EXPECT_THAT(
628fd4e5da5Sopenharmony_ci      getDiagnosticString(),
629fd4e5da5Sopenharmony_ci      HasSubstr("Expected Base dimension to be equal to Result Type dimension: "
630fd4e5da5Sopenharmony_ci                "BitCount"));
631fd4e5da5Sopenharmony_ci}
632fd4e5da5Sopenharmony_ci
633fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountNot32Vulkan) {
634fd4e5da5Sopenharmony_ci  const std::string body = R"(
635fd4e5da5Sopenharmony_ci%val1 = OpBitCount %s64 %s64_1
636fd4e5da5Sopenharmony_ci)";
637fd4e5da5Sopenharmony_ci
638fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
639fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
640fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
641fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-04781"));
642fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
643fd4e5da5Sopenharmony_ci              HasSubstr("Expected 32-bit int type for Base operand: BitCount"));
644fd4e5da5Sopenharmony_ci}
645fd4e5da5Sopenharmony_ci
646fd4e5da5Sopenharmony_ciTEST_F(ValidateBitwise, OpBitCountPointer) {
647fd4e5da5Sopenharmony_ci  const std::string body = R"(
648fd4e5da5Sopenharmony_ciOpCapability Shader
649fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
650fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
651fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
652fd4e5da5Sopenharmony_ci%void = OpTypeVoid
653fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
654fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer Function %int
655fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
656fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
657fd4e5da5Sopenharmony_ci%entry = OpLabel
658fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int Function
659fd4e5da5Sopenharmony_ci%count = OpBitCount %int %var
660fd4e5da5Sopenharmony_ciOpReturn
661fd4e5da5Sopenharmony_ciOpFunctionEnd
662fd4e5da5Sopenharmony_ci)";
663fd4e5da5Sopenharmony_ci
664fd4e5da5Sopenharmony_ci  CompileSuccessfully(body);
665fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
666fd4e5da5Sopenharmony_ci  EXPECT_THAT(
667fd4e5da5Sopenharmony_ci      getDiagnosticString(),
668fd4e5da5Sopenharmony_ci      HasSubstr(
669fd4e5da5Sopenharmony_ci          "Expected int scalar or vector type for Base operand: BitCount"));
670fd4e5da5Sopenharmony_ci}
671fd4e5da5Sopenharmony_ci
672fd4e5da5Sopenharmony_ci}  // namespace
673fd4e5da5Sopenharmony_ci}  // namespace val
674fd4e5da5Sopenharmony_ci}  // namespace spvtools
675