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