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