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_P(ValidateLiteralsShader,LiteralsShaderBad)88 TEST_P(ValidateLiteralsShader, LiteralsShaderBad) {
89 std::string str = GenerateShaderCode() + GetParam();
90 std::string inst_id = "11";
91 CompileSuccessfully(str);
92 EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions());
93 EXPECT_THAT(
94 getDiagnosticString(),
95 HasSubstr("The high-order bits of a literal number in instruction <id> " +
96 inst_id +
97 " must be 0 for a floating-point type, "
98 "or 0 for an integer type with Signedness of 0, "
99 "or sign extended when Signedness is 1"));
100 }
101
102 INSTANTIATE_TEST_CASE_P(
103 LiteralsShaderCases, ValidateLiteralsShader,
104 ::testing::Values("%11 = OpConstant %int16 !0xFFFF0000", // Sign bit is 0
105 "%11 = OpConstant %int16 !0x00008000", // Sign bit is 1
106 "%11 = OpConstant %int16 !0xABCD8000", // Sign bit is 1
107 "%11 = OpConstant %int16 !0xABCD0000",
108 "%11 = OpConstant %uint16 !0xABCD0000",
109 "%11 = OpConstant %half !0xABCD0000",
110 "%11 = OpConstant %half !0x00010000"));
111
TEST_F(ValidateLiterals,LiteralsKernelGood)112 TEST_F(ValidateLiterals, LiteralsKernelGood) {
113 std::string str = GenerateKernelCode() + R"(
114 %4 = OpConstant %uint8 !0x000000AB
115 %6 = OpConstant %uint8 255
116 )";
117 CompileSuccessfully(str);
118 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
119 }
120
TEST_P(ValidateLiteralsKernel,LiteralsKernelBad)121 TEST_P(ValidateLiteralsKernel, LiteralsKernelBad) {
122 std::string str = GenerateKernelCode() + GetParam();
123 std::string inst_id = "2";
124 CompileSuccessfully(str);
125 EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions());
126 EXPECT_THAT(
127 getDiagnosticString(),
128 HasSubstr("The high-order bits of a literal number in instruction <id> " +
129 inst_id +
130 " must be 0 for a floating-point type, "
131 "or 0 for an integer type with Signedness of 0, "
132 "or sign extended when Signedness is 1"));
133 }
134
135 INSTANTIATE_TEST_CASE_P(
136 LiteralsKernelCases, ValidateLiteralsKernel,
137 ::testing::Values("%2 = OpConstant %uint8 !0xABCDEF00",
138 "%2 = OpConstant %uint8 !0xABCDEFFF"));
139
140 } // namespace
141 } // namespace val
142 } // namespace spvtools
143