val_bitwise_test.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  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. // Tests for unique type declaration rules validator.
  15. #include <string>
  16. #include "gmock/gmock.h"
  17. #include "test/unit_spirv.h"
  18. #include "test/val/val_fixtures.h"
  19. namespace spvtools {
  20. namespace val {
  21. namespace {
  22. using ::testing::HasSubstr;
  23. using ::testing::Not;
  24. using ValidateBitwise = spvtest::ValidateBase<bool>;
  25. std::string GenerateShaderCode(
  26. const std::string& body,
  27. const std::string& capabilities_and_extensions = "") {
  28. const std::string capabilities =
  29. R"(
  30. OpCapability Shader
  31. OpCapability Int64
  32. OpCapability Float64)";
  33. const std::string after_extension_before_body =
  34. R"(
  35. OpMemoryModel Logical GLSL450
  36. OpEntryPoint Fragment %main "main"
  37. OpExecutionMode %main OriginUpperLeft
  38. %void = OpTypeVoid
  39. %func = OpTypeFunction %void
  40. %bool = OpTypeBool
  41. %f32 = OpTypeFloat 32
  42. %u32 = OpTypeInt 32 0
  43. %s32 = OpTypeInt 32 1
  44. %f64 = OpTypeFloat 64
  45. %u64 = OpTypeInt 64 0
  46. %s64 = OpTypeInt 64 1
  47. %boolvec2 = OpTypeVector %bool 2
  48. %s32vec2 = OpTypeVector %s32 2
  49. %u32vec2 = OpTypeVector %u32 2
  50. %u64vec2 = OpTypeVector %u64 2
  51. %f32vec2 = OpTypeVector %f32 2
  52. %f64vec2 = OpTypeVector %f64 2
  53. %boolvec3 = OpTypeVector %bool 3
  54. %u32vec3 = OpTypeVector %u32 3
  55. %u64vec3 = OpTypeVector %u64 3
  56. %s32vec3 = OpTypeVector %s32 3
  57. %f32vec3 = OpTypeVector %f32 3
  58. %f64vec3 = OpTypeVector %f64 3
  59. %boolvec4 = OpTypeVector %bool 4
  60. %u32vec4 = OpTypeVector %u32 4
  61. %u64vec4 = OpTypeVector %u64 4
  62. %s32vec4 = OpTypeVector %s32 4
  63. %f32vec4 = OpTypeVector %f32 4
  64. %f64vec4 = OpTypeVector %f64 4
  65. %f32_0 = OpConstant %f32 0
  66. %f32_1 = OpConstant %f32 1
  67. %f32_2 = OpConstant %f32 2
  68. %f32_3 = OpConstant %f32 3
  69. %f32_4 = OpConstant %f32 4
  70. %s32_0 = OpConstant %s32 0
  71. %s32_1 = OpConstant %s32 1
  72. %s32_2 = OpConstant %s32 2
  73. %s32_3 = OpConstant %s32 3
  74. %s32_4 = OpConstant %s32 4
  75. %s32_m1 = OpConstant %s32 -1
  76. %u32_0 = OpConstant %u32 0
  77. %u32_1 = OpConstant %u32 1
  78. %u32_2 = OpConstant %u32 2
  79. %u32_3 = OpConstant %u32 3
  80. %u32_4 = OpConstant %u32 4
  81. %f64_0 = OpConstant %f64 0
  82. %f64_1 = OpConstant %f64 1
  83. %f64_2 = OpConstant %f64 2
  84. %f64_3 = OpConstant %f64 3
  85. %f64_4 = OpConstant %f64 4
  86. %s64_0 = OpConstant %s64 0
  87. %s64_1 = OpConstant %s64 1
  88. %s64_2 = OpConstant %s64 2
  89. %s64_3 = OpConstant %s64 3
  90. %s64_4 = OpConstant %s64 4
  91. %s64_m1 = OpConstant %s64 -1
  92. %u64_0 = OpConstant %u64 0
  93. %u64_1 = OpConstant %u64 1
  94. %u64_2 = OpConstant %u64 2
  95. %u64_3 = OpConstant %u64 3
  96. %u64_4 = OpConstant %u64 4
  97. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  98. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  99. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  100. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  101. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  102. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  103. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  104. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  105. %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
  106. %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
  107. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  108. %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
  109. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  110. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  111. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  112. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  113. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  114. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  115. %main = OpFunction %void None %func
  116. %main_entry = OpLabel)";
  117. const std::string after_body =
  118. R"(
  119. OpReturn
  120. OpFunctionEnd)";
  121. return capabilities + capabilities_and_extensions +
  122. after_extension_before_body + body + after_body;
  123. }
  124. TEST_F(ValidateBitwise, ShiftAllSuccess) {
  125. const std::string body = R"(
  126. %val1 = OpShiftRightLogical %u64 %u64_1 %s32_2
  127. %val2 = OpShiftRightArithmetic %s32vec2 %s32vec2_12 %s32vec2_12
  128. %val3 = OpShiftLeftLogical %u32vec2 %s32vec2_12 %u32vec2_12
  129. )";
  130. CompileSuccessfully(GenerateShaderCode(body).c_str());
  131. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  132. }
  133. TEST_F(ValidateBitwise, OpShiftRightLogicalWrongResultType) {
  134. const std::string body = R"(
  135. %val1 = OpShiftRightLogical %bool %u64_1 %s32_2
  136. )";
  137. CompileSuccessfully(GenerateShaderCode(body).c_str());
  138. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  139. EXPECT_THAT(getDiagnosticString(),
  140. HasSubstr("Expected int scalar or vector type as Result Type: "
  141. "ShiftRightLogical"));
  142. }
  143. TEST_F(ValidateBitwise, OpShiftRightLogicalBaseNotInt) {
  144. const std::string body = R"(
  145. %val1 = OpShiftRightLogical %u32 %f32_1 %s32_2
  146. )";
  147. CompileSuccessfully(GenerateShaderCode(body).c_str());
  148. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  149. EXPECT_THAT(
  150. getDiagnosticString(),
  151. HasSubstr("Expected Base to be int scalar or vector: ShiftRightLogical"));
  152. }
  153. TEST_F(ValidateBitwise, OpShiftRightLogicalBaseWrongDimension) {
  154. const std::string body = R"(
  155. %val1 = OpShiftRightLogical %u32 %u32vec2_12 %s32_2
  156. )";
  157. CompileSuccessfully(GenerateShaderCode(body).c_str());
  158. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  159. EXPECT_THAT(
  160. getDiagnosticString(),
  161. HasSubstr("Expected Base to have the same dimension as Result Type: "
  162. "ShiftRightLogical"));
  163. }
  164. TEST_F(ValidateBitwise, OpShiftRightLogicalBaseWrongBitWidth) {
  165. const std::string body = R"(
  166. %val1 = OpShiftRightLogical %u64 %u32_1 %s32_2
  167. )";
  168. CompileSuccessfully(GenerateShaderCode(body).c_str());
  169. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  170. EXPECT_THAT(
  171. getDiagnosticString(),
  172. HasSubstr("Expected Base to have the same bit width as Result Type: "
  173. "ShiftRightLogical"));
  174. }
  175. TEST_F(ValidateBitwise, OpShiftRightLogicalShiftNotInt) {
  176. const std::string body = R"(
  177. %val1 = OpShiftRightLogical %u32 %u32_1 %f32_2
  178. )";
  179. CompileSuccessfully(GenerateShaderCode(body).c_str());
  180. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  181. EXPECT_THAT(
  182. getDiagnosticString(),
  183. HasSubstr(
  184. "Expected Shift to be int scalar or vector: ShiftRightLogical"));
  185. }
  186. TEST_F(ValidateBitwise, OpShiftRightLogicalShiftWrongDimension) {
  187. const std::string body = R"(
  188. %val1 = OpShiftRightLogical %u32 %u32_1 %s32vec2_12
  189. )";
  190. CompileSuccessfully(GenerateShaderCode(body).c_str());
  191. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  192. EXPECT_THAT(
  193. getDiagnosticString(),
  194. HasSubstr("Expected Shift to have the same dimension as Result Type: "
  195. "ShiftRightLogical"));
  196. }
  197. TEST_F(ValidateBitwise, LogicAllSuccess) {
  198. const std::string body = R"(
  199. %val1 = OpBitwiseOr %u64 %u64_1 %s64_0
  200. %val2 = OpBitwiseAnd %s64 %s64_1 %u64_0
  201. %val3 = OpBitwiseXor %s32vec2 %s32vec2_12 %u32vec2_01
  202. %val4 = OpNot %s32vec2 %u32vec2_01
  203. )";
  204. CompileSuccessfully(GenerateShaderCode(body).c_str());
  205. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  206. }
  207. TEST_F(ValidateBitwise, OpBitwiseAndWrongResultType) {
  208. const std::string body = R"(
  209. %val1 = OpBitwiseAnd %bool %u64_1 %s32_2
  210. )";
  211. CompileSuccessfully(GenerateShaderCode(body).c_str());
  212. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  213. EXPECT_THAT(
  214. getDiagnosticString(),
  215. HasSubstr(
  216. "Expected int scalar or vector type as Result Type: BitwiseAnd"));
  217. }
  218. TEST_F(ValidateBitwise, OpBitwiseAndLeftNotInt) {
  219. const std::string body = R"(
  220. %val1 = OpBitwiseAnd %u32 %f32_1 %s32_2
  221. )";
  222. CompileSuccessfully(GenerateShaderCode(body).c_str());
  223. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  224. EXPECT_THAT(getDiagnosticString(),
  225. HasSubstr("Expected int scalar or vector as operand: BitwiseAnd "
  226. "operand index 2"));
  227. }
  228. TEST_F(ValidateBitwise, OpBitwiseAndRightNotInt) {
  229. const std::string body = R"(
  230. %val1 = OpBitwiseAnd %u32 %u32_1 %f32_2
  231. )";
  232. CompileSuccessfully(GenerateShaderCode(body).c_str());
  233. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  234. EXPECT_THAT(getDiagnosticString(),
  235. HasSubstr("Expected int scalar or vector as operand: BitwiseAnd "
  236. "operand index 3"));
  237. }
  238. TEST_F(ValidateBitwise, OpBitwiseAndLeftWrongDimension) {
  239. const std::string body = R"(
  240. %val1 = OpBitwiseAnd %u32 %u32vec2_12 %s32_2
  241. )";
  242. CompileSuccessfully(GenerateShaderCode(body).c_str());
  243. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  244. EXPECT_THAT(
  245. getDiagnosticString(),
  246. HasSubstr("Expected operands to have the same dimension as Result Type: "
  247. "BitwiseAnd operand index 2"));
  248. }
  249. TEST_F(ValidateBitwise, OpBitwiseAndRightWrongDimension) {
  250. const std::string body = R"(
  251. %val1 = OpBitwiseAnd %u32 %s32_2 %u32vec2_12
  252. )";
  253. CompileSuccessfully(GenerateShaderCode(body).c_str());
  254. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  255. EXPECT_THAT(
  256. getDiagnosticString(),
  257. HasSubstr("Expected operands to have the same dimension as Result Type: "
  258. "BitwiseAnd operand index 3"));
  259. }
  260. TEST_F(ValidateBitwise, OpBitwiseAndLeftWrongBitWidth) {
  261. const std::string body = R"(
  262. %val1 = OpBitwiseAnd %u64 %u32_1 %s64_2
  263. )";
  264. CompileSuccessfully(GenerateShaderCode(body).c_str());
  265. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  266. EXPECT_THAT(
  267. getDiagnosticString(),
  268. HasSubstr("Expected operands to have the same bit width as Result Type: "
  269. "BitwiseAnd operand index 2"));
  270. }
  271. TEST_F(ValidateBitwise, OpBitwiseAndRightWrongBitWidth) {
  272. const std::string body = R"(
  273. %val1 = OpBitwiseAnd %u64 %u64_1 %s32_2
  274. )";
  275. CompileSuccessfully(GenerateShaderCode(body).c_str());
  276. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  277. EXPECT_THAT(
  278. getDiagnosticString(),
  279. HasSubstr("Expected operands to have the same bit width as Result Type: "
  280. "BitwiseAnd operand index 3"));
  281. }
  282. TEST_F(ValidateBitwise, OpBitFieldInsertSuccess) {
  283. const std::string body = R"(
  284. %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
  285. %val2 = OpBitFieldInsert %s32vec2 %s32vec2_12 %s32vec2_12 %s32_1 %u32_2
  286. )";
  287. CompileSuccessfully(GenerateShaderCode(body).c_str());
  288. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  289. }
  290. TEST_F(ValidateBitwise, OpBitFieldInsertVulkanSuccess) {
  291. const std::string body = R"(
  292. %val1 = OpBitFieldInsert %u32 %u32_1 %u32_2 %s32_1 %s32_2
  293. %val2 = OpBitFieldInsert %s32vec2 %s32vec2_12 %s32vec2_12 %s32_1 %u32_2
  294. )";
  295. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  296. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  297. }
  298. TEST_F(ValidateBitwise, OpBitFieldInsertWrongResultType) {
  299. const std::string body = R"(
  300. %val1 = OpBitFieldInsert %bool %u64_1 %u64_2 %s32_1 %s32_2
  301. )";
  302. CompileSuccessfully(GenerateShaderCode(body).c_str());
  303. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  304. EXPECT_THAT(
  305. getDiagnosticString(),
  306. HasSubstr(
  307. "Expected Base Type to be equal to Result Type: BitFieldInsert"));
  308. }
  309. TEST_F(ValidateBitwise, OpBitFieldInsertWrongBaseType) {
  310. const std::string body = R"(
  311. %val1 = OpBitFieldInsert %u64 %s64_1 %u64_2 %s32_1 %s32_2
  312. )";
  313. CompileSuccessfully(GenerateShaderCode(body).c_str());
  314. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  315. EXPECT_THAT(
  316. getDiagnosticString(),
  317. HasSubstr(
  318. "Expected Base Type to be equal to Result Type: BitFieldInsert"));
  319. }
  320. TEST_F(ValidateBitwise, OpBitFieldInsertWrongInsertType) {
  321. const std::string body = R"(
  322. %val1 = OpBitFieldInsert %u64 %u64_1 %s64_2 %s32_1 %s32_2
  323. )";
  324. CompileSuccessfully(GenerateShaderCode(body).c_str());
  325. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  326. EXPECT_THAT(
  327. getDiagnosticString(),
  328. HasSubstr(
  329. "Expected Insert Type to be equal to Result Type: BitFieldInsert"));
  330. }
  331. TEST_F(ValidateBitwise, OpBitFieldInsertOffsetNotInt) {
  332. const std::string body = R"(
  333. %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %f32_1 %s32_2
  334. )";
  335. CompileSuccessfully(GenerateShaderCode(body).c_str());
  336. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  337. EXPECT_THAT(
  338. getDiagnosticString(),
  339. HasSubstr("Expected Offset Type to be int scalar: BitFieldInsert"));
  340. }
  341. TEST_F(ValidateBitwise, OpBitFieldInsertCountNotInt) {
  342. const std::string body = R"(
  343. %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %u32_1 %f32_2
  344. )";
  345. CompileSuccessfully(GenerateShaderCode(body).c_str());
  346. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  347. EXPECT_THAT(
  348. getDiagnosticString(),
  349. HasSubstr("Expected Count Type to be int scalar: BitFieldInsert"));
  350. }
  351. TEST_F(ValidateBitwise, OpBitFieldInsertNot32Vulkan) {
  352. const std::string body = R"(
  353. %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
  354. )";
  355. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  356. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  357. EXPECT_THAT(getDiagnosticString(),
  358. AnyVUID("VUID-StandaloneSpirv-Base-04781"));
  359. EXPECT_THAT(
  360. getDiagnosticString(),
  361. HasSubstr("Expected 32-bit int type for Base operand: BitFieldInsert"));
  362. }
  363. TEST_F(ValidateBitwise, OpBitFieldInsertNot32Allow) {
  364. const std::string body = R"(
  365. %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
  366. )";
  367. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  368. spvValidatorOptionsSetAllowVulkan32BitBitwise(getValidatorOptions(), true);
  369. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  370. }
  371. TEST_F(ValidateBitwise, OpBitFieldSExtractSuccess) {
  372. const std::string body = R"(
  373. %val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
  374. %val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
  375. )";
  376. CompileSuccessfully(GenerateShaderCode(body).c_str());
  377. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  378. }
  379. TEST_F(ValidateBitwise, OpBitFieldSExtractVulkanSuccess) {
  380. const std::string body = R"(
  381. %val1 = OpBitFieldSExtract %u32 %u32_1 %s32_1 %s32_2
  382. %val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
  383. )";
  384. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  385. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  386. }
  387. TEST_F(ValidateBitwise, OpBitFieldSExtractWrongResultType) {
  388. const std::string body = R"(
  389. %val1 = OpBitFieldSExtract %bool %u64_1 %s32_1 %s32_2
  390. )";
  391. CompileSuccessfully(GenerateShaderCode(body).c_str());
  392. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  393. EXPECT_THAT(
  394. getDiagnosticString(),
  395. HasSubstr(
  396. "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
  397. }
  398. TEST_F(ValidateBitwise, OpBitFieldSExtractWrongBaseType) {
  399. const std::string body = R"(
  400. %val1 = OpBitFieldSExtract %u64 %s64_1 %s32_1 %s32_2
  401. )";
  402. CompileSuccessfully(GenerateShaderCode(body).c_str());
  403. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  404. EXPECT_THAT(
  405. getDiagnosticString(),
  406. HasSubstr(
  407. "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
  408. }
  409. TEST_F(ValidateBitwise, OpBitFieldSExtractOffsetNotInt) {
  410. const std::string body = R"(
  411. %val1 = OpBitFieldSExtract %u64 %u64_1 %f32_1 %s32_2
  412. )";
  413. CompileSuccessfully(GenerateShaderCode(body).c_str());
  414. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  415. EXPECT_THAT(
  416. getDiagnosticString(),
  417. HasSubstr("Expected Offset Type to be int scalar: BitFieldSExtract"));
  418. }
  419. TEST_F(ValidateBitwise, OpBitFieldSExtractCountNotInt) {
  420. const std::string body = R"(
  421. %val1 = OpBitFieldSExtract %u64 %u64_1 %u32_1 %f32_2
  422. )";
  423. CompileSuccessfully(GenerateShaderCode(body).c_str());
  424. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  425. EXPECT_THAT(
  426. getDiagnosticString(),
  427. HasSubstr("Expected Count Type to be int scalar: BitFieldSExtract"));
  428. }
  429. TEST_F(ValidateBitwise, OpBitFieldSExtractNot32Vulkan) {
  430. const std::string body = R"(
  431. %val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
  432. )";
  433. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  434. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  435. EXPECT_THAT(getDiagnosticString(),
  436. AnyVUID("VUID-StandaloneSpirv-Base-04781"));
  437. EXPECT_THAT(
  438. getDiagnosticString(),
  439. HasSubstr("Expected 32-bit int type for Base operand: BitFieldSExtract"));
  440. }
  441. TEST_F(ValidateBitwise, OpBitReverseSuccess) {
  442. const std::string body = R"(
  443. %val1 = OpBitReverse %u64 %u64_1
  444. %val2 = OpBitReverse %s32vec2 %s32vec2_12
  445. )";
  446. CompileSuccessfully(GenerateShaderCode(body).c_str());
  447. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  448. }
  449. TEST_F(ValidateBitwise, OpBitReverseVulkanSuccess) {
  450. const std::string body = R"(
  451. %val1 = OpBitReverse %u32 %u32_1
  452. %val2 = OpBitReverse %s32vec2 %s32vec2_12
  453. )";
  454. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  455. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  456. }
  457. TEST_F(ValidateBitwise, OpBitReverseWrongResultType) {
  458. const std::string body = R"(
  459. %val1 = OpBitReverse %bool %u64_1
  460. )";
  461. CompileSuccessfully(GenerateShaderCode(body).c_str());
  462. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  463. EXPECT_THAT(
  464. getDiagnosticString(),
  465. HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
  466. }
  467. TEST_F(ValidateBitwise, OpBitReverseWrongBaseType) {
  468. const std::string body = R"(
  469. %val1 = OpBitReverse %u64 %s64_1
  470. )";
  471. CompileSuccessfully(GenerateShaderCode(body).c_str());
  472. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  473. EXPECT_THAT(
  474. getDiagnosticString(),
  475. HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
  476. }
  477. TEST_F(ValidateBitwise, OpBitReverseNot32Vulkan) {
  478. const std::string body = R"(
  479. %val1 = OpBitReverse %u64 %u64_1
  480. )";
  481. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  482. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  483. EXPECT_THAT(getDiagnosticString(),
  484. AnyVUID("VUID-StandaloneSpirv-Base-04781"));
  485. EXPECT_THAT(
  486. getDiagnosticString(),
  487. HasSubstr("Expected 32-bit int type for Base operand: BitReverse"));
  488. }
  489. TEST_F(ValidateBitwise, OpBitCountSuccess) {
  490. const std::string body = R"(
  491. %val1 = OpBitCount %s32 %u64_1
  492. %val2 = OpBitCount %u32vec2 %s32vec2_12
  493. %val3 = OpBitCount %s64 %s64_1
  494. )";
  495. CompileSuccessfully(GenerateShaderCode(body).c_str());
  496. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  497. }
  498. TEST_F(ValidateBitwise, OpBitCountVulkanSuccess) {
  499. const std::string body = R"(
  500. %val1 = OpBitCount %s32 %u32_1
  501. %val2 = OpBitCount %u32vec2 %s32vec2_12
  502. )";
  503. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  504. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  505. }
  506. TEST_F(ValidateBitwise, OpBitCountWrongResultType) {
  507. const std::string body = R"(
  508. %val1 = OpBitCount %bool %u64_1
  509. )";
  510. CompileSuccessfully(GenerateShaderCode(body).c_str());
  511. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  512. EXPECT_THAT(
  513. getDiagnosticString(),
  514. HasSubstr("Expected int scalar or vector type as Result Type: BitCount"));
  515. }
  516. TEST_F(ValidateBitwise, OpBitCountBaseNotInt) {
  517. const std::string body = R"(
  518. %val1 = OpBitCount %u32 %f64_1
  519. )";
  520. CompileSuccessfully(GenerateShaderCode(body).c_str());
  521. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  522. EXPECT_THAT(
  523. getDiagnosticString(),
  524. HasSubstr(
  525. "Expected int scalar or vector type for Base operand: BitCount"));
  526. }
  527. TEST_F(ValidateBitwise, OpBitCountBaseWrongDimension) {
  528. const std::string body = R"(
  529. %val1 = OpBitCount %u32 %u32vec2_12
  530. )";
  531. CompileSuccessfully(GenerateShaderCode(body).c_str());
  532. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  533. EXPECT_THAT(
  534. getDiagnosticString(),
  535. HasSubstr("Expected Base dimension to be equal to Result Type dimension: "
  536. "BitCount"));
  537. }
  538. TEST_F(ValidateBitwise, OpBitCountNot32Vulkan) {
  539. const std::string body = R"(
  540. %val1 = OpBitCount %s64 %s64_1
  541. )";
  542. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
  543. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  544. EXPECT_THAT(getDiagnosticString(),
  545. AnyVUID("VUID-StandaloneSpirv-Base-04781"));
  546. EXPECT_THAT(getDiagnosticString(),
  547. HasSubstr("Expected 32-bit int type for Base operand: BitCount"));
  548. }
  549. TEST_F(ValidateBitwise, OpBitCountPointer) {
  550. const std::string body = R"(
  551. OpCapability Shader
  552. OpMemoryModel Logical GLSL450
  553. OpEntryPoint GLCompute %main "main"
  554. OpExecutionMode %main LocalSize 1 1 1
  555. %void = OpTypeVoid
  556. %int = OpTypeInt 32 0
  557. %ptr_int = OpTypePointer Function %int
  558. %void_fn = OpTypeFunction %void
  559. %main = OpFunction %void None %void_fn
  560. %entry = OpLabel
  561. %var = OpVariable %ptr_int Function
  562. %count = OpBitCount %int %var
  563. OpReturn
  564. OpFunctionEnd
  565. )";
  566. CompileSuccessfully(body);
  567. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  568. EXPECT_THAT(
  569. getDiagnosticString(),
  570. HasSubstr(
  571. "Expected int scalar or vector type for Base operand: BitCount"));
  572. }
  573. } // namespace
  574. } // namespace val
  575. } // namespace spvtools