val_logicals_test.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  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::Eq;
  23. using ::testing::HasSubstr;
  24. using ::testing::Not;
  25. using ValidateLogicals = spvtest::ValidateBase<bool>;
  26. std::string GenerateShaderCode(
  27. const std::string& body,
  28. const std::string& capabilities_and_extensions = "") {
  29. const std::string capabilities =
  30. R"(
  31. OpCapability Shader
  32. OpCapability Int64
  33. OpCapability Float64)";
  34. const std::string after_extension_before_body =
  35. R"(
  36. %ext_inst = OpExtInstImport "GLSL.std.450"
  37. OpMemoryModel Logical GLSL450
  38. OpEntryPoint Fragment %main "main"
  39. OpExecutionMode %main OriginUpperLeft
  40. %void = OpTypeVoid
  41. %func = OpTypeFunction %void
  42. %bool = OpTypeBool
  43. %f32 = OpTypeFloat 32
  44. %u32 = OpTypeInt 32 0
  45. %s32 = OpTypeInt 32 1
  46. %f64 = OpTypeFloat 64
  47. %u64 = OpTypeInt 64 0
  48. %s64 = OpTypeInt 64 1
  49. %boolvec2 = OpTypeVector %bool 2
  50. %s32vec2 = OpTypeVector %s32 2
  51. %u32vec2 = OpTypeVector %u32 2
  52. %u64vec2 = OpTypeVector %u64 2
  53. %f32vec2 = OpTypeVector %f32 2
  54. %f64vec2 = OpTypeVector %f64 2
  55. %boolvec3 = OpTypeVector %bool 3
  56. %u32vec3 = OpTypeVector %u32 3
  57. %u64vec3 = OpTypeVector %u64 3
  58. %s32vec3 = OpTypeVector %s32 3
  59. %f32vec3 = OpTypeVector %f32 3
  60. %f64vec3 = OpTypeVector %f64 3
  61. %boolvec4 = OpTypeVector %bool 4
  62. %u32vec4 = OpTypeVector %u32 4
  63. %u64vec4 = OpTypeVector %u64 4
  64. %s32vec4 = OpTypeVector %s32 4
  65. %f32vec4 = OpTypeVector %f32 4
  66. %f64vec4 = OpTypeVector %f64 4
  67. %f32_0 = OpConstant %f32 0
  68. %f32_1 = OpConstant %f32 1
  69. %f32_2 = OpConstant %f32 2
  70. %f32_3 = OpConstant %f32 3
  71. %f32_4 = OpConstant %f32 4
  72. %s32_0 = OpConstant %s32 0
  73. %s32_1 = OpConstant %s32 1
  74. %s32_2 = OpConstant %s32 2
  75. %s32_3 = OpConstant %s32 3
  76. %s32_4 = OpConstant %s32 4
  77. %s32_m1 = OpConstant %s32 -1
  78. %u32_0 = OpConstant %u32 0
  79. %u32_1 = OpConstant %u32 1
  80. %u32_2 = OpConstant %u32 2
  81. %u32_3 = OpConstant %u32 3
  82. %u32_4 = OpConstant %u32 4
  83. %f64_0 = OpConstant %f64 0
  84. %f64_1 = OpConstant %f64 1
  85. %f64_2 = OpConstant %f64 2
  86. %f64_3 = OpConstant %f64 3
  87. %f64_4 = OpConstant %f64 4
  88. %s64_0 = OpConstant %s64 0
  89. %s64_1 = OpConstant %s64 1
  90. %s64_2 = OpConstant %s64 2
  91. %s64_3 = OpConstant %s64 3
  92. %s64_4 = OpConstant %s64 4
  93. %s64_m1 = OpConstant %s64 -1
  94. %u64_0 = OpConstant %u64 0
  95. %u64_1 = OpConstant %u64 1
  96. %u64_2 = OpConstant %u64 2
  97. %u64_3 = OpConstant %u64 3
  98. %u64_4 = OpConstant %u64 4
  99. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  100. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  101. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  102. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  103. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  104. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  105. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  106. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  107. %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
  108. %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
  109. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  110. %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
  111. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  112. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  113. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  114. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  115. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  116. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  117. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  118. %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2
  119. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  120. %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3
  121. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  122. %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4
  123. %true = OpConstantTrue %bool
  124. %false = OpConstantFalse %bool
  125. %boolvec2_tf = OpConstantComposite %boolvec2 %true %false
  126. %boolvec3_tft = OpConstantComposite %boolvec3 %true %false %true
  127. %boolvec4_tftf = OpConstantComposite %boolvec4 %true %false %true %false
  128. %arr_u32_2 = OpTypeArray %u32 %u32_2
  129. %st_u32_u32 = OpTypeStruct %u32 %u32
  130. %mat_f32_2_2 = OpTypeMatrix %f32vec2 2
  131. %nul_arr_u32_2 = OpConstantNull %arr_u32_2
  132. %nul_st_u32_u32 = OpConstantNull %st_u32_u32
  133. %nul_mat_f32_2_2 = OpConstantNull %mat_f32_2_2
  134. %arr_u32_2_1_2 = OpConstantComposite %arr_u32_2 %u32_1 %u32_2
  135. %st_u32_u32_1_2 = OpConstantComposite %st_u32_u32 %u32_1 %u32_2
  136. %mat_f32_2_2_01_12 = OpConstantComposite %mat_f32_2_2 %f32vec2_01 %f32vec2_12
  137. %f32vec4ptr = OpTypePointer Function %f32vec4
  138. %main = OpFunction %void None %func
  139. %main_entry = OpLabel)";
  140. const std::string after_body =
  141. R"(
  142. OpReturn
  143. OpFunctionEnd)";
  144. return capabilities + capabilities_and_extensions +
  145. after_extension_before_body + body + after_body;
  146. }
  147. std::string GenerateKernelCode(
  148. const std::string& body,
  149. const std::string& capabilities_and_extensions = "") {
  150. const std::string capabilities =
  151. R"(
  152. OpCapability Addresses
  153. OpCapability Kernel
  154. OpCapability Linkage
  155. OpCapability Int64
  156. OpCapability Float64)";
  157. const std::string after_extension_before_body =
  158. R"(
  159. OpMemoryModel Physical32 OpenCL
  160. %void = OpTypeVoid
  161. %func = OpTypeFunction %void
  162. %bool = OpTypeBool
  163. %f32 = OpTypeFloat 32
  164. %u32 = OpTypeInt 32 0
  165. %f64 = OpTypeFloat 64
  166. %u64 = OpTypeInt 64 0
  167. %boolvec2 = OpTypeVector %bool 2
  168. %u32vec2 = OpTypeVector %u32 2
  169. %u64vec2 = OpTypeVector %u64 2
  170. %f32vec2 = OpTypeVector %f32 2
  171. %f64vec2 = OpTypeVector %f64 2
  172. %boolvec3 = OpTypeVector %bool 3
  173. %u32vec3 = OpTypeVector %u32 3
  174. %u64vec3 = OpTypeVector %u64 3
  175. %f32vec3 = OpTypeVector %f32 3
  176. %f64vec3 = OpTypeVector %f64 3
  177. %boolvec4 = OpTypeVector %bool 4
  178. %u32vec4 = OpTypeVector %u32 4
  179. %u64vec4 = OpTypeVector %u64 4
  180. %f32vec4 = OpTypeVector %f32 4
  181. %f64vec4 = OpTypeVector %f64 4
  182. %f32_0 = OpConstant %f32 0
  183. %f32_1 = OpConstant %f32 1
  184. %f32_2 = OpConstant %f32 2
  185. %f32_3 = OpConstant %f32 3
  186. %f32_4 = OpConstant %f32 4
  187. %u32_0 = OpConstant %u32 0
  188. %u32_1 = OpConstant %u32 1
  189. %u32_2 = OpConstant %u32 2
  190. %u32_3 = OpConstant %u32 3
  191. %u32_4 = OpConstant %u32 4
  192. %f64_0 = OpConstant %f64 0
  193. %f64_1 = OpConstant %f64 1
  194. %f64_2 = OpConstant %f64 2
  195. %f64_3 = OpConstant %f64 3
  196. %f64_4 = OpConstant %f64 4
  197. %u64_0 = OpConstant %u64 0
  198. %u64_1 = OpConstant %u64 1
  199. %u64_2 = OpConstant %u64 2
  200. %u64_3 = OpConstant %u64 3
  201. %u64_4 = OpConstant %u64 4
  202. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  203. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  204. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  205. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  206. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  207. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  208. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  209. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  210. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  211. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  212. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  213. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  214. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  215. %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2
  216. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  217. %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3
  218. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  219. %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4
  220. %true = OpConstantTrue %bool
  221. %false = OpConstantFalse %bool
  222. %boolvec2_tf = OpConstantComposite %boolvec2 %true %false
  223. %boolvec3_tft = OpConstantComposite %boolvec3 %true %false %true
  224. %boolvec4_tftf = OpConstantComposite %boolvec4 %true %false %true %false
  225. %f32vec4ptr = OpTypePointer Function %f32vec4
  226. %main = OpFunction %void None %func
  227. %main_entry = OpLabel)";
  228. const std::string after_body =
  229. R"(
  230. OpReturn
  231. OpFunctionEnd)";
  232. return capabilities + capabilities_and_extensions +
  233. after_extension_before_body + body + after_body;
  234. }
  235. TEST_F(ValidateLogicals, OpAnySuccess) {
  236. const std::string body = R"(
  237. %val1 = OpAny %bool %boolvec2_tf
  238. %val2 = OpAny %bool %boolvec3_tft
  239. %val3 = OpAny %bool %boolvec4_tftf
  240. )";
  241. CompileSuccessfully(GenerateShaderCode(body).c_str());
  242. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  243. }
  244. TEST_F(ValidateLogicals, OpAnyWrongTypeId) {
  245. const std::string body = R"(
  246. %val = OpAny %u32 %boolvec2_tf
  247. )";
  248. CompileSuccessfully(GenerateShaderCode(body).c_str());
  249. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  250. EXPECT_THAT(getDiagnosticString(),
  251. HasSubstr("Expected bool scalar type as Result Type: Any"));
  252. }
  253. TEST_F(ValidateLogicals, OpAnyWrongOperand) {
  254. const std::string body = R"(
  255. %val = OpAny %bool %u32vec3_123
  256. )";
  257. CompileSuccessfully(GenerateShaderCode(body).c_str());
  258. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  259. EXPECT_THAT(getDiagnosticString(),
  260. HasSubstr("Expected operand to be vector bool: Any"));
  261. }
  262. TEST_F(ValidateLogicals, OpIsNanSuccess) {
  263. const std::string body = R"(
  264. %val1 = OpIsNan %bool %f32_1
  265. %val2 = OpIsNan %bool %f64_0
  266. %val3 = OpIsNan %boolvec2 %f32vec2_12
  267. %val4 = OpIsNan %boolvec3 %f32vec3_123
  268. %val5 = OpIsNan %boolvec4 %f32vec4_1234
  269. )";
  270. CompileSuccessfully(GenerateShaderCode(body).c_str());
  271. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  272. }
  273. TEST_F(ValidateLogicals, OpIsNanWrongTypeId) {
  274. const std::string body = R"(
  275. %val1 = OpIsNan %u32 %f32_1
  276. )";
  277. CompileSuccessfully(GenerateShaderCode(body).c_str());
  278. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  279. EXPECT_THAT(
  280. getDiagnosticString(),
  281. HasSubstr("Expected bool scalar or vector type as Result Type: IsNan"));
  282. }
  283. TEST_F(ValidateLogicals, OpIsNanOperandNotFloat) {
  284. const std::string body = R"(
  285. %val1 = OpIsNan %bool %u32_1
  286. )";
  287. CompileSuccessfully(GenerateShaderCode(body).c_str());
  288. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  289. EXPECT_THAT(
  290. getDiagnosticString(),
  291. HasSubstr("Expected operand to be scalar or vector float: IsNan"));
  292. }
  293. TEST_F(ValidateLogicals, OpIsNanOperandWrongSize) {
  294. const std::string body = R"(
  295. %val1 = OpIsNan %bool %f32vec2_12
  296. )";
  297. CompileSuccessfully(GenerateShaderCode(body).c_str());
  298. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  299. EXPECT_THAT(
  300. getDiagnosticString(),
  301. HasSubstr(
  302. "Expected vector sizes of Result Type and the operand to be equal: "
  303. "IsNan"));
  304. }
  305. TEST_F(ValidateLogicals, OpLessOrGreaterSuccess) {
  306. const std::string body = R"(
  307. %val1 = OpLessOrGreater %bool %f32_0 %f32_1
  308. %val2 = OpLessOrGreater %bool %f64_0 %f64_0
  309. %val3 = OpLessOrGreater %boolvec2 %f32vec2_12 %f32vec2_12
  310. %val4 = OpLessOrGreater %boolvec3 %f32vec3_123 %f32vec3_123
  311. %val5 = OpLessOrGreater %boolvec4 %f32vec4_1234 %f32vec4_1234
  312. )";
  313. CompileSuccessfully(GenerateKernelCode(body).c_str());
  314. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  315. }
  316. TEST_F(ValidateLogicals, OpLessOrGreaterWrongTypeId) {
  317. const std::string body = R"(
  318. %val1 = OpLessOrGreater %u32 %f32_1 %f32_1
  319. )";
  320. CompileSuccessfully(GenerateKernelCode(body).c_str());
  321. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  322. EXPECT_THAT(
  323. getDiagnosticString(),
  324. HasSubstr(
  325. "Expected bool scalar or vector type as Result Type: LessOrGreater"));
  326. }
  327. TEST_F(ValidateLogicals, OpLessOrGreaterLeftOperandNotFloat) {
  328. const std::string body = R"(
  329. %val1 = OpLessOrGreater %bool %u32_1 %f32_1
  330. )";
  331. CompileSuccessfully(GenerateKernelCode(body).c_str());
  332. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  333. EXPECT_THAT(
  334. getDiagnosticString(),
  335. HasSubstr(
  336. "Expected operands to be scalar or vector float: LessOrGreater"));
  337. }
  338. TEST_F(ValidateLogicals, OpLessOrGreaterLeftOperandWrongSize) {
  339. const std::string body = R"(
  340. %val1 = OpLessOrGreater %bool %f32vec2_12 %f32_1
  341. )";
  342. CompileSuccessfully(GenerateKernelCode(body).c_str());
  343. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  344. EXPECT_THAT(
  345. getDiagnosticString(),
  346. HasSubstr(
  347. "Expected vector sizes of Result Type and the operands to be equal: "
  348. "LessOrGreater"));
  349. }
  350. TEST_F(ValidateLogicals, OpLessOrGreaterOperandsDifferentType) {
  351. const std::string body = R"(
  352. %val1 = OpLessOrGreater %bool %f32_1 %f64_1
  353. )";
  354. CompileSuccessfully(GenerateKernelCode(body).c_str());
  355. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  356. EXPECT_THAT(
  357. getDiagnosticString(),
  358. HasSubstr("Expected left and right operands to have the same type: "
  359. "LessOrGreater"));
  360. }
  361. TEST_F(ValidateLogicals, OpFOrdEqualSuccess) {
  362. const std::string body = R"(
  363. %val1 = OpFOrdEqual %bool %f32_0 %f32_1
  364. %val2 = OpFOrdEqual %bool %f64_0 %f64_0
  365. %val3 = OpFOrdEqual %boolvec2 %f32vec2_12 %f32vec2_12
  366. %val4 = OpFOrdEqual %boolvec3 %f32vec3_123 %f32vec3_123
  367. %val5 = OpFOrdEqual %boolvec4 %f32vec4_1234 %f32vec4_1234
  368. )";
  369. CompileSuccessfully(GenerateShaderCode(body).c_str());
  370. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  371. }
  372. TEST_F(ValidateLogicals, OpFOrdEqualWrongTypeId) {
  373. const std::string body = R"(
  374. %val1 = OpFOrdEqual %u32 %f32_1 %f32_1
  375. )";
  376. CompileSuccessfully(GenerateShaderCode(body).c_str());
  377. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  378. EXPECT_THAT(
  379. getDiagnosticString(),
  380. HasSubstr(
  381. "Expected bool scalar or vector type as Result Type: FOrdEqual"));
  382. }
  383. TEST_F(ValidateLogicals, OpFOrdEqualLeftOperandNotFloat) {
  384. const std::string body = R"(
  385. %val1 = OpFOrdEqual %bool %u32_1 %f32_1
  386. )";
  387. CompileSuccessfully(GenerateShaderCode(body).c_str());
  388. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  389. EXPECT_THAT(
  390. getDiagnosticString(),
  391. HasSubstr("Expected operands to be scalar or vector float: FOrdEqual"));
  392. }
  393. TEST_F(ValidateLogicals, OpFOrdEqualLeftOperandWrongSize) {
  394. const std::string body = R"(
  395. %val1 = OpFOrdEqual %bool %f32vec2_12 %f32_1
  396. )";
  397. CompileSuccessfully(GenerateShaderCode(body).c_str());
  398. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  399. EXPECT_THAT(
  400. getDiagnosticString(),
  401. HasSubstr(
  402. "Expected vector sizes of Result Type and the operands to be equal: "
  403. "FOrdEqual"));
  404. }
  405. TEST_F(ValidateLogicals, OpFOrdEqualOperandsDifferentType) {
  406. const std::string body = R"(
  407. %val1 = OpFOrdEqual %bool %f32_1 %f64_1
  408. )";
  409. CompileSuccessfully(GenerateShaderCode(body).c_str());
  410. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  411. EXPECT_THAT(
  412. getDiagnosticString(),
  413. HasSubstr("Expected left and right operands to have the same type: "
  414. "FOrdEqual"));
  415. }
  416. TEST_F(ValidateLogicals, OpLogicalEqualSuccess) {
  417. const std::string body = R"(
  418. %val1 = OpLogicalEqual %bool %true %false
  419. %val2 = OpLogicalEqual %boolvec2 %boolvec2_tf %boolvec2_tf
  420. %val3 = OpLogicalEqual %boolvec3 %boolvec3_tft %boolvec3_tft
  421. %val4 = OpLogicalEqual %boolvec4 %boolvec4_tftf %boolvec4_tftf
  422. )";
  423. CompileSuccessfully(GenerateKernelCode(body).c_str());
  424. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  425. }
  426. TEST_F(ValidateLogicals, OpLogicalEqualWrongTypeId) {
  427. const std::string body = R"(
  428. %val1 = OpLogicalEqual %u32 %true %false
  429. )";
  430. CompileSuccessfully(GenerateKernelCode(body).c_str());
  431. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  432. EXPECT_THAT(
  433. getDiagnosticString(),
  434. HasSubstr(
  435. "Expected bool scalar or vector type as Result Type: LogicalEqual"));
  436. }
  437. TEST_F(ValidateLogicals, OpLogicalEqualWrongLeftOperand) {
  438. const std::string body = R"(
  439. %val1 = OpLogicalEqual %bool %boolvec2_tf %false
  440. )";
  441. CompileSuccessfully(GenerateKernelCode(body).c_str());
  442. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  443. EXPECT_THAT(
  444. getDiagnosticString(),
  445. HasSubstr("Expected both operands to be of Result Type: LogicalEqual"));
  446. }
  447. TEST_F(ValidateLogicals, OpLogicalEqualWrongRightOperand) {
  448. const std::string body = R"(
  449. %val1 = OpLogicalEqual %boolvec2 %boolvec2_tf %false
  450. )";
  451. CompileSuccessfully(GenerateKernelCode(body).c_str());
  452. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  453. EXPECT_THAT(
  454. getDiagnosticString(),
  455. HasSubstr("Expected both operands to be of Result Type: LogicalEqual"));
  456. }
  457. TEST_F(ValidateLogicals, OpLogicalNotSuccess) {
  458. const std::string body = R"(
  459. %val1 = OpLogicalNot %bool %true
  460. %val2 = OpLogicalNot %boolvec2 %boolvec2_tf
  461. %val3 = OpLogicalNot %boolvec3 %boolvec3_tft
  462. %val4 = OpLogicalNot %boolvec4 %boolvec4_tftf
  463. )";
  464. CompileSuccessfully(GenerateKernelCode(body).c_str());
  465. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  466. }
  467. TEST_F(ValidateLogicals, OpLogicalNotWrongTypeId) {
  468. const std::string body = R"(
  469. %val1 = OpLogicalNot %u32 %true
  470. )";
  471. CompileSuccessfully(GenerateKernelCode(body).c_str());
  472. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  473. EXPECT_THAT(
  474. getDiagnosticString(),
  475. HasSubstr(
  476. "Expected bool scalar or vector type as Result Type: LogicalNot"));
  477. }
  478. TEST_F(ValidateLogicals, OpLogicalNotWrongOperand) {
  479. const std::string body = R"(
  480. %val1 = OpLogicalNot %bool %boolvec2_tf
  481. )";
  482. CompileSuccessfully(GenerateKernelCode(body).c_str());
  483. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  484. EXPECT_THAT(getDiagnosticString(),
  485. HasSubstr("Expected operand to be of Result Type: LogicalNot"));
  486. }
  487. TEST_F(ValidateLogicals, OpSelectSuccess) {
  488. const std::string body = R"(
  489. %val1 = OpSelect %u32 %true %u32_0 %u32_1
  490. %val2 = OpSelect %f32 %true %f32_0 %f32_1
  491. %val3 = OpSelect %f64 %true %f64_0 %f64_1
  492. %val4 = OpSelect %f32vec2 %boolvec2_tf %f32vec2_01 %f32vec2_12
  493. %val5 = OpSelect %f32vec4 %boolvec4_tftf %f32vec4_0123 %f32vec4_1234
  494. )";
  495. CompileSuccessfully(GenerateShaderCode(body).c_str());
  496. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  497. }
  498. TEST_F(ValidateLogicals, OpSelectWrongTypeId) {
  499. const std::string body = R"(
  500. %val1 = OpSelect %void %true %u32_0 %u32_1
  501. )";
  502. CompileSuccessfully(GenerateShaderCode(body).c_str());
  503. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  504. EXPECT_THAT(
  505. getDiagnosticString(),
  506. HasSubstr("Expected scalar or vector type as Result Type: Select"));
  507. }
  508. TEST_F(ValidateLogicals, OpSelectWrongTypeIdV14) {
  509. // In 1.4, the message changes to allow composites.
  510. const std::string body = R"(
  511. %val1 = OpSelect %void %true %u32_0 %u32_1
  512. )";
  513. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_UNIVERSAL_1_4);
  514. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  515. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  516. EXPECT_THAT(
  517. getDiagnosticString(),
  518. HasSubstr("Expected scalar or composite type as Result Type: Select"));
  519. }
  520. TEST_F(ValidateLogicals, OpSelectPointerNoCapability) {
  521. const std::string body = R"(
  522. %x = OpVariable %f32vec4ptr Function
  523. %y = OpVariable %f32vec4ptr Function
  524. OpStore %x %f32vec4_0123
  525. OpStore %y %f32vec4_1234
  526. %val1 = OpSelect %f32vec4ptr %true %x %y
  527. )";
  528. CompileSuccessfully(GenerateShaderCode(body).c_str());
  529. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  530. EXPECT_THAT(
  531. getDiagnosticString(),
  532. HasSubstr(
  533. "Using pointers with OpSelect requires capability VariablePointers "
  534. "or VariablePointersStorageBuffer"));
  535. }
  536. TEST_F(ValidateLogicals, OpSelectPointerWithCapability1) {
  537. const std::string body = R"(
  538. %x = OpVariable %f32vec4ptr Function
  539. %y = OpVariable %f32vec4ptr Function
  540. OpStore %x %f32vec4_0123
  541. OpStore %y %f32vec4_1234
  542. %val1 = OpSelect %f32vec4ptr %true %x %y
  543. )";
  544. const std::string extra_cap_ext = R"(
  545. OpCapability VariablePointers
  546. OpExtension "SPV_KHR_variable_pointers"
  547. )";
  548. CompileSuccessfully(GenerateShaderCode(body, extra_cap_ext).c_str());
  549. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  550. }
  551. TEST_F(ValidateLogicals, OpSelectPointerWithCapability2) {
  552. const std::string body = R"(
  553. %x = OpVariable %f32vec4ptr Function
  554. %y = OpVariable %f32vec4ptr Function
  555. OpStore %x %f32vec4_0123
  556. OpStore %y %f32vec4_1234
  557. %val1 = OpSelect %f32vec4ptr %true %x %y
  558. )";
  559. const std::string extra_cap_ext = R"(
  560. OpCapability VariablePointersStorageBuffer
  561. OpExtension "SPV_KHR_variable_pointers"
  562. )";
  563. CompileSuccessfully(GenerateShaderCode(body, extra_cap_ext).c_str());
  564. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  565. }
  566. TEST_F(ValidateLogicals, OpSelectWrongCondition) {
  567. const std::string body = R"(
  568. %val1 = OpSelect %u32 %u32_1 %u32_0 %u32_1
  569. )";
  570. CompileSuccessfully(GenerateShaderCode(body).c_str());
  571. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  572. EXPECT_THAT(
  573. getDiagnosticString(),
  574. HasSubstr("Expected bool scalar or vector type as condition: Select"));
  575. }
  576. TEST_F(ValidateLogicals, OpSelectWrongConditionDimension) {
  577. const std::string body = R"(
  578. %val1 = OpSelect %u32vec2 %true %u32vec2_01 %u32vec2_12
  579. )";
  580. CompileSuccessfully(GenerateShaderCode(body).c_str());
  581. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  582. EXPECT_THAT(
  583. getDiagnosticString(),
  584. HasSubstr(
  585. "Expected vector sizes of Result Type and the condition to be equal: "
  586. "Select"));
  587. }
  588. TEST_F(ValidateLogicals, OpSelectWrongLeftObject) {
  589. const std::string body = R"(
  590. %val1 = OpSelect %bool %true %u32vec2_01 %u32_1
  591. )";
  592. CompileSuccessfully(GenerateShaderCode(body).c_str());
  593. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  594. EXPECT_THAT(getDiagnosticString(),
  595. HasSubstr("Expected both objects to be of Result Type: Select"));
  596. }
  597. TEST_F(ValidateLogicals, OpSelectWrongRightObject) {
  598. const std::string body = R"(
  599. %val1 = OpSelect %bool %true %u32_1 %u32vec2_01
  600. )";
  601. CompileSuccessfully(GenerateShaderCode(body).c_str());
  602. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  603. EXPECT_THAT(getDiagnosticString(),
  604. HasSubstr("Expected both objects to be of Result Type: Select"));
  605. }
  606. TEST_F(ValidateLogicals, OpSelectArrayV13Bad) {
  607. const std::string body = R"(
  608. %val1 = OpSelect %arr_u32_2 %true %nul_arr_u32_2 %arr_u32_2_1_2
  609. )";
  610. CompileSuccessfully(GenerateShaderCode(body).c_str());
  611. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  612. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  613. EXPECT_THAT(
  614. getDiagnosticString(),
  615. HasSubstr("Expected scalar or vector type as Result Type: Select"));
  616. }
  617. TEST_F(ValidateLogicals, OpSelectArrayV13TargetV14Bad) {
  618. const std::string body = R"(
  619. %val1 = OpSelect %arr_u32_2 %true %nul_arr_u32_2 %arr_u32_2_1_2
  620. )";
  621. CompileSuccessfully(GenerateShaderCode(body).c_str());
  622. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  623. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  624. EXPECT_THAT(getDiagnosticString(),
  625. HasSubstr("Expected scalar or vector type as Result Type"));
  626. }
  627. TEST_F(ValidateLogicals, OpSelectArrayV14Good) {
  628. const std::string body = R"(
  629. %val1 = OpSelect %arr_u32_2 %true %nul_arr_u32_2 %arr_u32_2_1_2
  630. )";
  631. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_UNIVERSAL_1_4);
  632. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  633. EXPECT_THAT(getDiagnosticString(), Eq(""));
  634. }
  635. TEST_F(ValidateLogicals, OpSelectStructV13Bad) {
  636. const std::string body = R"(
  637. %val1 = OpSelect %st_u32_u32 %true %nul_st_u32_u32 %st_u32_u32_1_2
  638. )";
  639. CompileSuccessfully(GenerateShaderCode(body).c_str());
  640. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  641. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  642. EXPECT_THAT(
  643. getDiagnosticString(),
  644. HasSubstr("Expected scalar or vector type as Result Type: Select"));
  645. }
  646. TEST_F(ValidateLogicals, OpSelectStructV13TargetV14Bad) {
  647. const std::string body = R"(
  648. %val1 = OpSelect %st_u32_u32 %true %nul_st_u32_u32 %st_u32_u32_1_2
  649. )";
  650. CompileSuccessfully(GenerateShaderCode(body).c_str());
  651. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  652. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  653. EXPECT_THAT(getDiagnosticString(),
  654. HasSubstr("Expected scalar or vector type as Result Type"));
  655. }
  656. TEST_F(ValidateLogicals, OpSelectStructV14Good) {
  657. const std::string body = R"(
  658. %val1 = OpSelect %st_u32_u32 %true %nul_st_u32_u32 %st_u32_u32_1_2
  659. )";
  660. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_UNIVERSAL_1_4);
  661. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  662. EXPECT_THAT(getDiagnosticString(), Eq(""));
  663. }
  664. TEST_F(ValidateLogicals, OpSelectMatrixV13Bad) {
  665. const std::string body = R"(
  666. %val1 = OpSelect %mat_f32_2_2 %true %nul_mat_f32_2_2 %mat_f32_2_2_01_12
  667. )";
  668. CompileSuccessfully(GenerateShaderCode(body).c_str());
  669. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  670. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  671. EXPECT_THAT(
  672. getDiagnosticString(),
  673. HasSubstr("Expected scalar or vector type as Result Type: Select"));
  674. }
  675. TEST_F(ValidateLogicals, OpSelectMatrixV13TargetV14Bad) {
  676. const std::string body = R"(
  677. %val1 = OpSelect %mat_f32_2_2 %true %nul_mat_f32_2_2 %mat_f32_2_2_01_12
  678. )";
  679. CompileSuccessfully(GenerateShaderCode(body).c_str());
  680. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  681. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  682. EXPECT_THAT(getDiagnosticString(),
  683. HasSubstr("Expected scalar or vector type as Result Type"));
  684. }
  685. TEST_F(ValidateLogicals, OpSelectMatrixV14Good) {
  686. const std::string body = R"(
  687. %val1 = OpSelect %mat_f32_2_2 %true %nul_mat_f32_2_2 %mat_f32_2_2_01_12
  688. )";
  689. CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_UNIVERSAL_1_4);
  690. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  691. EXPECT_THAT(getDiagnosticString(), Eq(""));
  692. }
  693. TEST_F(ValidateLogicals, OpIEqualSuccess) {
  694. const std::string body = R"(
  695. %val1 = OpIEqual %bool %u32_0 %s32_1
  696. %val2 = OpIEqual %bool %s64_0 %u64_0
  697. %val3 = OpIEqual %boolvec2 %s32vec2_12 %u32vec2_12
  698. %val4 = OpIEqual %boolvec3 %s32vec3_123 %u32vec3_123
  699. %val5 = OpIEqual %boolvec4 %s32vec4_1234 %u32vec4_1234
  700. )";
  701. CompileSuccessfully(GenerateShaderCode(body).c_str());
  702. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  703. }
  704. TEST_F(ValidateLogicals, OpIEqualWrongTypeId) {
  705. const std::string body = R"(
  706. %val1 = OpIEqual %u32 %s32_1 %s32_1
  707. )";
  708. CompileSuccessfully(GenerateShaderCode(body).c_str());
  709. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  710. EXPECT_THAT(
  711. getDiagnosticString(),
  712. HasSubstr("Expected bool scalar or vector type as Result Type: IEqual"));
  713. }
  714. TEST_F(ValidateLogicals, OpIEqualLeftOperandNotInt) {
  715. const std::string body = R"(
  716. %val1 = OpIEqual %bool %f32_1 %s32_1
  717. )";
  718. CompileSuccessfully(GenerateShaderCode(body).c_str());
  719. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  720. EXPECT_THAT(
  721. getDiagnosticString(),
  722. HasSubstr("Expected operands to be scalar or vector int: IEqual"));
  723. }
  724. TEST_F(ValidateLogicals, OpIEqualLeftOperandWrongSize) {
  725. const std::string body = R"(
  726. %val1 = OpIEqual %bool %s32vec2_12 %s32_1
  727. )";
  728. CompileSuccessfully(GenerateShaderCode(body).c_str());
  729. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  730. EXPECT_THAT(
  731. getDiagnosticString(),
  732. HasSubstr(
  733. "Expected vector sizes of Result Type and the operands to be equal: "
  734. "IEqual"));
  735. }
  736. TEST_F(ValidateLogicals, OpIEqualRightOperandNotInt) {
  737. const std::string body = R"(
  738. %val1 = OpIEqual %bool %u32_1 %f32_1
  739. )";
  740. CompileSuccessfully(GenerateShaderCode(body).c_str());
  741. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  742. EXPECT_THAT(
  743. getDiagnosticString(),
  744. HasSubstr("Expected operands to be scalar or vector int: IEqual"));
  745. }
  746. TEST_F(ValidateLogicals, OpIEqualDifferentBitWidth) {
  747. const std::string body = R"(
  748. %val1 = OpIEqual %bool %u32_1 %u64_1
  749. )";
  750. CompileSuccessfully(GenerateShaderCode(body).c_str());
  751. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  752. EXPECT_THAT(getDiagnosticString(),
  753. HasSubstr("Expected both operands to have the same component bit "
  754. "width: IEqual"));
  755. }
  756. TEST_F(ValidateLogicals, OpUGreaterThanSuccess) {
  757. const std::string body = R"(
  758. %val1 = OpUGreaterThan %bool %u32_0 %u32_1
  759. %val2 = OpUGreaterThan %bool %s32_0 %u32_1
  760. %val3 = OpUGreaterThan %bool %u64_0 %u64_0
  761. %val4 = OpUGreaterThan %bool %u64_0 %s64_0
  762. %val5 = OpUGreaterThan %boolvec2 %u32vec2_12 %u32vec2_12
  763. %val6 = OpUGreaterThan %boolvec3 %s32vec3_123 %u32vec3_123
  764. %val7 = OpUGreaterThan %boolvec4 %u32vec4_1234 %u32vec4_1234
  765. )";
  766. CompileSuccessfully(GenerateShaderCode(body).c_str());
  767. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  768. }
  769. TEST_F(ValidateLogicals, OpUGreaterThanWrongTypeId) {
  770. const std::string body = R"(
  771. %val1 = OpUGreaterThan %u32 %u32_1 %u32_1
  772. )";
  773. CompileSuccessfully(GenerateShaderCode(body).c_str());
  774. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  775. EXPECT_THAT(
  776. getDiagnosticString(),
  777. HasSubstr(
  778. "Expected bool scalar or vector type as Result Type: UGreaterThan"));
  779. }
  780. TEST_F(ValidateLogicals, OpUGreaterThanLeftOperandNotInt) {
  781. const std::string body = R"(
  782. %val1 = OpUGreaterThan %bool %f32_1 %u32_1
  783. )";
  784. CompileSuccessfully(GenerateShaderCode(body).c_str());
  785. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  786. EXPECT_THAT(
  787. getDiagnosticString(),
  788. HasSubstr("Expected operands to be scalar or vector int: UGreaterThan"));
  789. }
  790. TEST_F(ValidateLogicals, OpUGreaterThanLeftOperandWrongSize) {
  791. const std::string body = R"(
  792. %val1 = OpUGreaterThan %bool %u32vec2_12 %u32_1
  793. )";
  794. CompileSuccessfully(GenerateShaderCode(body).c_str());
  795. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  796. EXPECT_THAT(
  797. getDiagnosticString(),
  798. HasSubstr(
  799. "Expected vector sizes of Result Type and the operands to be equal: "
  800. "UGreaterThan"));
  801. }
  802. TEST_F(ValidateLogicals, OpUGreaterThanRightOperandNotInt) {
  803. const std::string body = R"(
  804. %val1 = OpUGreaterThan %bool %u32_1 %f32_1
  805. )";
  806. CompileSuccessfully(GenerateShaderCode(body).c_str());
  807. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  808. EXPECT_THAT(
  809. getDiagnosticString(),
  810. HasSubstr("Expected operands to be scalar or vector int: UGreaterThan"));
  811. }
  812. TEST_F(ValidateLogicals, OpUGreaterThanDifferentBitWidth) {
  813. const std::string body = R"(
  814. %val1 = OpUGreaterThan %bool %u32_1 %u64_1
  815. )";
  816. CompileSuccessfully(GenerateShaderCode(body).c_str());
  817. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  818. EXPECT_THAT(
  819. getDiagnosticString(),
  820. HasSubstr("Expected both operands to have the same component bit width: "
  821. "UGreaterThan"));
  822. }
  823. TEST_F(ValidateLogicals, OpSGreaterThanSuccess) {
  824. const std::string body = R"(
  825. %val1 = OpSGreaterThan %bool %s32_0 %s32_1
  826. %val2 = OpSGreaterThan %bool %u32_0 %s32_1
  827. %val3 = OpSGreaterThan %bool %s64_0 %s64_0
  828. %val4 = OpSGreaterThan %bool %s64_0 %u64_0
  829. %val5 = OpSGreaterThan %boolvec2 %s32vec2_12 %s32vec2_12
  830. %val6 = OpSGreaterThan %boolvec3 %s32vec3_123 %u32vec3_123
  831. %val7 = OpSGreaterThan %boolvec4 %s32vec4_1234 %s32vec4_1234
  832. )";
  833. CompileSuccessfully(GenerateShaderCode(body).c_str());
  834. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  835. }
  836. TEST_F(ValidateLogicals, OpSGreaterThanWrongTypeId) {
  837. const std::string body = R"(
  838. %val1 = OpSGreaterThan %s32 %s32_1 %s32_1
  839. )";
  840. CompileSuccessfully(GenerateShaderCode(body).c_str());
  841. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  842. EXPECT_THAT(
  843. getDiagnosticString(),
  844. HasSubstr(
  845. "Expected bool scalar or vector type as Result Type: SGreaterThan"));
  846. }
  847. TEST_F(ValidateLogicals, OpSGreaterThanLeftOperandNotInt) {
  848. const std::string body = R"(
  849. %val1 = OpSGreaterThan %bool %f32_1 %s32_1
  850. )";
  851. CompileSuccessfully(GenerateShaderCode(body).c_str());
  852. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  853. EXPECT_THAT(
  854. getDiagnosticString(),
  855. HasSubstr("Expected operands to be scalar or vector int: SGreaterThan"));
  856. }
  857. TEST_F(ValidateLogicals, OpSGreaterThanLeftOperandWrongSize) {
  858. const std::string body = R"(
  859. %val1 = OpSGreaterThan %bool %s32vec2_12 %s32_1
  860. )";
  861. CompileSuccessfully(GenerateShaderCode(body).c_str());
  862. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  863. EXPECT_THAT(
  864. getDiagnosticString(),
  865. HasSubstr(
  866. "Expected vector sizes of Result Type and the operands to be equal: "
  867. "SGreaterThan"));
  868. }
  869. TEST_F(ValidateLogicals, OpSGreaterThanRightOperandNotInt) {
  870. const std::string body = R"(
  871. %val1 = OpSGreaterThan %bool %s32_1 %f32_1
  872. )";
  873. CompileSuccessfully(GenerateShaderCode(body).c_str());
  874. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  875. EXPECT_THAT(
  876. getDiagnosticString(),
  877. HasSubstr("Expected operands to be scalar or vector int: SGreaterThan"));
  878. }
  879. TEST_F(ValidateLogicals, OpSGreaterThanDifferentBitWidth) {
  880. const std::string body = R"(
  881. %val1 = OpSGreaterThan %bool %s32_1 %s64_1
  882. )";
  883. CompileSuccessfully(GenerateShaderCode(body).c_str());
  884. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  885. EXPECT_THAT(getDiagnosticString(),
  886. HasSubstr("Expected both operands to have the same component bit "
  887. "width: SGreaterThan"));
  888. }
  889. TEST_F(ValidateLogicals, PSBSelectSuccess) {
  890. const std::string body = R"(
  891. OpCapability PhysicalStorageBufferAddresses
  892. OpCapability Int64
  893. OpCapability Shader
  894. OpExtension "SPV_EXT_physical_storage_buffer"
  895. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  896. OpEntryPoint Fragment %main "main"
  897. OpExecutionMode %main OriginUpperLeft
  898. OpDecorate %val1 AliasedPointer
  899. %uint64 = OpTypeInt 64 0
  900. %bool = OpTypeBool
  901. %true = OpConstantTrue %bool
  902. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  903. %pptr_f = OpTypePointer Function %ptr
  904. %void = OpTypeVoid
  905. %voidfn = OpTypeFunction %void
  906. %main = OpFunction %void None %voidfn
  907. %entry = OpLabel
  908. %val1 = OpVariable %pptr_f Function
  909. %val2 = OpLoad %ptr %val1
  910. %val3 = OpSelect %ptr %true %val2 %val2
  911. OpReturn
  912. OpFunctionEnd
  913. )";
  914. CompileSuccessfully(body.c_str());
  915. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  916. }
  917. TEST_F(ValidateLogicals, SelectVectorsScalarCondition) {
  918. const std::string spirv = R"(
  919. OpCapability Shader
  920. OpCapability Linkage
  921. OpMemoryModel Logical GLSL450
  922. %void = OpTypeVoid
  923. %bool = OpTypeBool
  924. %int = OpTypeInt 32 0
  925. %int4 = OpTypeVector %int 4
  926. %int4_0 = OpConstantNull %int4
  927. %true = OpConstantTrue %bool
  928. %void_fn = OpTypeFunction %void
  929. %func = OpFunction %void None %void_fn
  930. %1 = OpLabel
  931. %select = OpSelect %int4 %true %int4_0 %int4_0
  932. OpReturn
  933. OpFunctionEnd
  934. )";
  935. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  936. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  937. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  938. EXPECT_THAT(getDiagnosticString(),
  939. HasSubstr("Expected vector sizes of Result Type and the "
  940. "condition to be equal: Select"));
  941. }
  942. TEST_F(ValidateLogicals, SelectVectorsScalarCondition1p4) {
  943. const std::string spirv = R"(
  944. OpCapability Shader
  945. OpCapability Linkage
  946. OpMemoryModel Logical GLSL450
  947. %void = OpTypeVoid
  948. %bool = OpTypeBool
  949. %int = OpTypeInt 32 0
  950. %int4 = OpTypeVector %int 4
  951. %int4_0 = OpConstantNull %int4
  952. %true = OpConstantTrue %bool
  953. %void_fn = OpTypeFunction %void
  954. %func = OpFunction %void None %void_fn
  955. %1 = OpLabel
  956. %select = OpSelect %int4 %true %int4_0 %int4_0
  957. OpReturn
  958. OpFunctionEnd
  959. )";
  960. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  961. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  962. }
  963. TEST_F(ValidateLogicals, SelectVectorsVectorConditionMismatchedDimensions1p4) {
  964. const std::string spirv = R"(
  965. OpCapability Shader
  966. OpCapability Linkage
  967. OpMemoryModel Logical GLSL450
  968. %void = OpTypeVoid
  969. %bool = OpTypeBool
  970. %bool3 = OpTypeVector %bool 3
  971. %int = OpTypeInt 32 0
  972. %int4 = OpTypeVector %int 4
  973. %int4_0 = OpConstantNull %int4
  974. %bool3_null = OpConstantNull %bool3
  975. %void_fn = OpTypeFunction %void
  976. %func = OpFunction %void None %void_fn
  977. %1 = OpLabel
  978. %select = OpSelect %int4 %bool3_null %int4_0 %int4_0
  979. OpReturn
  980. OpFunctionEnd
  981. )";
  982. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  983. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  984. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  985. EXPECT_THAT(getDiagnosticString(),
  986. HasSubstr("Expected vector sizes of Result Type and the "
  987. "condition to be equal: Select"));
  988. }
  989. TEST_F(ValidateLogicals, SelectNVBindlessSamplers) {
  990. const std::string spirv = R"(
  991. OpCapability Shader
  992. OpCapability BindlessTextureNV
  993. OpExtension "SPV_NV_bindless_texture"
  994. %1 = OpExtInstImport "GLSL.std.450"
  995. OpMemoryModel Logical GLSL450
  996. OpSamplerImageAddressingModeNV 64
  997. OpEntryPoint Fragment %main "main"
  998. OpExecutionMode %main OriginUpperLeft
  999. OpSource GLSL 450
  1000. OpSourceExtension "GL_NV_bindless_texture"
  1001. OpName %main "main"
  1002. OpName %s2D "s2D"
  1003. OpName %pickhandle "pickhandle"
  1004. OpName %Sampler1 "Sampler1"
  1005. OpName %Sampler2 "Sampler2"
  1006. OpDecorate %pickhandle Flat
  1007. OpDecorate %Sampler1 DescriptorSet 0
  1008. OpDecorate %Sampler1 Binding 0
  1009. OpDecorate %Sampler1 BindlessSamplerNV
  1010. OpDecorate %Sampler2 DescriptorSet 0
  1011. OpDecorate %Sampler2 Binding 1
  1012. OpDecorate %Sampler2 BindlessSamplerNV
  1013. %void = OpTypeVoid
  1014. %3 = OpTypeFunction %void
  1015. %float = OpTypeFloat 32
  1016. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  1017. %8 = OpTypeSampledImage %7
  1018. %_ptr_Function_8 = OpTypePointer Function %8
  1019. %int = OpTypeInt 32 1
  1020. %_ptr_Function_int = OpTypePointer Function %int
  1021. %int_0 = OpConstant %int 0
  1022. %bool = OpTypeBool
  1023. %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
  1024. %Sampler1 = OpVariable %_ptr_UniformConstant_8 UniformConstant
  1025. %Sampler2 = OpVariable %_ptr_UniformConstant_8 UniformConstant
  1026. %main = OpFunction %void None %3
  1027. %5 = OpLabel
  1028. %s2D = OpVariable %_ptr_Function_8 Function
  1029. %pickhandle = OpVariable %_ptr_Function_int Function
  1030. %14 = OpLoad %int %pickhandle
  1031. %17 = OpIEqual %bool %14 %int_0
  1032. %20 = OpLoad %8 %Sampler1
  1033. %22 = OpLoad %8 %Sampler2
  1034. %23 = OpSelect %8 %17 %20 %22
  1035. OpStore %s2D %23
  1036. OpReturn
  1037. OpFunctionEnd
  1038. )";
  1039. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1040. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1041. }
  1042. } // namespace
  1043. } // namespace val
  1044. } // namespace spvtools