val_conversion_test.cpp 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915
  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_code_generator.h"
  19. #include "test/val/val_fixtures.h"
  20. namespace spvtools {
  21. namespace val {
  22. namespace {
  23. using ::testing::HasSubstr;
  24. using ::testing::Not;
  25. using ::testing::Values;
  26. using ValidateConversion = spvtest::ValidateBase<bool>;
  27. std::string GenerateShaderCode(
  28. const std::string& body,
  29. const std::string& capabilities_and_extensions = "",
  30. const std::string& decorations = "", const std::string& types = "",
  31. const std::string& variables = "") {
  32. const std::string capabilities =
  33. R"(
  34. OpCapability Shader
  35. OpCapability Int64
  36. OpCapability Float64)";
  37. const std::string after_extension_before_decorations =
  38. R"(
  39. OpMemoryModel Logical GLSL450
  40. OpEntryPoint Fragment %main "main"
  41. OpExecutionMode %main OriginUpperLeft)";
  42. const std::string after_decorations_before_types =
  43. R"(
  44. %void = OpTypeVoid
  45. %func = OpTypeFunction %void
  46. %bool = OpTypeBool
  47. %f32 = OpTypeFloat 32
  48. %u32 = OpTypeInt 32 0
  49. %s32 = OpTypeInt 32 1
  50. %f64 = OpTypeFloat 64
  51. %u64 = OpTypeInt 64 0
  52. %s64 = OpTypeInt 64 1
  53. %boolvec2 = OpTypeVector %bool 2
  54. %s32vec2 = OpTypeVector %s32 2
  55. %u32vec2 = OpTypeVector %u32 2
  56. %u64vec2 = OpTypeVector %u64 2
  57. %f32vec2 = OpTypeVector %f32 2
  58. %f64vec2 = OpTypeVector %f64 2
  59. %boolvec3 = OpTypeVector %bool 3
  60. %u32vec3 = OpTypeVector %u32 3
  61. %u64vec3 = OpTypeVector %u64 3
  62. %s32vec3 = OpTypeVector %s32 3
  63. %f32vec3 = OpTypeVector %f32 3
  64. %f64vec3 = OpTypeVector %f64 3
  65. %boolvec4 = OpTypeVector %bool 4
  66. %u32vec4 = OpTypeVector %u32 4
  67. %u64vec4 = OpTypeVector %u64 4
  68. %s32vec4 = OpTypeVector %s32 4
  69. %f32vec4 = OpTypeVector %f32 4
  70. %f64vec4 = OpTypeVector %f64 4
  71. %f32_0 = OpConstant %f32 0
  72. %f32_1 = OpConstant %f32 1
  73. %f32_2 = OpConstant %f32 2
  74. %f32_3 = OpConstant %f32 3
  75. %f32_4 = OpConstant %f32 4
  76. %s32_0 = OpConstant %s32 0
  77. %s32_1 = OpConstant %s32 1
  78. %s32_2 = OpConstant %s32 2
  79. %s32_3 = OpConstant %s32 3
  80. %s32_4 = OpConstant %s32 4
  81. %s32_m1 = OpConstant %s32 -1
  82. %u32_0 = OpConstant %u32 0
  83. %u32_1 = OpConstant %u32 1
  84. %u32_2 = OpConstant %u32 2
  85. %u32_3 = OpConstant %u32 3
  86. %u32_4 = OpConstant %u32 4
  87. %f64_0 = OpConstant %f64 0
  88. %f64_1 = OpConstant %f64 1
  89. %f64_2 = OpConstant %f64 2
  90. %f64_3 = OpConstant %f64 3
  91. %f64_4 = OpConstant %f64 4
  92. %s64_0 = OpConstant %s64 0
  93. %s64_1 = OpConstant %s64 1
  94. %s64_2 = OpConstant %s64 2
  95. %s64_3 = OpConstant %s64 3
  96. %s64_4 = OpConstant %s64 4
  97. %s64_m1 = OpConstant %s64 -1
  98. %u64_0 = OpConstant %u64 0
  99. %u64_1 = OpConstant %u64 1
  100. %u64_2 = OpConstant %u64 2
  101. %u64_3 = OpConstant %u64 3
  102. %u64_4 = OpConstant %u64 4
  103. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  104. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  105. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  106. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  107. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  108. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  109. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  110. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  111. %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
  112. %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
  113. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  114. %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
  115. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  116. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  117. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  118. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  119. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  120. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  121. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  122. %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2
  123. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  124. %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3
  125. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  126. %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4
  127. %true = OpConstantTrue %bool
  128. %false = OpConstantFalse %bool
  129. %f32ptr_func = OpTypePointer Function %f32)";
  130. const std::string after_variables_before_body =
  131. R"(
  132. %main = OpFunction %void None %func
  133. %main_entry = OpLabel)";
  134. const std::string after_body =
  135. R"(
  136. OpReturn
  137. OpFunctionEnd)";
  138. return capabilities + capabilities_and_extensions +
  139. after_extension_before_decorations + decorations +
  140. after_decorations_before_types + types + variables +
  141. after_variables_before_body + body + after_body;
  142. }
  143. std::string GenerateKernelCode(
  144. const std::string& body,
  145. const std::string& capabilities_and_extensions = "") {
  146. const std::string capabilities =
  147. R"(
  148. OpCapability Addresses
  149. OpCapability Kernel
  150. OpCapability Linkage
  151. OpCapability GenericPointer
  152. OpCapability Int64
  153. OpCapability Float64)";
  154. const std::string after_extension_before_body =
  155. R"(
  156. OpMemoryModel Physical32 OpenCL
  157. %void = OpTypeVoid
  158. %func = OpTypeFunction %void
  159. %bool = OpTypeBool
  160. %f32 = OpTypeFloat 32
  161. %u32 = OpTypeInt 32 0
  162. %f64 = OpTypeFloat 64
  163. %u64 = OpTypeInt 64 0
  164. %boolvec2 = OpTypeVector %bool 2
  165. %u32vec2 = OpTypeVector %u32 2
  166. %u64vec2 = OpTypeVector %u64 2
  167. %f32vec2 = OpTypeVector %f32 2
  168. %f64vec2 = OpTypeVector %f64 2
  169. %boolvec3 = OpTypeVector %bool 3
  170. %u32vec3 = OpTypeVector %u32 3
  171. %u64vec3 = OpTypeVector %u64 3
  172. %f32vec3 = OpTypeVector %f32 3
  173. %f64vec3 = OpTypeVector %f64 3
  174. %boolvec4 = OpTypeVector %bool 4
  175. %u32vec4 = OpTypeVector %u32 4
  176. %u64vec4 = OpTypeVector %u64 4
  177. %f32vec4 = OpTypeVector %f32 4
  178. %f64vec4 = OpTypeVector %f64 4
  179. %f32_0 = OpConstant %f32 0
  180. %f32_1 = OpConstant %f32 1
  181. %f32_2 = OpConstant %f32 2
  182. %f32_3 = OpConstant %f32 3
  183. %f32_4 = OpConstant %f32 4
  184. %u32_0 = OpConstant %u32 0
  185. %u32_1 = OpConstant %u32 1
  186. %u32_2 = OpConstant %u32 2
  187. %u32_3 = OpConstant %u32 3
  188. %u32_4 = OpConstant %u32 4
  189. %f64_0 = OpConstant %f64 0
  190. %f64_1 = OpConstant %f64 1
  191. %f64_2 = OpConstant %f64 2
  192. %f64_3 = OpConstant %f64 3
  193. %f64_4 = OpConstant %f64 4
  194. %u64_0 = OpConstant %u64 0
  195. %u64_1 = OpConstant %u64 1
  196. %u64_2 = OpConstant %u64 2
  197. %u64_3 = OpConstant %u64 3
  198. %u64_4 = OpConstant %u64 4
  199. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  200. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  201. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  202. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  203. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  204. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  205. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  206. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  207. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  208. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  209. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  210. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  211. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  212. %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2
  213. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  214. %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3
  215. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  216. %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4
  217. %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
  218. %true = OpConstantTrue %bool
  219. %false = OpConstantFalse %bool
  220. %f32ptr_func = OpTypePointer Function %f32
  221. %u32ptr_func = OpTypePointer Function %u32
  222. %f32ptr_gen = OpTypePointer Generic %f32
  223. %f32ptr_inp = OpTypePointer Input %f32
  224. %f32ptr_wg = OpTypePointer Workgroup %f32
  225. %f32ptr_cwg = OpTypePointer CrossWorkgroup %f32
  226. %f32inp = OpVariable %f32ptr_inp Input
  227. %main = OpFunction %void None %func
  228. %main_entry = OpLabel)";
  229. const std::string after_body =
  230. R"(
  231. OpReturn
  232. OpFunctionEnd)";
  233. return capabilities + capabilities_and_extensions +
  234. after_extension_before_body + body + after_body;
  235. }
  236. TEST_F(ValidateConversion, ConvertFToUSuccess) {
  237. const std::string body = R"(
  238. %val1 = OpConvertFToU %u32 %f32_1
  239. %val2 = OpConvertFToU %u32 %f64_0
  240. %val3 = OpConvertFToU %u32vec2 %f32vec2_01
  241. )";
  242. CompileSuccessfully(GenerateShaderCode(body).c_str());
  243. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  244. }
  245. TEST_F(ValidateConversion, ConvertFToUWrongResultType) {
  246. const std::string body = R"(
  247. %val = OpConvertFToU %s32 %f32_1
  248. )";
  249. CompileSuccessfully(GenerateShaderCode(body).c_str());
  250. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  251. EXPECT_THAT(getDiagnosticString(),
  252. HasSubstr("Expected unsigned int scalar or vector type as Result "
  253. "Type: ConvertFToU"));
  254. }
  255. TEST_F(ValidateConversion, ConvertFToUWrongInputType) {
  256. const std::string body = R"(
  257. %val = OpConvertFToU %u32 %u32_1
  258. )";
  259. CompileSuccessfully(GenerateShaderCode(body).c_str());
  260. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  261. EXPECT_THAT(
  262. getDiagnosticString(),
  263. HasSubstr("Expected input to be float scalar or vector: ConvertFToU"));
  264. }
  265. TEST_F(ValidateConversion, ConvertFToUDifferentDimension) {
  266. const std::string body = R"(
  267. %val = OpConvertFToU %u32 %f32vec2_01
  268. )";
  269. CompileSuccessfully(GenerateShaderCode(body).c_str());
  270. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  271. EXPECT_THAT(getDiagnosticString(),
  272. HasSubstr("Expected input to have the same dimension as Result "
  273. "Type: ConvertFToU"));
  274. }
  275. TEST_F(ValidateConversion, ConvertFToSSuccess) {
  276. const std::string body = R"(
  277. %val1 = OpConvertFToS %s32 %f32_1
  278. %val2 = OpConvertFToS %u32 %f64_0
  279. %val3 = OpConvertFToS %s32vec2 %f32vec2_01
  280. )";
  281. CompileSuccessfully(GenerateShaderCode(body).c_str());
  282. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  283. }
  284. TEST_F(ValidateConversion, ConvertFToSWrongResultType) {
  285. const std::string body = R"(
  286. %val = OpConvertFToS %bool %f32_1
  287. )";
  288. CompileSuccessfully(GenerateShaderCode(body).c_str());
  289. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  290. EXPECT_THAT(
  291. getDiagnosticString(),
  292. HasSubstr(
  293. "Expected int scalar or vector type as Result Type: ConvertFToS"));
  294. }
  295. TEST_F(ValidateConversion, ConvertFToSWrongInputType) {
  296. const std::string body = R"(
  297. %val = OpConvertFToS %s32 %u32_1
  298. )";
  299. CompileSuccessfully(GenerateShaderCode(body).c_str());
  300. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  301. EXPECT_THAT(
  302. getDiagnosticString(),
  303. HasSubstr("Expected input to be float scalar or vector: ConvertFToS"));
  304. }
  305. TEST_F(ValidateConversion, ConvertFToSDifferentDimension) {
  306. const std::string body = R"(
  307. %val = OpConvertFToS %u32 %f32vec2_01
  308. )";
  309. CompileSuccessfully(GenerateShaderCode(body).c_str());
  310. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  311. EXPECT_THAT(getDiagnosticString(),
  312. HasSubstr("Expected input to have the same dimension as Result "
  313. "Type: ConvertFToS"));
  314. }
  315. TEST_F(ValidateConversion, ConvertSToFSuccess) {
  316. const std::string body = R"(
  317. %val1 = OpConvertSToF %f32 %u32_1
  318. %val2 = OpConvertSToF %f32 %s64_0
  319. %val3 = OpConvertSToF %f32vec2 %s32vec2_01
  320. )";
  321. CompileSuccessfully(GenerateShaderCode(body).c_str());
  322. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  323. }
  324. TEST_F(ValidateConversion, ConvertSToFWrongResultType) {
  325. const std::string body = R"(
  326. %val = OpConvertSToF %u32 %s32_1
  327. )";
  328. CompileSuccessfully(GenerateShaderCode(body).c_str());
  329. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  330. EXPECT_THAT(
  331. getDiagnosticString(),
  332. HasSubstr(
  333. "Expected float scalar or vector type as Result Type: ConvertSToF"));
  334. }
  335. TEST_F(ValidateConversion, ConvertSToFWrongInputType) {
  336. const std::string body = R"(
  337. %val = OpConvertSToF %f32 %f32_1
  338. )";
  339. CompileSuccessfully(GenerateShaderCode(body).c_str());
  340. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  341. EXPECT_THAT(
  342. getDiagnosticString(),
  343. HasSubstr("Expected input to be int scalar or vector: ConvertSToF"));
  344. }
  345. TEST_F(ValidateConversion, ConvertSToFDifferentDimension) {
  346. const std::string body = R"(
  347. %val = OpConvertSToF %f32 %u32vec2_01
  348. )";
  349. CompileSuccessfully(GenerateShaderCode(body).c_str());
  350. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  351. EXPECT_THAT(getDiagnosticString(),
  352. HasSubstr("Expected input to have the same dimension as Result "
  353. "Type: ConvertSToF"));
  354. }
  355. TEST_F(ValidateConversion, UConvertSuccess) {
  356. const std::string body = R"(
  357. %val1 = OpUConvert %u32 %u64_1
  358. %val2 = OpUConvert %u64 %s32_0
  359. %val3 = OpUConvert %u64vec2 %s32vec2_01
  360. )";
  361. CompileSuccessfully(GenerateShaderCode(body).c_str());
  362. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  363. }
  364. TEST_F(ValidateConversion, UConvertWrongResultType) {
  365. const std::string body = R"(
  366. %val = OpUConvert %s32 %s32_1
  367. )";
  368. CompileSuccessfully(GenerateShaderCode(body).c_str());
  369. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  370. EXPECT_THAT(getDiagnosticString(),
  371. HasSubstr("Expected unsigned int scalar or vector type as Result "
  372. "Type: UConvert"));
  373. }
  374. TEST_F(ValidateConversion, UConvertWrongInputType) {
  375. const std::string body = R"(
  376. %val = OpUConvert %u32 %f32_1
  377. )";
  378. CompileSuccessfully(GenerateShaderCode(body).c_str());
  379. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  380. EXPECT_THAT(getDiagnosticString(),
  381. HasSubstr("Expected input to be int scalar or vector: UConvert"));
  382. }
  383. TEST_F(ValidateConversion, UConvertDifferentDimension) {
  384. const std::string body = R"(
  385. %val = OpUConvert %u32 %u32vec2_01
  386. )";
  387. CompileSuccessfully(GenerateShaderCode(body).c_str());
  388. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  389. EXPECT_THAT(getDiagnosticString(),
  390. HasSubstr("Expected input to have the same dimension as Result "
  391. "Type: UConvert"));
  392. }
  393. TEST_F(ValidateConversion, UConvertSameBitWidth) {
  394. const std::string body = R"(
  395. %val = OpUConvert %u32 %s32_1
  396. )";
  397. CompileSuccessfully(GenerateShaderCode(body).c_str());
  398. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  399. EXPECT_THAT(getDiagnosticString(),
  400. HasSubstr("Expected input to have different bit width from "
  401. "Result Type: UConvert"));
  402. }
  403. TEST_F(ValidateConversion, SConvertSuccess) {
  404. const std::string body = R"(
  405. %val1 = OpSConvert %s32 %u64_1
  406. %val2 = OpSConvert %s64 %s32_0
  407. %val3 = OpSConvert %u64vec2 %s32vec2_01
  408. )";
  409. CompileSuccessfully(GenerateShaderCode(body).c_str());
  410. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  411. }
  412. TEST_F(ValidateConversion, SConvertWrongResultType) {
  413. const std::string body = R"(
  414. %val = OpSConvert %f32 %s32_1
  415. )";
  416. CompileSuccessfully(GenerateShaderCode(body).c_str());
  417. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  418. EXPECT_THAT(
  419. getDiagnosticString(),
  420. HasSubstr("Expected int scalar or vector type as Result Type: SConvert"));
  421. }
  422. TEST_F(ValidateConversion, SConvertWrongInputType) {
  423. const std::string body = R"(
  424. %val = OpSConvert %u32 %f32_1
  425. )";
  426. CompileSuccessfully(GenerateShaderCode(body).c_str());
  427. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  428. EXPECT_THAT(getDiagnosticString(),
  429. HasSubstr("Expected input to be int scalar or vector: SConvert"));
  430. }
  431. TEST_F(ValidateConversion, SConvertDifferentDimension) {
  432. const std::string body = R"(
  433. %val = OpSConvert %s32 %u32vec2_01
  434. )";
  435. CompileSuccessfully(GenerateShaderCode(body).c_str());
  436. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  437. EXPECT_THAT(getDiagnosticString(),
  438. HasSubstr("Expected input to have the same dimension as Result "
  439. "Type: SConvert"));
  440. }
  441. TEST_F(ValidateConversion, SConvertSameBitWidth) {
  442. const std::string body = R"(
  443. %val = OpSConvert %u32 %s32_1
  444. )";
  445. CompileSuccessfully(GenerateShaderCode(body).c_str());
  446. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  447. EXPECT_THAT(getDiagnosticString(),
  448. HasSubstr("Expected input to have different bit width from "
  449. "Result Type: SConvert"));
  450. }
  451. TEST_F(ValidateConversion, FConvertSuccess) {
  452. const std::string body = R"(
  453. %val1 = OpFConvert %f32 %f64_1
  454. %val2 = OpFConvert %f64 %f32_0
  455. %val3 = OpFConvert %f64vec2 %f32vec2_01
  456. )";
  457. CompileSuccessfully(GenerateShaderCode(body).c_str());
  458. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  459. }
  460. TEST_F(ValidateConversion, FConvertWrongResultType) {
  461. const std::string body = R"(
  462. %val = OpFConvert %u32 %f32_1
  463. )";
  464. CompileSuccessfully(GenerateShaderCode(body).c_str());
  465. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  466. EXPECT_THAT(
  467. getDiagnosticString(),
  468. HasSubstr(
  469. "Expected float scalar or vector type as Result Type: FConvert"));
  470. }
  471. TEST_F(ValidateConversion, FConvertWrongInputType) {
  472. const std::string body = R"(
  473. %val = OpFConvert %f32 %u64_1
  474. )";
  475. CompileSuccessfully(GenerateShaderCode(body).c_str());
  476. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  477. EXPECT_THAT(
  478. getDiagnosticString(),
  479. HasSubstr("Expected input to be float scalar or vector: FConvert"));
  480. }
  481. TEST_F(ValidateConversion, FConvertDifferentDimension) {
  482. const std::string body = R"(
  483. %val = OpFConvert %f64 %f32vec2_01
  484. )";
  485. CompileSuccessfully(GenerateShaderCode(body).c_str());
  486. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  487. EXPECT_THAT(getDiagnosticString(),
  488. HasSubstr("Expected input to have the same dimension as Result "
  489. "Type: FConvert"));
  490. }
  491. TEST_F(ValidateConversion, FConvertSameBitWidth) {
  492. const std::string body = R"(
  493. %val = OpFConvert %f32 %f32_1
  494. )";
  495. CompileSuccessfully(GenerateShaderCode(body).c_str());
  496. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  497. EXPECT_THAT(getDiagnosticString(),
  498. HasSubstr("Expected input to have different bit width from "
  499. "Result Type: FConvert"));
  500. }
  501. TEST_F(ValidateConversion, QuantizeToF16Success) {
  502. const std::string body = R"(
  503. %val1 = OpQuantizeToF16 %f32 %f32_1
  504. %val2 = OpQuantizeToF16 %f32 %f32_0
  505. %val3 = OpQuantizeToF16 %f32vec2 %f32vec2_01
  506. )";
  507. CompileSuccessfully(GenerateShaderCode(body).c_str());
  508. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  509. }
  510. TEST_F(ValidateConversion, QuantizeToF16WrongResultType) {
  511. const std::string body = R"(
  512. %val = OpQuantizeToF16 %u32 %f32_1
  513. )";
  514. CompileSuccessfully(GenerateShaderCode(body).c_str());
  515. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  516. EXPECT_THAT(
  517. getDiagnosticString(),
  518. HasSubstr("Expected 32-bit float scalar or vector type as Result Type: "
  519. "QuantizeToF16"));
  520. }
  521. TEST_F(ValidateConversion, QuantizeToF16WrongResultTypeBitWidth) {
  522. const std::string body = R"(
  523. %val = OpQuantizeToF16 %u64 %f64_1
  524. )";
  525. CompileSuccessfully(GenerateShaderCode(body).c_str());
  526. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  527. EXPECT_THAT(
  528. getDiagnosticString(),
  529. HasSubstr("Expected 32-bit float scalar or vector type as Result Type: "
  530. "QuantizeToF16"));
  531. }
  532. TEST_F(ValidateConversion, QuantizeToF16WrongInputType) {
  533. const std::string body = R"(
  534. %val = OpQuantizeToF16 %f32 %f64_1
  535. )";
  536. CompileSuccessfully(GenerateShaderCode(body).c_str());
  537. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  538. EXPECT_THAT(
  539. getDiagnosticString(),
  540. HasSubstr(
  541. "Expected input type to be equal to Result Type: QuantizeToF16"));
  542. }
  543. TEST_F(ValidateConversion, ConvertPtrToUSuccess) {
  544. const std::string body = R"(
  545. %ptr = OpVariable %f32ptr_func Function
  546. %val1 = OpConvertPtrToU %u32 %ptr
  547. %val2 = OpConvertPtrToU %u64 %ptr
  548. )";
  549. CompileSuccessfully(GenerateKernelCode(body).c_str());
  550. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  551. }
  552. TEST_F(ValidateConversion, ConvertPtrToUWrongResultType) {
  553. const std::string body = R"(
  554. %ptr = OpVariable %f32ptr_func Function
  555. %val = OpConvertPtrToU %f32 %ptr
  556. )";
  557. CompileSuccessfully(GenerateKernelCode(body).c_str());
  558. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  559. EXPECT_THAT(getDiagnosticString(),
  560. HasSubstr("Expected unsigned int scalar type as Result Type: "
  561. "ConvertPtrToU"));
  562. }
  563. TEST_F(ValidateConversion, ConvertPtrToUNotPointer) {
  564. const std::string body = R"(
  565. %val = OpConvertPtrToU %u32 %f32_1
  566. )";
  567. CompileSuccessfully(GenerateKernelCode(body).c_str());
  568. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  569. EXPECT_THAT(getDiagnosticString(),
  570. HasSubstr("Expected input to be a pointer: ConvertPtrToU"));
  571. }
  572. TEST_F(ValidateConversion, SatConvertSToUSuccess) {
  573. const std::string body = R"(
  574. %val1 = OpSatConvertSToU %u32 %u64_2
  575. %val2 = OpSatConvertSToU %u64 %u32_1
  576. %val3 = OpSatConvertSToU %u64vec2 %u32vec2_12
  577. )";
  578. CompileSuccessfully(GenerateKernelCode(body).c_str());
  579. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  580. }
  581. TEST_F(ValidateConversion, SatConvertSToUWrongResultType) {
  582. const std::string body = R"(
  583. %val = OpSatConvertSToU %f32 %u32_1
  584. )";
  585. CompileSuccessfully(GenerateKernelCode(body).c_str());
  586. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  587. EXPECT_THAT(getDiagnosticString(),
  588. HasSubstr("Expected int scalar or vector type as Result Type: "
  589. "SatConvertSToU"));
  590. }
  591. TEST_F(ValidateConversion, SatConvertSToUWrongInputType) {
  592. const std::string body = R"(
  593. %val = OpSatConvertSToU %u32 %f32_1
  594. )";
  595. CompileSuccessfully(GenerateKernelCode(body).c_str());
  596. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  597. EXPECT_THAT(
  598. getDiagnosticString(),
  599. HasSubstr("Expected int scalar or vector as input: SatConvertSToU"));
  600. }
  601. TEST_F(ValidateConversion, SatConvertSToUDifferentDimension) {
  602. const std::string body = R"(
  603. %val = OpSatConvertSToU %u32 %u32vec2_12
  604. )";
  605. CompileSuccessfully(GenerateKernelCode(body).c_str());
  606. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  607. EXPECT_THAT(
  608. getDiagnosticString(),
  609. HasSubstr("Expected input to have the same dimension as Result Type: "
  610. "SatConvertSToU"));
  611. }
  612. TEST_F(ValidateConversion, ConvertUToPtrSuccess) {
  613. const std::string body = R"(
  614. %val1 = OpConvertUToPtr %f32ptr_func %u32_1
  615. %val2 = OpConvertUToPtr %f32ptr_func %u64_1
  616. )";
  617. CompileSuccessfully(GenerateKernelCode(body).c_str());
  618. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  619. }
  620. TEST_F(ValidateConversion, ConvertUToPtrWrongResultType) {
  621. const std::string body = R"(
  622. %val = OpConvertUToPtr %f32 %u32_1
  623. )";
  624. CompileSuccessfully(GenerateKernelCode(body).c_str());
  625. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  626. EXPECT_THAT(getDiagnosticString(),
  627. HasSubstr("Expected Result Type to be a pointer: ConvertUToPtr"));
  628. }
  629. TEST_F(ValidateConversion, ConvertUToPtrNotInt) {
  630. const std::string body = R"(
  631. %val = OpConvertUToPtr %f32ptr_func %f32_1
  632. )";
  633. CompileSuccessfully(GenerateKernelCode(body).c_str());
  634. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  635. EXPECT_THAT(getDiagnosticString(),
  636. HasSubstr("Expected int scalar as input: ConvertUToPtr"));
  637. }
  638. TEST_F(ValidateConversion, ConvertUToPtrNotIntScalar) {
  639. const std::string body = R"(
  640. %val = OpConvertUToPtr %f32ptr_func %u32vec2_12
  641. )";
  642. CompileSuccessfully(GenerateKernelCode(body).c_str());
  643. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  644. EXPECT_THAT(getDiagnosticString(),
  645. HasSubstr("Expected int scalar as input: ConvertUToPtr"));
  646. }
  647. TEST_F(ValidateConversion, PtrCastToGenericSuccess) {
  648. const std::string body = R"(
  649. %ptr_func = OpVariable %f32ptr_func Function
  650. %val = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  651. )";
  652. CompileSuccessfully(GenerateKernelCode(body).c_str());
  653. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  654. }
  655. TEST_F(ValidateConversion, PtrCastToGenericWrongResultType) {
  656. const std::string body = R"(
  657. %ptr_func = OpVariable %f32ptr_func Function
  658. %val = OpPtrCastToGeneric %f32 %ptr_func
  659. )";
  660. CompileSuccessfully(GenerateKernelCode(body).c_str());
  661. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  662. EXPECT_THAT(
  663. getDiagnosticString(),
  664. HasSubstr("Expected Result Type to be a pointer: PtrCastToGeneric"));
  665. }
  666. TEST_F(ValidateConversion, PtrCastToGenericWrongResultStorageClass) {
  667. const std::string body = R"(
  668. %ptr_func = OpVariable %f32ptr_func Function
  669. %val = OpPtrCastToGeneric %f32ptr_func %ptr_func
  670. )";
  671. CompileSuccessfully(GenerateKernelCode(body).c_str());
  672. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  673. EXPECT_THAT(getDiagnosticString(),
  674. HasSubstr("Expected Result Type to have storage class Generic: "
  675. "PtrCastToGeneric"));
  676. }
  677. TEST_F(ValidateConversion, PtrCastToGenericWrongInputType) {
  678. const std::string body = R"(
  679. %ptr_func = OpVariable %f32ptr_func Function
  680. %val = OpPtrCastToGeneric %f32ptr_gen %f32
  681. )";
  682. CompileSuccessfully(GenerateKernelCode(body).c_str());
  683. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  684. EXPECT_THAT(getDiagnosticString(),
  685. HasSubstr("Operand '4[%float]' cannot be a "
  686. "type"));
  687. }
  688. TEST_F(ValidateConversion, PtrCastToGenericWrongInputStorageClass) {
  689. const std::string body = R"(
  690. %val = OpPtrCastToGeneric %f32ptr_gen %f32inp
  691. )";
  692. CompileSuccessfully(GenerateKernelCode(body).c_str());
  693. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  694. EXPECT_THAT(getDiagnosticString(),
  695. HasSubstr("Expected input to have storage class Workgroup, "
  696. "CrossWorkgroup or Function: PtrCastToGeneric"));
  697. }
  698. TEST_F(ValidateConversion, PtrCastToGenericPointToDifferentType) {
  699. const std::string body = R"(
  700. %ptr_func = OpVariable %u32ptr_func Function
  701. %val = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  702. )";
  703. CompileSuccessfully(GenerateKernelCode(body).c_str());
  704. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  705. EXPECT_THAT(
  706. getDiagnosticString(),
  707. HasSubstr("Expected input and Result Type to point to the same type: "
  708. "PtrCastToGeneric"));
  709. }
  710. TEST_F(ValidateConversion, GenericCastToPtrSuccess) {
  711. const std::string body = R"(
  712. %ptr_func = OpVariable %f32ptr_func Function
  713. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  714. %ptr_func2 = OpGenericCastToPtr %f32ptr_func %ptr_gen
  715. %ptr_wg = OpGenericCastToPtr %f32ptr_wg %ptr_gen
  716. %ptr_cwg = OpGenericCastToPtr %f32ptr_cwg %ptr_gen
  717. )";
  718. CompileSuccessfully(GenerateKernelCode(body).c_str());
  719. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  720. }
  721. TEST_F(ValidateConversion, GenericCastToPtrWrongResultType) {
  722. const std::string body = R"(
  723. %ptr_func = OpVariable %f32ptr_func Function
  724. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  725. %ptr_func2 = OpGenericCastToPtr %f32 %ptr_gen
  726. )";
  727. CompileSuccessfully(GenerateKernelCode(body).c_str());
  728. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  729. EXPECT_THAT(
  730. getDiagnosticString(),
  731. HasSubstr("Expected Result Type to be a pointer: GenericCastToPtr"));
  732. }
  733. TEST_F(ValidateConversion, GenericCastToPtrWrongResultStorageClass) {
  734. const std::string body = R"(
  735. %ptr_func = OpVariable %f32ptr_func Function
  736. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  737. %ptr_func2 = OpGenericCastToPtr %f32ptr_gen %ptr_gen
  738. )";
  739. CompileSuccessfully(GenerateKernelCode(body).c_str());
  740. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  741. EXPECT_THAT(getDiagnosticString(),
  742. HasSubstr("Expected Result Type to have storage class Workgroup, "
  743. "CrossWorkgroup or Function: GenericCastToPtr"));
  744. }
  745. TEST_F(ValidateConversion, GenericCastToPtrWrongInputType) {
  746. const std::string body = R"(
  747. %ptr_func = OpVariable %f32ptr_func Function
  748. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  749. %ptr_func2 = OpGenericCastToPtr %f32ptr_func %f32_1
  750. )";
  751. CompileSuccessfully(GenerateKernelCode(body).c_str());
  752. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  753. EXPECT_THAT(getDiagnosticString(),
  754. HasSubstr("Expected input to be a pointer: GenericCastToPtr"));
  755. }
  756. TEST_F(ValidateConversion, GenericCastToPtrWrongInputStorageClass) {
  757. const std::string body = R"(
  758. %ptr_func = OpVariable %f32ptr_func Function
  759. %ptr_func2 = OpGenericCastToPtr %f32ptr_func %ptr_func
  760. )";
  761. CompileSuccessfully(GenerateKernelCode(body).c_str());
  762. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  763. EXPECT_THAT(getDiagnosticString(),
  764. HasSubstr("Expected input to have storage class Generic: "
  765. "GenericCastToPtr"));
  766. }
  767. TEST_F(ValidateConversion, GenericCastToPtrPointToDifferentType) {
  768. const std::string body = R"(
  769. %ptr_func = OpVariable %f32ptr_func Function
  770. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  771. %ptr_func2 = OpGenericCastToPtr %u32ptr_func %ptr_gen
  772. )";
  773. CompileSuccessfully(GenerateKernelCode(body).c_str());
  774. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  775. EXPECT_THAT(
  776. getDiagnosticString(),
  777. HasSubstr("Expected input and Result Type to point to the same type: "
  778. "GenericCastToPtr"));
  779. }
  780. TEST_F(ValidateConversion, GenericCastToPtrExplicitSuccess) {
  781. const std::string body = R"(
  782. %ptr_func = OpVariable %f32ptr_func Function
  783. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  784. %ptr_func2 = OpGenericCastToPtrExplicit %f32ptr_func %ptr_gen Function
  785. %ptr_wg = OpGenericCastToPtrExplicit %f32ptr_wg %ptr_gen Workgroup
  786. %ptr_cwg = OpGenericCastToPtrExplicit %f32ptr_cwg %ptr_gen CrossWorkgroup
  787. )";
  788. CompileSuccessfully(GenerateKernelCode(body).c_str());
  789. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  790. }
  791. TEST_F(ValidateConversion, GenericCastToPtrExplicitWrongResultType) {
  792. const std::string body = R"(
  793. %ptr_func = OpVariable %f32ptr_func Function
  794. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  795. %ptr_func2 = OpGenericCastToPtrExplicit %f32 %ptr_gen Function
  796. )";
  797. CompileSuccessfully(GenerateKernelCode(body).c_str());
  798. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  799. EXPECT_THAT(
  800. getDiagnosticString(),
  801. HasSubstr(
  802. "Expected Result Type to be a pointer: GenericCastToPtrExplicit"));
  803. }
  804. TEST_F(ValidateConversion, GenericCastToPtrExplicitResultStorageClassDiffers) {
  805. const std::string body = R"(
  806. %ptr_func = OpVariable %f32ptr_func Function
  807. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  808. %ptr_func2 = OpGenericCastToPtrExplicit %f32ptr_func %ptr_gen Workgroup
  809. )";
  810. CompileSuccessfully(GenerateKernelCode(body).c_str());
  811. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  812. EXPECT_THAT(getDiagnosticString(),
  813. HasSubstr("Expected Result Type to be of target storage class: "
  814. "GenericCastToPtrExplicit"));
  815. }
  816. TEST_F(ValidateConversion, GenericCastToPtrExplicitWrongResultStorageClass) {
  817. const std::string body = R"(
  818. %ptr_func = OpVariable %f32ptr_func Function
  819. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  820. %ptr_func2 = OpGenericCastToPtrExplicit %f32ptr_gen %ptr_gen Generic
  821. )";
  822. CompileSuccessfully(GenerateKernelCode(body).c_str());
  823. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  824. EXPECT_THAT(
  825. getDiagnosticString(),
  826. HasSubstr("Expected target storage class to be Workgroup, "
  827. "CrossWorkgroup or Function: GenericCastToPtrExplicit"));
  828. }
  829. TEST_F(ValidateConversion, GenericCastToPtrExplicitWrongInputType) {
  830. const std::string body = R"(
  831. %ptr_func = OpVariable %f32ptr_func Function
  832. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  833. %ptr_func2 = OpGenericCastToPtrExplicit %f32ptr_func %f32_1 Function
  834. )";
  835. CompileSuccessfully(GenerateKernelCode(body).c_str());
  836. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  837. EXPECT_THAT(
  838. getDiagnosticString(),
  839. HasSubstr("Expected input to be a pointer: GenericCastToPtrExplicit"));
  840. }
  841. TEST_F(ValidateConversion, GenericCastToPtrExplicitWrongInputStorageClass) {
  842. const std::string body = R"(
  843. %ptr_func = OpVariable %f32ptr_func Function
  844. %ptr_func2 = OpGenericCastToPtrExplicit %f32ptr_func %ptr_func Function
  845. )";
  846. CompileSuccessfully(GenerateKernelCode(body).c_str());
  847. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  848. EXPECT_THAT(getDiagnosticString(),
  849. HasSubstr("Expected input to have storage class Generic: "
  850. "GenericCastToPtrExplicit"));
  851. }
  852. TEST_F(ValidateConversion, GenericCastToPtrExplicitPointToDifferentType) {
  853. const std::string body = R"(
  854. %ptr_func = OpVariable %f32ptr_func Function
  855. %ptr_gen = OpPtrCastToGeneric %f32ptr_gen %ptr_func
  856. %ptr_func2 = OpGenericCastToPtrExplicit %u32ptr_func %ptr_gen Function
  857. )";
  858. CompileSuccessfully(GenerateKernelCode(body).c_str());
  859. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  860. EXPECT_THAT(
  861. getDiagnosticString(),
  862. HasSubstr("Expected input and Result Type to point to the same type: "
  863. "GenericCastToPtrExplicit"));
  864. }
  865. TEST_F(ValidateConversion, CoopMatConversionSuccess) {
  866. const std::string body =
  867. R"(
  868. OpCapability Shader
  869. OpCapability Float16
  870. OpCapability Int16
  871. OpCapability CooperativeMatrixNV
  872. OpExtension "SPV_NV_cooperative_matrix"
  873. OpMemoryModel Logical GLSL450
  874. OpEntryPoint GLCompute %main "main"
  875. %void = OpTypeVoid
  876. %func = OpTypeFunction %void
  877. %bool = OpTypeBool
  878. %f16 = OpTypeFloat 16
  879. %f32 = OpTypeFloat 32
  880. %u16 = OpTypeInt 16 0
  881. %u32 = OpTypeInt 32 0
  882. %s16 = OpTypeInt 16 1
  883. %s32 = OpTypeInt 32 1
  884. %u32_8 = OpConstant %u32 8
  885. %subgroup = OpConstant %u32 3
  886. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  887. %f32mat = OpTypeCooperativeMatrixNV %f32 %subgroup %u32_8 %u32_8
  888. %u16mat = OpTypeCooperativeMatrixNV %u16 %subgroup %u32_8 %u32_8
  889. %u32mat = OpTypeCooperativeMatrixNV %u32 %subgroup %u32_8 %u32_8
  890. %s16mat = OpTypeCooperativeMatrixNV %s16 %subgroup %u32_8 %u32_8
  891. %s32mat = OpTypeCooperativeMatrixNV %s32 %subgroup %u32_8 %u32_8
  892. %f16_1 = OpConstant %f16 1
  893. %f32_1 = OpConstant %f32 1
  894. %u16_1 = OpConstant %u16 1
  895. %u32_1 = OpConstant %u32 1
  896. %s16_1 = OpConstant %s16 1
  897. %s32_1 = OpConstant %s32 1
  898. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  899. %f32mat_1 = OpConstantComposite %f32mat %f32_1
  900. %u16mat_1 = OpConstantComposite %u16mat %u16_1
  901. %u32mat_1 = OpConstantComposite %u32mat %u32_1
  902. %s16mat_1 = OpConstantComposite %s16mat %s16_1
  903. %s32mat_1 = OpConstantComposite %s32mat %s32_1
  904. %main = OpFunction %void None %func
  905. %main_entry = OpLabel
  906. %val11 = OpConvertFToU %u16mat %f16mat_1
  907. %val12 = OpConvertFToU %u32mat %f16mat_1
  908. %val13 = OpConvertFToS %s16mat %f16mat_1
  909. %val14 = OpConvertFToS %s32mat %f16mat_1
  910. %val15 = OpFConvert %f32mat %f16mat_1
  911. %val21 = OpConvertFToU %u16mat %f32mat_1
  912. %val22 = OpConvertFToU %u32mat %f32mat_1
  913. %val23 = OpConvertFToS %s16mat %f32mat_1
  914. %val24 = OpConvertFToS %s32mat %f32mat_1
  915. %val25 = OpFConvert %f16mat %f32mat_1
  916. %val31 = OpConvertUToF %f16mat %u16mat_1
  917. %val32 = OpConvertUToF %f32mat %u16mat_1
  918. %val33 = OpUConvert %u32mat %u16mat_1
  919. %val34 = OpSConvert %s32mat %u16mat_1
  920. %val41 = OpConvertSToF %f16mat %s16mat_1
  921. %val42 = OpConvertSToF %f32mat %s16mat_1
  922. %val43 = OpUConvert %u32mat %s16mat_1
  923. %val44 = OpSConvert %s32mat %s16mat_1
  924. OpReturn
  925. OpFunctionEnd)";
  926. CompileSuccessfully(body.c_str());
  927. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  928. }
  929. TEST_F(ValidateConversion, CoopMatConversionShapesMismatchFail) {
  930. const std::string body =
  931. R"(
  932. OpCapability Shader
  933. OpCapability Float16
  934. OpCapability Int16
  935. OpCapability CooperativeMatrixNV
  936. OpExtension "SPV_NV_cooperative_matrix"
  937. OpMemoryModel Logical GLSL450
  938. OpEntryPoint GLCompute %main "main"
  939. %void = OpTypeVoid
  940. %func = OpTypeFunction %void
  941. %bool = OpTypeBool
  942. %f16 = OpTypeFloat 16
  943. %f32 = OpTypeFloat 32
  944. %u16 = OpTypeInt 16 0
  945. %u32 = OpTypeInt 32 0
  946. %s16 = OpTypeInt 16 1
  947. %s32 = OpTypeInt 32 1
  948. %u32_8 = OpConstant %u32 8
  949. %u32_4 = OpConstant %u32 4
  950. %subgroup = OpConstant %u32 3
  951. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  952. %f32mat = OpTypeCooperativeMatrixNV %f32 %subgroup %u32_4 %u32_4
  953. %f16_1 = OpConstant %f16 1
  954. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  955. %main = OpFunction %void None %func
  956. %main_entry = OpLabel
  957. %val15 = OpFConvert %f32mat %f16mat_1
  958. OpReturn
  959. OpFunctionEnd)";
  960. CompileSuccessfully(body.c_str());
  961. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  962. EXPECT_THAT(
  963. getDiagnosticString(),
  964. HasSubstr(
  965. "Expected rows of Matrix type and Result Type to be identical"));
  966. }
  967. TEST_F(ValidateConversion, CoopMatConversionShapesMismatchPass) {
  968. const std::string body =
  969. R"(
  970. OpCapability Shader
  971. OpCapability Float16
  972. OpCapability Int16
  973. OpCapability CooperativeMatrixNV
  974. OpExtension "SPV_NV_cooperative_matrix"
  975. OpMemoryModel Logical GLSL450
  976. OpEntryPoint GLCompute %main "main"
  977. %void = OpTypeVoid
  978. %func = OpTypeFunction %void
  979. %bool = OpTypeBool
  980. %f16 = OpTypeFloat 16
  981. %f32 = OpTypeFloat 32
  982. %u16 = OpTypeInt 16 0
  983. %u32 = OpTypeInt 32 0
  984. %s16 = OpTypeInt 16 1
  985. %s32 = OpTypeInt 32 1
  986. %u32_8 = OpConstant %u32 8
  987. %u32_4 = OpSpecConstant %u32 4
  988. %subgroup = OpConstant %u32 3
  989. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  990. %f32mat = OpTypeCooperativeMatrixNV %f32 %subgroup %u32_4 %u32_4
  991. %f16_1 = OpConstant %f16 1
  992. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  993. %main = OpFunction %void None %func
  994. %main_entry = OpLabel
  995. %val15 = OpFConvert %f32mat %f16mat_1
  996. OpReturn
  997. OpFunctionEnd)";
  998. CompileSuccessfully(body.c_str());
  999. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1000. }
  1001. TEST_F(ValidateConversion, BitcastSuccess) {
  1002. const std::string body = R"(
  1003. %ptr = OpVariable %f32ptr_func Function
  1004. %val1 = OpBitcast %u32 %ptr
  1005. %val2 = OpBitcast %u64 %ptr
  1006. %val3 = OpBitcast %f32ptr_func %u32_1
  1007. %val4 = OpBitcast %f32ptr_wg %u64_1
  1008. %val5 = OpBitcast %f32 %u32_1
  1009. %val6 = OpBitcast %f32vec2 %u32vec2_12
  1010. %val7 = OpBitcast %f32vec2 %u64_1
  1011. %val8 = OpBitcast %f64 %u32vec2_12
  1012. %val9 = OpBitcast %f32vec4 %f64vec2_12
  1013. )";
  1014. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1015. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1016. }
  1017. TEST_F(ValidateConversion, BitcastSuccessSPV1p5) {
  1018. const std::string body = R"(
  1019. %ptr = OpVariable %f32ptr_func Function
  1020. %val1 = OpBitcast %u32 %ptr
  1021. %val2 = OpBitcast %u64 %ptr
  1022. %val3 = OpBitcast %f32ptr_func %u32_1
  1023. %val4 = OpBitcast %f32ptr_wg %u64_1
  1024. %val5 = OpBitcast %f32 %u32_1
  1025. %val6 = OpBitcast %f32vec2 %u32vec2_12
  1026. %val7 = OpBitcast %f32vec2 %u64_1
  1027. %val8 = OpBitcast %f64 %u32vec2_12
  1028. %val9 = OpBitcast %f32vec4 %f64vec2_12
  1029. %val10 = OpBitcast %u32ptr_func %u32vec2_01
  1030. %val11 = OpBitcast %u32vec2 %ptr
  1031. )";
  1032. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1033. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1034. }
  1035. TEST_F(ValidateConversion, BitcastSuccessPhysicalStorageBufferKHR) {
  1036. const std::string body = R"(
  1037. %ptr = OpVariable %f32ptr_func Function
  1038. %val1 = OpBitcast %u32 %ptr
  1039. %val2 = OpBitcast %u64 %ptr
  1040. %val3 = OpBitcast %f32ptr_func %u32_1
  1041. %val4 = OpBitcast %f32ptr_wg %u64_1
  1042. %val5 = OpBitcast %f32 %u32_1
  1043. %val6 = OpBitcast %f32vec2 %u32vec2_12
  1044. %val7 = OpBitcast %f32vec2 %u64_1
  1045. %val8 = OpBitcast %f64 %u32vec2_12
  1046. %val9 = OpBitcast %f32vec4 %f64vec2_12
  1047. %val10 = OpBitcast %u32ptr_func %u32vec2_01
  1048. %val11 = OpBitcast %u32vec2 %ptr
  1049. )";
  1050. CompileSuccessfully(
  1051. GenerateKernelCode(body,
  1052. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1053. .c_str());
  1054. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1055. }
  1056. TEST_F(ValidateConversion, BitcastInputHasNoType) {
  1057. const std::string body = R"(
  1058. %val = OpBitcast %u32 %f32
  1059. )";
  1060. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1061. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1062. EXPECT_THAT(getDiagnosticString(),
  1063. HasSubstr("Operand '4[%float]' cannot be a "
  1064. "type"));
  1065. }
  1066. TEST_F(ValidateConversion, BitcastWrongResultType) {
  1067. const std::string body = R"(
  1068. %val = OpBitcast %bool %f32_1
  1069. )";
  1070. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1071. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1072. EXPECT_THAT(
  1073. getDiagnosticString(),
  1074. HasSubstr("Expected Result Type to be a pointer or int or float vector "
  1075. "or scalar type: Bitcast"));
  1076. }
  1077. TEST_F(ValidateConversion, BitcastWrongInputType) {
  1078. const std::string body = R"(
  1079. %val = OpBitcast %u32 %true
  1080. )";
  1081. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1082. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1083. EXPECT_THAT(getDiagnosticString(),
  1084. HasSubstr("Expected input to be a pointer or int or float vector "
  1085. "or scalar: Bitcast"));
  1086. }
  1087. TEST_F(ValidateConversion, BitcastPtrWrongInputType) {
  1088. const std::string body = R"(
  1089. %val = OpBitcast %u32ptr_func %f32_1
  1090. )";
  1091. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1092. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1093. EXPECT_THAT(getDiagnosticString(),
  1094. HasSubstr("Expected input to be a pointer or int scalar if "
  1095. "Result Type is pointer: Bitcast"));
  1096. }
  1097. TEST_F(ValidateConversion, BitcastPtrWrongInputTypeSPV1p5) {
  1098. const std::string body = R"(
  1099. %val = OpBitcast %u32ptr_func %f32_1
  1100. )";
  1101. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1102. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1103. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1104. EXPECT_THAT(getDiagnosticString(),
  1105. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1106. "int vector if Result Type is pointer: Bitcast"));
  1107. }
  1108. TEST_F(ValidateConversion, BitcastPtrWrongInputTypePhysicalStorageBufferKHR) {
  1109. const std::string body = R"(
  1110. %val = OpBitcast %u32ptr_func %f32_1
  1111. )";
  1112. CompileSuccessfully(
  1113. GenerateKernelCode(body,
  1114. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1115. .c_str());
  1116. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1117. EXPECT_THAT(getDiagnosticString(),
  1118. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1119. "int vector if Result Type is pointer: Bitcast"));
  1120. }
  1121. TEST_F(ValidateConversion, BitcastPtrWrongInputTypeIntVectorSPV1p5) {
  1122. const std::string body = R"(
  1123. %val = OpBitcast %u32ptr_func %u64vec2_01
  1124. )";
  1125. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1126. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1127. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1128. EXPECT_THAT(getDiagnosticString(),
  1129. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1130. "int vector if Result Type is pointer: Bitcast"));
  1131. }
  1132. TEST_F(ValidateConversion,
  1133. BitcastPtrWrongInputTypeIntVectorPhysicalStorageBufferKHR) {
  1134. const std::string body = R"(
  1135. %val = OpBitcast %u32ptr_func %u64vec2_01
  1136. )";
  1137. CompileSuccessfully(
  1138. GenerateKernelCode(body,
  1139. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1140. .c_str());
  1141. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1142. EXPECT_THAT(getDiagnosticString(),
  1143. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1144. "int vector if Result Type is pointer: Bitcast"));
  1145. }
  1146. TEST_F(ValidateConversion, BitcastPtrWrongResultType) {
  1147. const std::string body = R"(
  1148. %val = OpBitcast %f32 %f32inp
  1149. )";
  1150. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1151. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1152. EXPECT_THAT(getDiagnosticString(),
  1153. HasSubstr("Pointer can only be converted to another pointer or "
  1154. "int scalar: Bitcast"));
  1155. }
  1156. TEST_F(ValidateConversion, BitcastPtrWrongResultTypeSPV1p5) {
  1157. const std::string body = R"(
  1158. %val = OpBitcast %f32 %f32inp
  1159. )";
  1160. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1161. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1162. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1163. EXPECT_THAT(getDiagnosticString(),
  1164. HasSubstr("Pointer can only be converted to another pointer, int "
  1165. "scalar or 32-bit int vector: Bitcast"));
  1166. }
  1167. TEST_F(ValidateConversion, BitcastPtrWrongResultTypePhysicalStorageBufferKHR) {
  1168. const std::string body = R"(
  1169. %val = OpBitcast %f32 %f32inp
  1170. )";
  1171. CompileSuccessfully(
  1172. GenerateKernelCode(body,
  1173. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1174. .c_str());
  1175. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1176. EXPECT_THAT(getDiagnosticString(),
  1177. HasSubstr("Pointer can only be converted to another pointer, int "
  1178. "scalar or 32-bit int vector: Bitcast"));
  1179. }
  1180. TEST_F(ValidateConversion, BitcastPtrWrongResultTypeIntVectorSPV1p5) {
  1181. const std::string body = R"(
  1182. %val = OpBitcast %u64vec2 %f32inp
  1183. )";
  1184. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1185. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1186. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1187. EXPECT_THAT(getDiagnosticString(),
  1188. HasSubstr("Pointer can only be converted to another pointer, int "
  1189. "scalar or 32-bit int vector: Bitcast"));
  1190. }
  1191. TEST_F(ValidateConversion,
  1192. BitcastPtrWrongResultTypeIntVectorPhysicalStorageBufferKHR) {
  1193. const std::string body = R"(
  1194. %val = OpBitcast %u64vec2 %f32inp
  1195. )";
  1196. CompileSuccessfully(
  1197. GenerateKernelCode(body,
  1198. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1199. .c_str());
  1200. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1201. EXPECT_THAT(getDiagnosticString(),
  1202. HasSubstr("Pointer can only be converted to another pointer, int "
  1203. "scalar or 32-bit int vector: Bitcast"));
  1204. }
  1205. TEST_F(ValidateConversion, BitcastDifferentTotalBitWidth) {
  1206. const std::string body = R"(
  1207. %val = OpBitcast %f32 %u64_1
  1208. )";
  1209. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1210. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1211. EXPECT_THAT(
  1212. getDiagnosticString(),
  1213. HasSubstr(
  1214. "Expected input to have the same total bit width as Result Type: "
  1215. "Bitcast"));
  1216. }
  1217. TEST_F(ValidateConversion, ConvertUToPtrInputIsAType) {
  1218. const std::string spirv = R"(
  1219. OpCapability Addresses
  1220. OpCapability Shader
  1221. OpCapability Linkage
  1222. OpMemoryModel Logical GLSL450
  1223. %int = OpTypeInt 32 0
  1224. %ptr_int = OpTypePointer Function %int
  1225. %void = OpTypeVoid
  1226. %voidfn = OpTypeFunction %void
  1227. %func = OpFunction %void None %voidfn
  1228. %entry = OpLabel
  1229. %1 = OpConvertUToPtr %ptr_int %int
  1230. OpReturn
  1231. OpFunctionEnd
  1232. )";
  1233. CompileSuccessfully(spirv);
  1234. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1235. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand '1[%uint]' cannot be a "
  1236. "type"));
  1237. }
  1238. TEST_F(ValidateConversion, ConvertUToPtrPSBSuccess) {
  1239. const std::string body = R"(
  1240. OpCapability PhysicalStorageBufferAddresses
  1241. OpCapability Int64
  1242. OpCapability Shader
  1243. OpExtension "SPV_EXT_physical_storage_buffer"
  1244. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1245. OpEntryPoint Fragment %main "main"
  1246. OpExecutionMode %main OriginUpperLeft
  1247. %uint64 = OpTypeInt 64 0
  1248. %u64_1 = OpConstant %uint64 1
  1249. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1250. %void = OpTypeVoid
  1251. %voidfn = OpTypeFunction %void
  1252. %main = OpFunction %void None %voidfn
  1253. %entry = OpLabel
  1254. %val1 = OpConvertUToPtr %ptr %u64_1
  1255. OpReturn
  1256. OpFunctionEnd
  1257. )";
  1258. CompileSuccessfully(body.c_str());
  1259. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1260. }
  1261. TEST_F(ValidateConversion, ConvertUToPtrPSBStorageClass) {
  1262. const std::string body = R"(
  1263. OpCapability PhysicalStorageBufferAddresses
  1264. OpCapability Int64
  1265. OpCapability Shader
  1266. OpExtension "SPV_EXT_physical_storage_buffer"
  1267. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1268. OpEntryPoint Fragment %main "main"
  1269. OpExecutionMode %main OriginUpperLeft
  1270. %uint64 = OpTypeInt 64 0
  1271. %u64_1 = OpConstant %uint64 1
  1272. %ptr = OpTypePointer Function %uint64
  1273. %void = OpTypeVoid
  1274. %voidfn = OpTypeFunction %void
  1275. %main = OpFunction %void None %voidfn
  1276. %entry = OpLabel
  1277. %val1 = OpConvertUToPtr %ptr %u64_1
  1278. %val2 = OpConvertPtrToU %uint64 %val1
  1279. OpReturn
  1280. OpFunctionEnd
  1281. )";
  1282. CompileSuccessfully(body.c_str());
  1283. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1284. EXPECT_THAT(getDiagnosticString(),
  1285. HasSubstr("Pointer storage class must be "
  1286. "PhysicalStorageBuffer: ConvertUToPtr"));
  1287. }
  1288. TEST_F(ValidateConversion, ConvertUToPtrVulkanWrongWidth) {
  1289. const std::string body = R"(
  1290. OpCapability PhysicalStorageBufferAddresses
  1291. OpCapability Int64
  1292. OpCapability Shader
  1293. OpExtension "SPV_EXT_physical_storage_buffer"
  1294. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1295. OpEntryPoint Fragment %main "main"
  1296. OpExecutionMode %main OriginUpperLeft
  1297. %uint32 = OpTypeInt 32 0
  1298. %uint64 = OpTypeInt 64 0
  1299. %u32_1 = OpConstant %uint32 1
  1300. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1301. %void = OpTypeVoid
  1302. %voidfn = OpTypeFunction %void
  1303. %main = OpFunction %void None %voidfn
  1304. %entry = OpLabel
  1305. %val1 = OpConvertUToPtr %ptr %u32_1
  1306. OpReturn
  1307. OpFunctionEnd
  1308. )";
  1309. CompileSuccessfully(body.c_str());
  1310. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1311. EXPECT_THAT(getDiagnosticString(),
  1312. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710"));
  1313. EXPECT_THAT(
  1314. getDiagnosticString(),
  1315. HasSubstr("PhysicalStorageBuffer64 addressing mode requires the input "
  1316. "integer to have a 64-bit width for Vulkan environment."));
  1317. }
  1318. TEST_F(ValidateConversion, ConvertPtrToUPSBSuccess) {
  1319. const std::string body = R"(
  1320. OpCapability PhysicalStorageBufferAddresses
  1321. OpCapability Int64
  1322. OpCapability Shader
  1323. OpExtension "SPV_EXT_physical_storage_buffer"
  1324. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1325. OpEntryPoint Fragment %main "main"
  1326. OpExecutionMode %main OriginUpperLeft
  1327. OpDecorate %val1 RestrictPointer
  1328. %uint64 = OpTypeInt 64 0
  1329. %u64_1 = OpConstant %uint64 1
  1330. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1331. %pptr_f = OpTypePointer Function %ptr
  1332. %void = OpTypeVoid
  1333. %voidfn = OpTypeFunction %void
  1334. %main = OpFunction %void None %voidfn
  1335. %entry = OpLabel
  1336. %val1 = OpVariable %pptr_f Function
  1337. %val2 = OpLoad %ptr %val1
  1338. %val3 = OpConvertPtrToU %uint64 %val2
  1339. OpReturn
  1340. OpFunctionEnd
  1341. )";
  1342. CompileSuccessfully(body.c_str());
  1343. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1344. }
  1345. TEST_F(ValidateConversion, ConvertPtrToUPSBStorageClass) {
  1346. const std::string body = R"(
  1347. OpCapability PhysicalStorageBufferAddresses
  1348. OpCapability Int64
  1349. OpCapability Shader
  1350. OpExtension "SPV_EXT_physical_storage_buffer"
  1351. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1352. OpEntryPoint Fragment %main "main"
  1353. OpExecutionMode %main OriginUpperLeft
  1354. %uint64 = OpTypeInt 64 0
  1355. %u64_1 = OpConstant %uint64 1
  1356. %ptr = OpTypePointer Function %uint64
  1357. %void = OpTypeVoid
  1358. %voidfn = OpTypeFunction %void
  1359. %main = OpFunction %void None %voidfn
  1360. %entry = OpLabel
  1361. %val1 = OpVariable %ptr Function
  1362. %val2 = OpConvertPtrToU %uint64 %val1
  1363. OpReturn
  1364. OpFunctionEnd
  1365. )";
  1366. CompileSuccessfully(body.c_str());
  1367. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1368. EXPECT_THAT(getDiagnosticString(),
  1369. HasSubstr("Pointer storage class must be "
  1370. "PhysicalStorageBuffer: ConvertPtrToU"));
  1371. }
  1372. TEST_F(ValidateConversion, ConvertPtrToUVulkanWrongWidth) {
  1373. const std::string body = R"(
  1374. OpCapability PhysicalStorageBufferAddresses
  1375. OpCapability Int64
  1376. OpCapability Shader
  1377. OpExtension "SPV_EXT_physical_storage_buffer"
  1378. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1379. OpEntryPoint Fragment %main "main"
  1380. OpExecutionMode %main OriginUpperLeft
  1381. OpDecorate %val1 RestrictPointer
  1382. %uint32 = OpTypeInt 32 0
  1383. %uint64 = OpTypeInt 64 0
  1384. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1385. %pptr_f = OpTypePointer Function %ptr
  1386. %void = OpTypeVoid
  1387. %voidfn = OpTypeFunction %void
  1388. %main = OpFunction %void None %voidfn
  1389. %entry = OpLabel
  1390. %val1 = OpVariable %pptr_f Function
  1391. %val2 = OpLoad %ptr %val1
  1392. %val3 = OpConvertPtrToU %uint32 %val2
  1393. OpReturn
  1394. OpFunctionEnd
  1395. )";
  1396. CompileSuccessfully(body.c_str());
  1397. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1398. EXPECT_THAT(getDiagnosticString(),
  1399. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710"));
  1400. EXPECT_THAT(
  1401. getDiagnosticString(),
  1402. HasSubstr("PhysicalStorageBuffer64 addressing mode requires the result "
  1403. "integer type to have a 64-bit width for Vulkan environment."));
  1404. }
  1405. TEST_F(ValidateConversion, ConvertUToAccelerationStructureU32Vec2) {
  1406. const std::string extensions = R"(
  1407. OpCapability RayQueryKHR
  1408. OpExtension "SPV_KHR_ray_query"
  1409. )";
  1410. const std::string types = R"(
  1411. %u32vec2ptr_func = OpTypePointer Function %u32vec2
  1412. %typeAS = OpTypeAccelerationStructureKHR
  1413. )";
  1414. const std::string body = R"(
  1415. %asHandle = OpVariable %u32vec2ptr_func Function
  1416. %load = OpLoad %u32vec2 %asHandle
  1417. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1418. )";
  1419. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1420. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1421. }
  1422. TEST_F(ValidateConversion, ConvertUToAccelerationStructureSuccessU64) {
  1423. const std::string extensions = R"(
  1424. OpCapability RayQueryKHR
  1425. OpExtension "SPV_KHR_ray_query"
  1426. )";
  1427. const std::string types = R"(
  1428. %u64_func = OpTypePointer Function %u64
  1429. %typeAS = OpTypeAccelerationStructureKHR
  1430. )";
  1431. const std::string body = R"(
  1432. %asHandle = OpVariable %u64_func Function
  1433. %load = OpLoad %u64 %asHandle
  1434. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1435. )";
  1436. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1437. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1438. }
  1439. TEST_F(ValidateConversion, ConvertUToAccelerationStructureResult) {
  1440. const std::string extensions = R"(
  1441. OpCapability RayQueryKHR
  1442. OpExtension "SPV_KHR_ray_query"
  1443. )";
  1444. const std::string types = R"(
  1445. %u32vec2ptr_func = OpTypePointer Function %u32vec2
  1446. %typeRQ = OpTypeRayQueryKHR
  1447. )";
  1448. const std::string body = R"(
  1449. %asHandle = OpVariable %u32vec2ptr_func Function
  1450. %load = OpLoad %u32vec2 %asHandle
  1451. %val = OpConvertUToAccelerationStructureKHR %typeRQ %load
  1452. )";
  1453. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1454. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1455. EXPECT_THAT(getDiagnosticString(),
  1456. HasSubstr("Expected Result Type to be a Acceleration Structure"));
  1457. }
  1458. TEST_F(ValidateConversion, ConvertUToAccelerationStructureU32) {
  1459. const std::string extensions = R"(
  1460. OpCapability RayQueryKHR
  1461. OpExtension "SPV_KHR_ray_query"
  1462. )";
  1463. const std::string types = R"(
  1464. %u32ptr_func = OpTypePointer Function %u32
  1465. %typeAS = OpTypeAccelerationStructureKHR
  1466. )";
  1467. const std::string body = R"(
  1468. %asHandle = OpVariable %u32ptr_func Function
  1469. %load = OpLoad %u32 %asHandle
  1470. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1471. )";
  1472. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1473. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1474. EXPECT_THAT(getDiagnosticString(),
  1475. HasSubstr("Expected 64-bit uint scalar or 2-component 32-bit "
  1476. "uint vector as input"));
  1477. }
  1478. TEST_F(ValidateConversion, ConvertUToAccelerationStructureS64) {
  1479. const std::string extensions = R"(
  1480. OpCapability RayQueryKHR
  1481. OpExtension "SPV_KHR_ray_query"
  1482. )";
  1483. const std::string types = R"(
  1484. %s64ptr_func = OpTypePointer Function %s64
  1485. %typeAS = OpTypeAccelerationStructureKHR
  1486. )";
  1487. const std::string body = R"(
  1488. %asHandle = OpVariable %s64ptr_func Function
  1489. %load = OpLoad %s64 %asHandle
  1490. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1491. )";
  1492. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1493. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1494. EXPECT_THAT(getDiagnosticString(),
  1495. HasSubstr("Expected 64-bit uint scalar or 2-component 32-bit "
  1496. "uint vector as input"));
  1497. }
  1498. TEST_F(ValidateConversion, ConvertUToAccelerationStructureS32Vec2) {
  1499. const std::string extensions = R"(
  1500. OpCapability RayQueryKHR
  1501. OpExtension "SPV_KHR_ray_query"
  1502. )";
  1503. const std::string types = R"(
  1504. %s32vec2ptr_func = OpTypePointer Function %s32vec2
  1505. %typeAS = OpTypeAccelerationStructureKHR
  1506. )";
  1507. const std::string body = R"(
  1508. %asHandle = OpVariable %s32vec2ptr_func Function
  1509. %load = OpLoad %s32vec2 %asHandle
  1510. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1511. )";
  1512. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1513. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1514. EXPECT_THAT(getDiagnosticString(),
  1515. HasSubstr("Expected 64-bit uint scalar or 2-component 32-bit "
  1516. "uint vector as input"));
  1517. }
  1518. using ValidateSmallConversions = spvtest::ValidateBase<std::string>;
  1519. CodeGenerator GetSmallConversionsCodeGenerator() {
  1520. CodeGenerator generator;
  1521. generator.capabilities_ = R"(
  1522. OpCapability Shader
  1523. OpCapability Linkage
  1524. OpCapability UniformAndStorageBuffer16BitAccess
  1525. OpCapability UniformAndStorageBuffer8BitAccess
  1526. )";
  1527. generator.extensions_ = R"(
  1528. OpExtension "SPV_KHR_16bit_storage"
  1529. OpExtension "SPV_KHR_8bit_storage"
  1530. )";
  1531. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  1532. generator.before_types_ = R"(
  1533. OpDecorate %char_block Block
  1534. OpMemberDecorate %char_block 0 Offset 0
  1535. OpDecorate %short_block Block
  1536. OpMemberDecorate %short_block 0 Offset 0
  1537. OpDecorate %half_block Block
  1538. OpMemberDecorate %half_block 0 Offset 0
  1539. OpDecorate %int_block Block
  1540. OpMemberDecorate %int_block 0 Offset 0
  1541. OpDecorate %float_block Block
  1542. OpMemberDecorate %float_block 0 Offset 0
  1543. )";
  1544. generator.types_ = R"(
  1545. %void = OpTypeVoid
  1546. %int = OpTypeInt 32 0
  1547. %int_0 = OpConstant %int 0
  1548. %int_1 = OpConstant %int 1
  1549. %int2 = OpTypeVector %int 2
  1550. %float = OpTypeFloat 32
  1551. %float_0 = OpConstant %float 0
  1552. %float2 = OpTypeVector %float 2
  1553. %char = OpTypeInt 8 0
  1554. %char2 = OpTypeVector %char 2
  1555. %short = OpTypeInt 16 0
  1556. %short2 = OpTypeVector %short 2
  1557. %half = OpTypeFloat 16
  1558. %half2 = OpTypeVector %half 2
  1559. %char_block = OpTypeStruct %char2
  1560. %short_block = OpTypeStruct %short2
  1561. %half_block = OpTypeStruct %half2
  1562. %int_block = OpTypeStruct %int2
  1563. %float_block = OpTypeStruct %float2
  1564. %ptr_ssbo_char_block = OpTypePointer StorageBuffer %char_block
  1565. %ptr_ssbo_char2 = OpTypePointer StorageBuffer %char2
  1566. %ptr_ssbo_char = OpTypePointer StorageBuffer %char
  1567. %ptr_ssbo_short_block = OpTypePointer StorageBuffer %short_block
  1568. %ptr_ssbo_short2 = OpTypePointer StorageBuffer %short2
  1569. %ptr_ssbo_short = OpTypePointer StorageBuffer %short
  1570. %ptr_ssbo_half_block = OpTypePointer StorageBuffer %half_block
  1571. %ptr_ssbo_half2 = OpTypePointer StorageBuffer %half2
  1572. %ptr_ssbo_half = OpTypePointer StorageBuffer %half
  1573. %ptr_ssbo_int_block = OpTypePointer StorageBuffer %int_block
  1574. %ptr_ssbo_int2 = OpTypePointer StorageBuffer %int2
  1575. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1576. %ptr_ssbo_float_block = OpTypePointer StorageBuffer %float_block
  1577. %ptr_ssbo_float2 = OpTypePointer StorageBuffer %float2
  1578. %ptr_ssbo_float = OpTypePointer StorageBuffer %float
  1579. %void_fn = OpTypeFunction %void
  1580. %char_var = OpVariable %ptr_ssbo_char_block StorageBuffer
  1581. %short_var = OpVariable %ptr_ssbo_short_block StorageBuffer
  1582. %half_var = OpVariable %ptr_ssbo_half_block StorageBuffer
  1583. %int_var = OpVariable %ptr_ssbo_int_block StorageBuffer
  1584. %float_var = OpVariable %ptr_ssbo_float_block StorageBuffer
  1585. )";
  1586. generator.after_types_ = R"(
  1587. %func = OpFunction %void None %void_fn
  1588. %entry = OpLabel
  1589. %char2_gep = OpAccessChain %ptr_ssbo_char2 %char_var %int_0
  1590. %ld_char2 = OpLoad %char2 %char2_gep
  1591. %char_gep = OpAccessChain %ptr_ssbo_char %char_var %int_0 %int_0
  1592. %ld_char = OpLoad %char %char_gep
  1593. %short2_gep = OpAccessChain %ptr_ssbo_short2 %short_var %int_0
  1594. %ld_short2 = OpLoad %short2 %short2_gep
  1595. %short_gep = OpAccessChain %ptr_ssbo_short %short_var %int_0 %int_0
  1596. %ld_short = OpLoad %short %short_gep
  1597. %half2_gep = OpAccessChain %ptr_ssbo_half2 %half_var %int_0
  1598. %ld_half2 = OpLoad %half2 %half2_gep
  1599. %half_gep = OpAccessChain %ptr_ssbo_half %half_var %int_0 %int_0
  1600. %ld_half = OpLoad %half %half_gep
  1601. %int2_gep = OpAccessChain %ptr_ssbo_int2 %int_var %int_0
  1602. %ld_int2 = OpLoad %int2 %int2_gep
  1603. %int_gep = OpAccessChain %ptr_ssbo_int %int_var %int_0 %int_0
  1604. %ld_int = OpLoad %int %int_gep
  1605. %float2_gep = OpAccessChain %ptr_ssbo_float2 %float_var %int_0
  1606. %ld_float2 = OpLoad %float2 %float2_gep
  1607. %float_gep = OpAccessChain %ptr_ssbo_float %float_var %int_0 %int_0
  1608. %ld_float = OpLoad %float %float_gep
  1609. )";
  1610. generator.add_at_the_end_ = R"(
  1611. OpReturn
  1612. OpFunctionEnd
  1613. )";
  1614. return generator;
  1615. }
  1616. TEST_P(ValidateSmallConversions, Instruction) {
  1617. CodeGenerator generator = GetSmallConversionsCodeGenerator();
  1618. generator.after_types_ += GetParam() + "\n";
  1619. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  1620. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1621. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1622. EXPECT_THAT(
  1623. getDiagnosticString(),
  1624. HasSubstr(
  1625. "8- or 16-bit types can only be used with width-only conversions"));
  1626. }
  1627. INSTANTIATE_TEST_SUITE_P(SmallConversionInstructions, ValidateSmallConversions,
  1628. Values("%inst = OpConvertFToU %char %ld_float",
  1629. "%inst = OpConvertFToU %char2 %ld_float2",
  1630. "%inst = OpConvertFToU %short %ld_float",
  1631. "%inst = OpConvertFToU %short2 %ld_float2",
  1632. "%inst = OpConvertFToU %int %ld_half",
  1633. "%inst = OpConvertFToU %int2 %ld_half2",
  1634. "%inst = OpConvertFToS %char %ld_float",
  1635. "%inst = OpConvertFToS %char2 %ld_float2",
  1636. "%inst = OpConvertFToS %short %ld_float",
  1637. "%inst = OpConvertFToS %short2 %ld_float2",
  1638. "%inst = OpConvertFToS %int %ld_half",
  1639. "%inst = OpConvertFToS %int2 %ld_half2",
  1640. "%inst = OpConvertSToF %float %ld_char",
  1641. "%inst = OpConvertSToF %float2 %ld_char2",
  1642. "%inst = OpConvertSToF %float %ld_short",
  1643. "%inst = OpConvertSToF %float2 %ld_short2",
  1644. "%inst = OpConvertSToF %half %ld_int",
  1645. "%inst = OpConvertSToF %half2 %ld_int2",
  1646. "%inst = OpConvertUToF %float %ld_char",
  1647. "%inst = OpConvertUToF %float2 %ld_char2",
  1648. "%inst = OpConvertUToF %float %ld_short",
  1649. "%inst = OpConvertUToF %float2 %ld_short2",
  1650. "%inst = OpConvertUToF %half %ld_int",
  1651. "%inst = OpConvertUToF %half2 %ld_int2",
  1652. "%inst = OpBitcast %half %ld_short",
  1653. "%inst = OpBitcast %half2 %ld_short2",
  1654. "%inst = OpBitcast %short %ld_half",
  1655. "%inst = OpBitcast %short2 %ld_half2"));
  1656. } // namespace
  1657. } // namespace val
  1658. } // namespace spvtools