val_data_test.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. // Copyright (c) 2016 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. // Validation tests for Data Rules.
  15. #include <string>
  16. #include <utility>
  17. #include "gmock/gmock.h"
  18. #include "test/unit_spirv.h"
  19. #include "test/val/val_fixtures.h"
  20. namespace spvtools {
  21. namespace val {
  22. namespace {
  23. using ::testing::HasSubstr;
  24. using ::testing::MatchesRegex;
  25. using ValidateData = spvtest::ValidateBase<std::pair<std::string, bool>>;
  26. std::string HeaderWith(std::string cap) {
  27. return std::string("OpCapability Shader OpCapability Linkage OpCapability ") +
  28. cap + " OpMemoryModel Logical GLSL450 ";
  29. }
  30. std::string header = R"(
  31. OpCapability Shader
  32. OpCapability Linkage
  33. OpMemoryModel Logical GLSL450
  34. )";
  35. std::string header_with_addresses = R"(
  36. OpCapability Addresses
  37. OpCapability Kernel
  38. OpCapability GenericPointer
  39. OpCapability Linkage
  40. OpMemoryModel Physical32 OpenCL
  41. )";
  42. std::string header_with_vec16_cap = R"(
  43. OpCapability Shader
  44. OpCapability Vector16
  45. OpCapability Linkage
  46. OpMemoryModel Logical GLSL450
  47. )";
  48. std::string header_with_int8 = R"(
  49. OpCapability Shader
  50. OpCapability Linkage
  51. OpCapability Int8
  52. OpMemoryModel Logical GLSL450
  53. )";
  54. std::string header_with_int16 = R"(
  55. OpCapability Shader
  56. OpCapability Linkage
  57. OpCapability Int16
  58. OpMemoryModel Logical GLSL450
  59. )";
  60. std::string header_with_int64 = R"(
  61. OpCapability Shader
  62. OpCapability Linkage
  63. OpCapability Int64
  64. OpMemoryModel Logical GLSL450
  65. )";
  66. std::string header_with_float16 = R"(
  67. OpCapability Shader
  68. OpCapability Linkage
  69. OpCapability Float16
  70. OpMemoryModel Logical GLSL450
  71. )";
  72. std::string header_with_float16_buffer = R"(
  73. OpCapability Shader
  74. OpCapability Linkage
  75. OpCapability Float16Buffer
  76. OpMemoryModel Logical GLSL450
  77. )";
  78. std::string header_with_float64 = R"(
  79. OpCapability Shader
  80. OpCapability Linkage
  81. OpCapability Float64
  82. OpMemoryModel Logical GLSL450
  83. )";
  84. std::string invalid_comp_error = "Illegal number of components";
  85. std::string missing_cap_error = "requires the Vector16 capability";
  86. std::string missing_int8_cap_error = "requires the Int8 capability";
  87. std::string missing_int16_cap_error =
  88. "requires the Int16 capability,"
  89. " or an extension that explicitly enables 16-bit integers.";
  90. std::string missing_int64_cap_error = "requires the Int64 capability";
  91. std::string missing_float16_cap_error =
  92. "requires the Float16 or Float16Buffer capability,"
  93. " or an extension that explicitly enables 16-bit floating point.";
  94. std::string missing_float64_cap_error = "requires the Float64 capability";
  95. std::string invalid_num_bits_error = "Invalid number of bits";
  96. TEST_F(ValidateData, vec0) {
  97. std::string str = header + R"(
  98. %1 = OpTypeFloat 32
  99. %2 = OpTypeVector %1 0
  100. )";
  101. CompileSuccessfully(str.c_str());
  102. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  103. EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_comp_error));
  104. }
  105. TEST_F(ValidateData, vec1) {
  106. std::string str = header + R"(
  107. %1 = OpTypeFloat 32
  108. %2 = OpTypeVector %1 1
  109. )";
  110. CompileSuccessfully(str.c_str());
  111. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  112. EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_comp_error));
  113. }
  114. TEST_F(ValidateData, vec2) {
  115. std::string str = header + R"(
  116. %1 = OpTypeFloat 32
  117. %2 = OpTypeVector %1 2
  118. )";
  119. CompileSuccessfully(str.c_str());
  120. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  121. }
  122. TEST_F(ValidateData, vec3) {
  123. std::string str = header + R"(
  124. %1 = OpTypeFloat 32
  125. %2 = OpTypeVector %1 3
  126. )";
  127. CompileSuccessfully(str.c_str());
  128. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  129. }
  130. TEST_F(ValidateData, vec4) {
  131. std::string str = header + R"(
  132. %1 = OpTypeFloat 32
  133. %2 = OpTypeVector %1 4
  134. )";
  135. CompileSuccessfully(str.c_str());
  136. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  137. }
  138. TEST_F(ValidateData, vec5) {
  139. std::string str = header + R"(
  140. %1 = OpTypeFloat 32
  141. %2 = OpTypeVector %1 5
  142. )";
  143. CompileSuccessfully(str.c_str());
  144. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  145. EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_comp_error));
  146. }
  147. TEST_F(ValidateData, vec8) {
  148. std::string str = header + R"(
  149. %1 = OpTypeFloat 32
  150. %2 = OpTypeVector %1 8
  151. )";
  152. CompileSuccessfully(str.c_str());
  153. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  154. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_cap_error));
  155. }
  156. TEST_F(ValidateData, vec8_with_capability) {
  157. std::string str = header_with_vec16_cap + R"(
  158. %1 = OpTypeFloat 32
  159. %2 = OpTypeVector %1 8
  160. )";
  161. CompileSuccessfully(str.c_str());
  162. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  163. }
  164. TEST_F(ValidateData, vec16) {
  165. std::string str = header + R"(
  166. %1 = OpTypeFloat 32
  167. %2 = OpTypeVector %1 8
  168. )";
  169. CompileSuccessfully(str.c_str());
  170. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  171. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_cap_error));
  172. }
  173. TEST_F(ValidateData, vec16_with_capability) {
  174. std::string str = header_with_vec16_cap + R"(
  175. %1 = OpTypeFloat 32
  176. %2 = OpTypeVector %1 16
  177. )";
  178. CompileSuccessfully(str.c_str());
  179. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  180. }
  181. TEST_F(ValidateData, vec15) {
  182. std::string str = header + R"(
  183. %1 = OpTypeFloat 32
  184. %2 = OpTypeVector %1 15
  185. )";
  186. CompileSuccessfully(str.c_str());
  187. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  188. EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_comp_error));
  189. }
  190. TEST_F(ValidateData, int8_good) {
  191. std::string str = header_with_int8 + "%2 = OpTypeInt 8 0";
  192. CompileSuccessfully(str.c_str());
  193. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  194. }
  195. TEST_F(ValidateData, int8_bad) {
  196. std::string str = header + "%2 = OpTypeInt 8 1";
  197. CompileSuccessfully(str.c_str());
  198. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  199. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int8_cap_error));
  200. }
  201. TEST_F(ValidateData, int8_with_storage_buffer_8bit_access_good) {
  202. std::string str = HeaderWith(
  203. "StorageBuffer8BitAccess "
  204. "OpExtension \"SPV_KHR_8bit_storage\"") +
  205. " %2 = OpTypeInt 8 0";
  206. CompileSuccessfully(str.c_str());
  207. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()) << getDiagnosticString();
  208. }
  209. TEST_F(ValidateData, int8_with_uniform_and_storage_buffer_8bit_access_good) {
  210. std::string str = HeaderWith(
  211. "UniformAndStorageBuffer8BitAccess "
  212. "OpExtension \"SPV_KHR_8bit_storage\"") +
  213. " %2 = OpTypeInt 8 0";
  214. CompileSuccessfully(str.c_str());
  215. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()) << getDiagnosticString();
  216. }
  217. TEST_F(ValidateData, int8_with_storage_push_constant_8_good) {
  218. std::string str = HeaderWith(
  219. "StoragePushConstant8 "
  220. "OpExtension \"SPV_KHR_8bit_storage\"") +
  221. " %2 = OpTypeInt 8 0";
  222. CompileSuccessfully(str.c_str());
  223. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()) << getDiagnosticString();
  224. }
  225. TEST_F(ValidateData, int16_good) {
  226. std::string str = header_with_int16 + "%2 = OpTypeInt 16 1";
  227. CompileSuccessfully(str.c_str());
  228. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  229. }
  230. TEST_F(ValidateData, storage_uniform_buffer_block_16_good) {
  231. std::string str = HeaderWith(
  232. "StorageUniformBufferBlock16 "
  233. "OpExtension \"SPV_KHR_16bit_storage\"") +
  234. "%2 = OpTypeInt 16 1 %3 = OpTypeFloat 16";
  235. CompileSuccessfully(str.c_str());
  236. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  237. }
  238. TEST_F(ValidateData, storage_uniform_16_good) {
  239. std::string str =
  240. HeaderWith("StorageUniform16 OpExtension \"SPV_KHR_16bit_storage\"") +
  241. "%2 = OpTypeInt 16 1 %3 = OpTypeFloat 16";
  242. CompileSuccessfully(str.c_str());
  243. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  244. }
  245. TEST_F(ValidateData, storage_push_constant_16_good) {
  246. std::string str = HeaderWith(
  247. "StoragePushConstant16 "
  248. "OpExtension \"SPV_KHR_16bit_storage\"") +
  249. "%2 = OpTypeInt 16 1 %3 = OpTypeFloat 16";
  250. CompileSuccessfully(str.c_str());
  251. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  252. }
  253. TEST_F(ValidateData, storage_input_output_16_good) {
  254. std::string str = HeaderWith(
  255. "StorageInputOutput16 "
  256. "OpExtension \"SPV_KHR_16bit_storage\"") +
  257. "%2 = OpTypeInt 16 1 %3 = OpTypeFloat 16";
  258. CompileSuccessfully(str.c_str());
  259. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  260. }
  261. TEST_F(ValidateData, amd_gpu_shader_half_float_fetch_16_good) {
  262. std::string str = R"(
  263. OpCapability Shader
  264. OpCapability Linkage
  265. OpExtension "SPV_AMD_gpu_shader_half_float_fetch"
  266. OpMemoryModel Logical GLSL450
  267. %2 = OpTypeFloat 16)";
  268. CompileSuccessfully(str.c_str());
  269. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  270. }
  271. TEST_F(ValidateData, int16_bad) {
  272. std::string str = header + "%2 = OpTypeInt 16 1";
  273. CompileSuccessfully(str.c_str());
  274. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  275. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int16_cap_error));
  276. }
  277. TEST_F(ValidateData, int64_good) {
  278. std::string str = header_with_int64 + "%2 = OpTypeInt 64 1";
  279. CompileSuccessfully(str.c_str());
  280. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  281. }
  282. TEST_F(ValidateData, int64_bad) {
  283. std::string str = header + "%2 = OpTypeInt 64 1";
  284. CompileSuccessfully(str.c_str());
  285. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  286. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int64_cap_error));
  287. }
  288. // Number of bits in an integer may be only one of: {8,16,32,64}
  289. TEST_F(ValidateData, int_invalid_num_bits) {
  290. std::string str = header + "%2 = OpTypeInt 48 1";
  291. CompileSuccessfully(str.c_str());
  292. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  293. EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_num_bits_error));
  294. }
  295. TEST_F(ValidateData, float16_good) {
  296. std::string str = header_with_float16 + "%2 = OpTypeFloat 16";
  297. CompileSuccessfully(str.c_str());
  298. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  299. }
  300. TEST_F(ValidateData, float16_buffer_good) {
  301. std::string str = header_with_float16_buffer + "%2 = OpTypeFloat 16";
  302. CompileSuccessfully(str.c_str());
  303. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  304. }
  305. TEST_F(ValidateData, float16_bad) {
  306. std::string str = header + "%2 = OpTypeFloat 16";
  307. CompileSuccessfully(str.c_str());
  308. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  309. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_float16_cap_error));
  310. }
  311. TEST_F(ValidateData, float64_good) {
  312. std::string str = header_with_float64 + "%2 = OpTypeFloat 64";
  313. CompileSuccessfully(str.c_str());
  314. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  315. }
  316. TEST_F(ValidateData, float64_bad) {
  317. std::string str = header + "%2 = OpTypeFloat 64";
  318. CompileSuccessfully(str.c_str());
  319. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  320. EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_float64_cap_error));
  321. }
  322. // Number of bits in a float may be only one of: {16,32,64}
  323. TEST_F(ValidateData, float_invalid_num_bits) {
  324. std::string str = header + "%2 = OpTypeFloat 48";
  325. CompileSuccessfully(str.c_str());
  326. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  327. EXPECT_THAT(getDiagnosticString(), HasSubstr(invalid_num_bits_error));
  328. }
  329. TEST_F(ValidateData, matrix_data_type_float) {
  330. std::string str = header + R"(
  331. %f32 = OpTypeFloat 32
  332. %vec3 = OpTypeVector %f32 3
  333. %mat33 = OpTypeMatrix %vec3 3
  334. )";
  335. CompileSuccessfully(str.c_str());
  336. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  337. }
  338. TEST_F(ValidateData, ids_should_be_validated_before_data) {
  339. std::string str = header + R"(
  340. %f32 = OpTypeFloat 32
  341. %mat33 = OpTypeMatrix %vec3 3
  342. )";
  343. CompileSuccessfully(str.c_str());
  344. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  345. EXPECT_THAT(getDiagnosticString(),
  346. HasSubstr("Operand '3[%3]' requires a previous definition"));
  347. }
  348. TEST_F(ValidateData, matrix_bad_column_type) {
  349. std::string str = header + R"(
  350. %f32 = OpTypeFloat 32
  351. %mat33 = OpTypeMatrix %f32 3
  352. )";
  353. CompileSuccessfully(str.c_str());
  354. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  355. EXPECT_THAT(getDiagnosticString(),
  356. HasSubstr("Columns in a matrix must be of type vector"));
  357. }
  358. TEST_F(ValidateData, matrix_data_type_int) {
  359. std::string str = header + R"(
  360. %int32 = OpTypeInt 32 1
  361. %vec3 = OpTypeVector %int32 3
  362. %mat33 = OpTypeMatrix %vec3 3
  363. )";
  364. CompileSuccessfully(str.c_str());
  365. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  366. EXPECT_THAT(getDiagnosticString(),
  367. HasSubstr("can only be parameterized with floating-point types"));
  368. }
  369. TEST_F(ValidateData, matrix_data_type_bool) {
  370. std::string str = header + R"(
  371. %boolt = OpTypeBool
  372. %vec3 = OpTypeVector %boolt 3
  373. %mat33 = OpTypeMatrix %vec3 3
  374. )";
  375. CompileSuccessfully(str.c_str());
  376. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  377. EXPECT_THAT(getDiagnosticString(),
  378. HasSubstr("can only be parameterized with floating-point types"));
  379. }
  380. TEST_F(ValidateData, matrix_with_0_columns) {
  381. std::string str = header + R"(
  382. %f32 = OpTypeFloat 32
  383. %vec3 = OpTypeVector %f32 3
  384. %mat33 = OpTypeMatrix %vec3 0
  385. )";
  386. CompileSuccessfully(str.c_str());
  387. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  388. EXPECT_THAT(
  389. getDiagnosticString(),
  390. HasSubstr("can only be parameterized as having only 2, 3, or 4 columns"));
  391. }
  392. TEST_F(ValidateData, matrix_with_1_column) {
  393. std::string str = header + R"(
  394. %f32 = OpTypeFloat 32
  395. %vec3 = OpTypeVector %f32 3
  396. %mat33 = OpTypeMatrix %vec3 1
  397. )";
  398. CompileSuccessfully(str.c_str());
  399. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  400. EXPECT_THAT(
  401. getDiagnosticString(),
  402. HasSubstr("can only be parameterized as having only 2, 3, or 4 columns"));
  403. }
  404. TEST_F(ValidateData, matrix_with_2_columns) {
  405. std::string str = header + R"(
  406. %f32 = OpTypeFloat 32
  407. %vec3 = OpTypeVector %f32 3
  408. %mat33 = OpTypeMatrix %vec3 2
  409. )";
  410. CompileSuccessfully(str.c_str());
  411. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  412. }
  413. TEST_F(ValidateData, matrix_with_3_columns) {
  414. std::string str = header + R"(
  415. %f32 = OpTypeFloat 32
  416. %vec3 = OpTypeVector %f32 3
  417. %mat33 = OpTypeMatrix %vec3 3
  418. )";
  419. CompileSuccessfully(str.c_str());
  420. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  421. }
  422. TEST_F(ValidateData, matrix_with_4_columns) {
  423. std::string str = header + R"(
  424. %f32 = OpTypeFloat 32
  425. %vec3 = OpTypeVector %f32 3
  426. %mat33 = OpTypeMatrix %vec3 4
  427. )";
  428. CompileSuccessfully(str.c_str());
  429. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  430. }
  431. TEST_F(ValidateData, matrix_with_5_column) {
  432. std::string str = header + R"(
  433. %f32 = OpTypeFloat 32
  434. %vec3 = OpTypeVector %f32 3
  435. %mat33 = OpTypeMatrix %vec3 5
  436. )";
  437. CompileSuccessfully(str.c_str());
  438. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  439. EXPECT_THAT(
  440. getDiagnosticString(),
  441. HasSubstr("can only be parameterized as having only 2, 3, or 4 columns"));
  442. }
  443. TEST_F(ValidateData, specialize_int) {
  444. std::string str = header + R"(
  445. %i32 = OpTypeInt 32 1
  446. %len = OpSpecConstant %i32 2)";
  447. CompileSuccessfully(str.c_str());
  448. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  449. }
  450. TEST_F(ValidateData, specialize_float) {
  451. std::string str = header + R"(
  452. %f32 = OpTypeFloat 32
  453. %len = OpSpecConstant %f32 2)";
  454. CompileSuccessfully(str.c_str());
  455. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  456. }
  457. TEST_F(ValidateData, specialize_boolean) {
  458. std::string str = header + R"(
  459. %2 = OpTypeBool
  460. %3 = OpSpecConstantTrue %2
  461. %4 = OpSpecConstantFalse %2)";
  462. CompileSuccessfully(str.c_str());
  463. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  464. }
  465. TEST_F(ValidateData, specialize_boolean_true_to_int) {
  466. std::string str = header + R"(
  467. %2 = OpTypeInt 32 1
  468. %3 = OpSpecConstantTrue %2)";
  469. CompileSuccessfully(str.c_str());
  470. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  471. EXPECT_THAT(getDiagnosticString(),
  472. HasSubstr("OpSpecConstantTrue Result Type <id> '1[%int]' is not "
  473. "a boolean type"));
  474. }
  475. TEST_F(ValidateData, specialize_boolean_false_to_int) {
  476. std::string str = header + R"(
  477. %2 = OpTypeInt 32 1
  478. %4 = OpSpecConstantFalse %2)";
  479. CompileSuccessfully(str.c_str());
  480. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  481. EXPECT_THAT(getDiagnosticString(),
  482. HasSubstr("OpSpecConstantFalse Result Type <id> '1[%int]' is not "
  483. "a boolean type"));
  484. }
  485. TEST_F(ValidateData, missing_forward_pointer_decl) {
  486. std::string str = header_with_addresses + R"(
  487. %uintt = OpTypeInt 32 0
  488. %3 = OpTypeStruct %fwd_ptrt %uintt
  489. )";
  490. CompileSuccessfully(str.c_str());
  491. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  492. EXPECT_THAT(getDiagnosticString(),
  493. HasSubstr("Operand '3[%3]' requires a previous definition"));
  494. }
  495. TEST_F(ValidateData, missing_forward_pointer_decl_self_reference) {
  496. std::string str = header_with_addresses + R"(
  497. %uintt = OpTypeInt 32 0
  498. %3 = OpTypeStruct %3 %uintt
  499. )";
  500. CompileSuccessfully(str.c_str());
  501. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  502. EXPECT_THAT(
  503. getDiagnosticString(),
  504. HasSubstr("Operand '2[%_struct_2]' requires a previous definition"));
  505. }
  506. TEST_F(ValidateData, forward_pointer_missing_definition) {
  507. std::string str = header_with_addresses + R"(
  508. OpTypeForwardPointer %_ptr_Generic_struct_A Generic
  509. %uintt = OpTypeInt 32 0
  510. %struct_B = OpTypeStruct %uintt %_ptr_Generic_struct_A
  511. )";
  512. CompileSuccessfully(str.c_str());
  513. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  514. EXPECT_THAT(getDiagnosticString(),
  515. HasSubstr("forward referenced IDs have not been defined"));
  516. }
  517. TEST_F(ValidateData, forward_ref_bad_type) {
  518. std::string str = header_with_addresses + R"(
  519. OpTypeForwardPointer %_ptr_Generic_struct_A Generic
  520. %uintt = OpTypeInt 32 0
  521. %struct_B = OpTypeStruct %uintt %_ptr_Generic_struct_A
  522. %_ptr_Generic_struct_A = OpTypeFloat 32
  523. )";
  524. CompileSuccessfully(str.c_str());
  525. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  526. EXPECT_THAT(getDiagnosticString(),
  527. HasSubstr("Pointer type in OpTypeForwardPointer is not a pointer "
  528. "type.\n OpTypeForwardPointer %float Generic\n"));
  529. }
  530. TEST_F(ValidateData, forward_ref_points_to_non_struct) {
  531. std::string str = header_with_addresses + R"(
  532. OpTypeForwardPointer %_ptr_Generic_struct_A Generic
  533. %uintt = OpTypeInt 32 0
  534. %struct_B = OpTypeStruct %uintt %_ptr_Generic_struct_A
  535. %_ptr_Generic_struct_A = OpTypePointer Generic %uintt
  536. )";
  537. CompileSuccessfully(str.c_str());
  538. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  539. EXPECT_THAT(getDiagnosticString(),
  540. HasSubstr("Forward pointers must point to a structure"));
  541. }
  542. TEST_F(ValidateData, struct_forward_pointer_good) {
  543. std::string str = header_with_addresses + R"(
  544. OpTypeForwardPointer %_ptr_Generic_struct_A Generic
  545. %uintt = OpTypeInt 32 0
  546. %struct_B = OpTypeStruct %uintt %_ptr_Generic_struct_A
  547. %struct_C = OpTypeStruct %uintt %struct_B
  548. %struct_A = OpTypeStruct %uintt %struct_C
  549. %_ptr_Generic_struct_A = OpTypePointer Generic %struct_C
  550. )";
  551. CompileSuccessfully(str.c_str());
  552. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  553. }
  554. TEST_F(ValidateData, ext_16bit_storage_caps_allow_free_fp_rounding_mode) {
  555. for (const char* cap : {"StorageUniform16", "StorageUniformBufferBlock16"}) {
  556. for (const char* mode : {"RTE", "RTZ", "RTP", "RTN"}) {
  557. std::string str = std::string(R"(
  558. OpCapability Shader
  559. OpCapability Linkage
  560. OpCapability )") +
  561. cap + R"(
  562. OpExtension "SPV_KHR_storage_buffer_storage_class"
  563. OpExtension "SPV_KHR_variable_pointers"
  564. OpExtension "SPV_KHR_16bit_storage"
  565. OpMemoryModel Logical GLSL450
  566. OpDecorate %_ FPRoundingMode )" + mode + R"(
  567. %half = OpTypeFloat 16
  568. %float = OpTypeFloat 32
  569. %float_1_25 = OpConstant %float 1.25
  570. %half_ptr = OpTypePointer StorageBuffer %half
  571. %half_ptr_var = OpVariable %half_ptr StorageBuffer
  572. %void = OpTypeVoid
  573. %func = OpTypeFunction %void
  574. %main = OpFunction %void None %func
  575. %main_entry = OpLabel
  576. %_ = OpFConvert %half %float_1_25
  577. OpStore %half_ptr_var %_
  578. OpReturn
  579. OpFunctionEnd
  580. )";
  581. CompileSuccessfully(str.c_str());
  582. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  583. }
  584. }
  585. }
  586. TEST_F(ValidateData, vulkan_disallow_free_fp_rounding_mode) {
  587. for (const char* mode : {"RTE", "RTZ"}) {
  588. for (const auto env : {SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1}) {
  589. std::string str = std::string(R"(
  590. OpCapability Shader
  591. OpExtension "SPV_KHR_storage_buffer_storage_class"
  592. OpExtension "SPV_KHR_variable_pointers"
  593. OpMemoryModel Logical GLSL450
  594. OpDecorate %_ FPRoundingMode )") +
  595. mode + R"(
  596. %half = OpTypeFloat 16
  597. %float = OpTypeFloat 32
  598. %float_1_25 = OpConstant %float 1.25
  599. %half_ptr = OpTypePointer StorageBuffer %half
  600. %half_ptr_var = OpVariable %half_ptr StorageBuffer
  601. %void = OpTypeVoid
  602. %func = OpTypeFunction %void
  603. %main = OpFunction %void None %func
  604. %main_entry = OpLabel
  605. %_ = OpFConvert %half %float_1_25
  606. OpStore %half_ptr_var %_
  607. OpReturn
  608. OpFunctionEnd
  609. )";
  610. CompileSuccessfully(str.c_str());
  611. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions(env));
  612. EXPECT_THAT(
  613. getDiagnosticString(),
  614. HasSubstr(
  615. "Operand 2 of Decorate requires one of these capabilities: "
  616. "StorageBuffer16BitAccess UniformAndStorageBuffer16BitAccess "
  617. "StoragePushConstant16 StorageInputOutput16"));
  618. }
  619. }
  620. }
  621. TEST_F(ValidateData, void_array) {
  622. std::string str = header + R"(
  623. %void = OpTypeVoid
  624. %int = OpTypeInt 32 0
  625. %int_5 = OpConstant %int 5
  626. %array = OpTypeArray %void %int_5
  627. )";
  628. CompileSuccessfully(str.c_str());
  629. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  630. EXPECT_THAT(
  631. getDiagnosticString(),
  632. HasSubstr("OpTypeArray Element Type <id> '1[%void]' is a void type."));
  633. }
  634. TEST_F(ValidateData, void_runtime_array) {
  635. std::string str = header + R"(
  636. %void = OpTypeVoid
  637. %array = OpTypeRuntimeArray %void
  638. )";
  639. CompileSuccessfully(str.c_str());
  640. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  641. EXPECT_THAT(
  642. getDiagnosticString(),
  643. HasSubstr(
  644. "OpTypeRuntimeArray Element Type <id> '1[%void]' is a void type."));
  645. }
  646. TEST_F(ValidateData, vulkan_RTA_array_at_end_of_struct) {
  647. std::string str = R"(
  648. OpCapability Shader
  649. OpMemoryModel Logical GLSL450
  650. OpEntryPoint Fragment %func "func"
  651. OpExecutionMode %func OriginUpperLeft
  652. OpDecorate %array_t ArrayStride 4
  653. OpMemberDecorate %struct_t 0 Offset 0
  654. OpMemberDecorate %struct_t 1 Offset 4
  655. OpDecorate %struct_t Block
  656. %uint_t = OpTypeInt 32 0
  657. %array_t = OpTypeRuntimeArray %uint_t
  658. %struct_t = OpTypeStruct %uint_t %array_t
  659. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  660. %2 = OpVariable %struct_ptr StorageBuffer
  661. %void = OpTypeVoid
  662. %func_t = OpTypeFunction %void
  663. %func = OpFunction %void None %func_t
  664. %1 = OpLabel
  665. OpReturn
  666. OpFunctionEnd
  667. )";
  668. CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_1);
  669. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  670. }
  671. TEST_F(ValidateData, vulkan_RTA_not_at_end_of_struct) {
  672. std::string str = R"(
  673. OpCapability Shader
  674. OpMemoryModel Logical GLSL450
  675. OpEntryPoint Fragment %func "func"
  676. OpExecutionMode %func OriginUpperLeft
  677. OpDecorate %array_t ArrayStride 4
  678. OpMemberDecorate %struct_t 0 Offset 0
  679. OpMemberDecorate %struct_t 1 Offset 4
  680. OpDecorate %struct_t Block
  681. %uint_t = OpTypeInt 32 0
  682. %array_t = OpTypeRuntimeArray %uint_t
  683. %struct_t = OpTypeStruct %array_t %uint_t
  684. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  685. %2 = OpVariable %struct_ptr StorageBuffer
  686. %void = OpTypeVoid
  687. %func_t = OpTypeFunction %void
  688. %func = OpFunction %void None %func_t
  689. %1 = OpLabel
  690. OpReturn
  691. OpFunctionEnd
  692. )";
  693. CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_1);
  694. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  695. EXPECT_THAT(getDiagnosticString(),
  696. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  697. EXPECT_THAT(getDiagnosticString(),
  698. HasSubstr("In Vulkan, OpTypeRuntimeArray must only be used for "
  699. "the last member of an OpTypeStruct\n %_struct_3 = "
  700. "OpTypeStruct %_runtimearr_uint %uint\n"));
  701. }
  702. TEST_F(ValidateData, TypeForwardReference) {
  703. std::string test = R"(
  704. OpCapability Shader
  705. OpCapability PhysicalStorageBufferAddresses
  706. OpCapability Linkage
  707. OpMemoryModel Logical GLSL450
  708. OpTypeForwardPointer %1 PhysicalStorageBuffer
  709. %2 = OpTypeStruct
  710. %3 = OpTypeRuntimeArray %1
  711. %1 = OpTypePointer PhysicalStorageBuffer %2
  712. )";
  713. CompileSuccessfully(test, SPV_ENV_UNIVERSAL_1_5);
  714. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  715. }
  716. TEST_F(ValidateData, VulkanTypeForwardStorageClass) {
  717. std::string test = R"(
  718. OpCapability Shader
  719. OpCapability PhysicalStorageBufferAddresses
  720. OpMemoryModel Logical GLSL450
  721. OpTypeForwardPointer %1 Uniform
  722. %2 = OpTypeStruct
  723. %3 = OpTypeRuntimeArray %1
  724. %1 = OpTypePointer Uniform %2
  725. )";
  726. CompileSuccessfully(test, SPV_ENV_VULKAN_1_2);
  727. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  728. EXPECT_THAT(getDiagnosticString(),
  729. AnyVUID("VUID-StandaloneSpirv-OpTypeForwardPointer-04711"));
  730. EXPECT_THAT(getDiagnosticString(),
  731. HasSubstr("In Vulkan, OpTypeForwardPointer must have "
  732. "a storage class of PhysicalStorageBuffer."));
  733. }
  734. TEST_F(ValidateData, TypeForwardReferenceMustBeForwardPointer) {
  735. std::string test = R"(
  736. OpCapability Shader
  737. OpCapability PhysicalStorageBufferAddresses
  738. OpCapability Linkage
  739. OpMemoryModel Logical GLSL450
  740. %1 = OpTypeStruct
  741. %2 = OpTypeRuntimeArray %3
  742. %3 = OpTypePointer PhysicalStorageBuffer %1
  743. )";
  744. CompileSuccessfully(test, SPV_ENV_UNIVERSAL_1_5);
  745. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  746. EXPECT_THAT(getDiagnosticString(),
  747. HasSubstr("Operand '3[%_ptr_PhysicalStorageBuffer__struct_1]' "
  748. "requires a previous definition"));
  749. }
  750. } // namespace
  751. } // namespace val
  752. } // namespace spvtools