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// Validation tests for illegal literals
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include <string>
18fd4e5da5Sopenharmony_ci#include <utility>
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_ci#include "gmock/gmock.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_ci
29fd4e5da5Sopenharmony_ciusing ValidateLiterals = spvtest::ValidateBase<std::string>;
30fd4e5da5Sopenharmony_ciusing ValidateLiteralsShader = spvtest::ValidateBase<std::string>;
31fd4e5da5Sopenharmony_ciusing ValidateLiteralsKernel = spvtest::ValidateBase<std::string>;
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_cistd::string GenerateShaderCode() {
34fd4e5da5Sopenharmony_ci  std::string str = R"(
35fd4e5da5Sopenharmony_ci          OpCapability Shader
36fd4e5da5Sopenharmony_ci          OpCapability Linkage
37fd4e5da5Sopenharmony_ci          OpCapability Int16
38fd4e5da5Sopenharmony_ci          OpCapability Int64
39fd4e5da5Sopenharmony_ci          OpCapability Float16
40fd4e5da5Sopenharmony_ci          OpCapability Float64
41fd4e5da5Sopenharmony_ci          OpMemoryModel Logical GLSL450
42fd4e5da5Sopenharmony_ci%int16  = OpTypeInt 16 1
43fd4e5da5Sopenharmony_ci%uint16 = OpTypeInt 16 0
44fd4e5da5Sopenharmony_ci%int32  = OpTypeInt 32 1
45fd4e5da5Sopenharmony_ci%uint32 = OpTypeInt 32 0
46fd4e5da5Sopenharmony_ci%int64  = OpTypeInt 64 1
47fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
48fd4e5da5Sopenharmony_ci%half   = OpTypeFloat 16
49fd4e5da5Sopenharmony_ci%float  = OpTypeFloat 32
50fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64
51fd4e5da5Sopenharmony_ci%10     = OpTypeVoid
52fd4e5da5Sopenharmony_ci    )";
53fd4e5da5Sopenharmony_ci  return str;
54fd4e5da5Sopenharmony_ci}
55fd4e5da5Sopenharmony_ci
56fd4e5da5Sopenharmony_cistd::string GenerateKernelCode() {
57fd4e5da5Sopenharmony_ci  std::string str = R"(
58fd4e5da5Sopenharmony_ci          OpCapability Kernel
59fd4e5da5Sopenharmony_ci          OpCapability Addresses
60fd4e5da5Sopenharmony_ci          OpCapability Linkage
61fd4e5da5Sopenharmony_ci          OpCapability Int8
62fd4e5da5Sopenharmony_ci          OpMemoryModel Physical64 OpenCL
63fd4e5da5Sopenharmony_ci%uint8  = OpTypeInt 8 0
64fd4e5da5Sopenharmony_ci    )";
65fd4e5da5Sopenharmony_ci  return str;
66fd4e5da5Sopenharmony_ci}
67fd4e5da5Sopenharmony_ci
68fd4e5da5Sopenharmony_ciTEST_F(ValidateLiterals, LiteralsShaderGood) {
69fd4e5da5Sopenharmony_ci  std::string str = GenerateShaderCode() + R"(
70fd4e5da5Sopenharmony_ci%11 = OpConstant %int16   !0x00007FFF
71fd4e5da5Sopenharmony_ci%12 = OpConstant %int16   !0xFFFF8000
72fd4e5da5Sopenharmony_ci%13 = OpConstant %int16   !0xFFFFABCD
73fd4e5da5Sopenharmony_ci%14 = OpConstant %uint16  !0x0000ABCD
74fd4e5da5Sopenharmony_ci%15 = OpConstant %int16  -32768
75fd4e5da5Sopenharmony_ci%16 = OpConstant %uint16  65535
76fd4e5da5Sopenharmony_ci%17 = OpConstant %int32  -2147483648
77fd4e5da5Sopenharmony_ci%18 = OpConstant %uint32  4294967295
78fd4e5da5Sopenharmony_ci%19 = OpConstant %int64  -9223372036854775808
79fd4e5da5Sopenharmony_ci%20 = OpConstant %uint64  18446744073709551615
80fd4e5da5Sopenharmony_ci%21 = OpConstant %half    !0x0000FFFF
81fd4e5da5Sopenharmony_ci%22 = OpConstant %float   !0xFFFFFFFF
82fd4e5da5Sopenharmony_ci%23 = OpConstant %double  !0xFFFFFFFF !0xFFFFFFFF
83fd4e5da5Sopenharmony_ci  )";
84fd4e5da5Sopenharmony_ci  CompileSuccessfully(str);
85fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
86fd4e5da5Sopenharmony_ci}
87fd4e5da5Sopenharmony_ci
88fd4e5da5Sopenharmony_ciTEST_F(ValidateLiterals, InvalidInt) {
89fd4e5da5Sopenharmony_ci  std::string str = GenerateShaderCode() + R"(
90fd4e5da5Sopenharmony_ci%11 = OpTypeInt 32 90
91fd4e5da5Sopenharmony_ci  )";
92fd4e5da5Sopenharmony_ci  CompileSuccessfully(str);
93fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions());
94fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
95fd4e5da5Sopenharmony_ci              HasSubstr("OpTypeInt has invalid signedness:"));
96fd4e5da5Sopenharmony_ci}
97fd4e5da5Sopenharmony_ci
98fd4e5da5Sopenharmony_ciTEST_P(ValidateLiteralsShader, LiteralsShaderBad) {
99fd4e5da5Sopenharmony_ci  std::string str = GenerateShaderCode() + GetParam();
100fd4e5da5Sopenharmony_ci  std::string inst_id = "11";
101fd4e5da5Sopenharmony_ci  CompileSuccessfully(str);
102fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions());
103fd4e5da5Sopenharmony_ci  EXPECT_THAT(
104fd4e5da5Sopenharmony_ci      getDiagnosticString(),
105fd4e5da5Sopenharmony_ci      HasSubstr("The high-order bits of a literal number in instruction <id> " +
106fd4e5da5Sopenharmony_ci                inst_id +
107fd4e5da5Sopenharmony_ci                " must be 0 for a floating-point type, "
108fd4e5da5Sopenharmony_ci                "or 0 for an integer type with Signedness of 0, "
109fd4e5da5Sopenharmony_ci                "or sign extended when Signedness is 1"));
110fd4e5da5Sopenharmony_ci}
111fd4e5da5Sopenharmony_ci
112fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
113fd4e5da5Sopenharmony_ci    LiteralsShaderCases, ValidateLiteralsShader,
114fd4e5da5Sopenharmony_ci    ::testing::Values("%11 = OpConstant %int16  !0xFFFF0000",  // Sign bit is 0
115fd4e5da5Sopenharmony_ci                      "%11 = OpConstant %int16  !0x00008000",  // Sign bit is 1
116fd4e5da5Sopenharmony_ci                      "%11 = OpConstant %int16  !0xABCD8000",  // Sign bit is 1
117fd4e5da5Sopenharmony_ci                      "%11 = OpConstant %int16  !0xABCD0000",
118fd4e5da5Sopenharmony_ci                      "%11 = OpConstant %uint16 !0xABCD0000",
119fd4e5da5Sopenharmony_ci                      "%11 = OpConstant %half   !0xABCD0000",
120fd4e5da5Sopenharmony_ci                      "%11 = OpConstant %half   !0x00010000"));
121fd4e5da5Sopenharmony_ci
122fd4e5da5Sopenharmony_ciTEST_F(ValidateLiterals, LiteralsKernelGood) {
123fd4e5da5Sopenharmony_ci  std::string str = GenerateKernelCode() + R"(
124fd4e5da5Sopenharmony_ci%4  = OpConstant %uint8  !0x000000AB
125fd4e5da5Sopenharmony_ci%6  = OpConstant %uint8  255
126fd4e5da5Sopenharmony_ci  )";
127fd4e5da5Sopenharmony_ci  CompileSuccessfully(str);
128fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
129fd4e5da5Sopenharmony_ci}
130fd4e5da5Sopenharmony_ci
131fd4e5da5Sopenharmony_ciTEST_P(ValidateLiteralsKernel, LiteralsKernelBad) {
132fd4e5da5Sopenharmony_ci  std::string str = GenerateKernelCode() + GetParam();
133fd4e5da5Sopenharmony_ci  std::string inst_id = "2";
134fd4e5da5Sopenharmony_ci  CompileSuccessfully(str);
135fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions());
136fd4e5da5Sopenharmony_ci  EXPECT_THAT(
137fd4e5da5Sopenharmony_ci      getDiagnosticString(),
138fd4e5da5Sopenharmony_ci      HasSubstr("The high-order bits of a literal number in instruction <id> " +
139fd4e5da5Sopenharmony_ci                inst_id +
140fd4e5da5Sopenharmony_ci                " must be 0 for a floating-point type, "
141fd4e5da5Sopenharmony_ci                "or 0 for an integer type with Signedness of 0, "
142fd4e5da5Sopenharmony_ci                "or sign extended when Signedness is 1"));
143fd4e5da5Sopenharmony_ci}
144fd4e5da5Sopenharmony_ci
145fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
146fd4e5da5Sopenharmony_ci    LiteralsKernelCases, ValidateLiteralsKernel,
147fd4e5da5Sopenharmony_ci    ::testing::Values("%2 = OpConstant %uint8  !0xABCDEF00",
148fd4e5da5Sopenharmony_ci                      "%2 = OpConstant %uint8  !0xABCDEFFF"));
149fd4e5da5Sopenharmony_ci
150fd4e5da5Sopenharmony_ci}  // namespace
151fd4e5da5Sopenharmony_ci}  // namespace val
152fd4e5da5Sopenharmony_ci}  // namespace spvtools
153