val_conversion_test.cpp 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458
  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 = R"(
  969. OpCapability Shader
  970. OpCapability Float16
  971. OpCapability Int16
  972. OpCapability CooperativeMatrixNV
  973. OpExtension "SPV_NV_cooperative_matrix"
  974. OpMemoryModel Logical GLSL450
  975. OpEntryPoint GLCompute %main "main"
  976. %void = OpTypeVoid
  977. %func = OpTypeFunction %void
  978. %bool = OpTypeBool
  979. %f16 = OpTypeFloat 16
  980. %f32 = OpTypeFloat 32
  981. %u16 = OpTypeInt 16 0
  982. %u32 = OpTypeInt 32 0
  983. %s16 = OpTypeInt 16 1
  984. %s32 = OpTypeInt 32 1
  985. %u32_8 = OpConstant %u32 8
  986. %u32_4 = OpSpecConstant %u32 4
  987. %subgroup = OpConstant %u32 3
  988. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  989. %f32mat = OpTypeCooperativeMatrixNV %f32 %subgroup %u32_4 %u32_4
  990. %f16_1 = OpConstant %f16 1
  991. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  992. %main = OpFunction %void None %func
  993. %main_entry = OpLabel
  994. %val15 = OpFConvert %f32mat %f16mat_1
  995. OpReturn
  996. OpFunctionEnd)";
  997. CompileSuccessfully(body.c_str());
  998. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  999. }
  1000. TEST_F(ValidateConversion, CoopMatKHRConversionSuccess) {
  1001. const std::string body = R"(
  1002. OpCapability Shader
  1003. OpCapability Float16
  1004. OpCapability Int16
  1005. OpCapability CooperativeMatrixKHR
  1006. OpExtension "SPV_KHR_cooperative_matrix"
  1007. OpExtension "SPV_KHR_vulkan_memory_model"
  1008. OpMemoryModel Logical GLSL450
  1009. OpEntryPoint GLCompute %main "main"
  1010. %void = OpTypeVoid
  1011. %func = OpTypeFunction %void
  1012. %bool = OpTypeBool
  1013. %f16 = OpTypeFloat 16
  1014. %f32 = OpTypeFloat 32
  1015. %u16 = OpTypeInt 16 0
  1016. %u32 = OpTypeInt 32 0
  1017. %s16 = OpTypeInt 16 1
  1018. %s32 = OpTypeInt 32 1
  1019. %u32_8 = OpConstant %u32 8
  1020. %use_A = OpConstant %u32 0
  1021. %subgroup = OpConstant %u32 3
  1022. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  1023. %f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A
  1024. %u16mat = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_A
  1025. %u32mat = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_A
  1026. %s16mat = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_A
  1027. %s32mat = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_A
  1028. %f16_1 = OpConstant %f16 1
  1029. %f32_1 = OpConstant %f32 1
  1030. %u16_1 = OpConstant %u16 1
  1031. %u32_1 = OpConstant %u32 1
  1032. %s16_1 = OpConstant %s16 1
  1033. %s32_1 = OpConstant %s32 1
  1034. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  1035. %f32mat_1 = OpConstantComposite %f32mat %f32_1
  1036. %u16mat_1 = OpConstantComposite %u16mat %u16_1
  1037. %u32mat_1 = OpConstantComposite %u32mat %u32_1
  1038. %s16mat_1 = OpConstantComposite %s16mat %s16_1
  1039. %s32mat_1 = OpConstantComposite %s32mat %s32_1
  1040. %main = OpFunction %void None %func
  1041. %main_entry = OpLabel
  1042. %val11 = OpConvertFToU %u16mat %f16mat_1
  1043. %val12 = OpConvertFToU %u32mat %f16mat_1
  1044. %val13 = OpConvertFToS %s16mat %f16mat_1
  1045. %val14 = OpConvertFToS %s32mat %f16mat_1
  1046. %val15 = OpFConvert %f32mat %f16mat_1
  1047. %val21 = OpConvertFToU %u16mat %f32mat_1
  1048. %val22 = OpConvertFToU %u32mat %f32mat_1
  1049. %val23 = OpConvertFToS %s16mat %f32mat_1
  1050. %val24 = OpConvertFToS %s32mat %f32mat_1
  1051. %val25 = OpFConvert %f16mat %f32mat_1
  1052. %val31 = OpConvertUToF %f16mat %u16mat_1
  1053. %val32 = OpConvertUToF %f32mat %u16mat_1
  1054. %val33 = OpUConvert %u32mat %u16mat_1
  1055. %val34 = OpSConvert %s32mat %u16mat_1
  1056. %val41 = OpConvertSToF %f16mat %s16mat_1
  1057. %val42 = OpConvertSToF %f32mat %s16mat_1
  1058. %val43 = OpUConvert %u32mat %s16mat_1
  1059. %val44 = OpSConvert %s32mat %s16mat_1
  1060. OpReturn
  1061. OpFunctionEnd)";
  1062. CompileSuccessfully(body.c_str());
  1063. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1064. }
  1065. TEST_F(ValidateConversion, CoopMatKHRConversionUseMismatchFail) {
  1066. const std::string body = R"(
  1067. OpCapability Shader
  1068. OpCapability Float16
  1069. OpCapability Int16
  1070. OpCapability CooperativeMatrixKHR
  1071. OpExtension "SPV_KHR_cooperative_matrix"
  1072. OpExtension "SPV_KHR_vulkan_memory_model"
  1073. OpMemoryModel Logical GLSL450
  1074. OpEntryPoint GLCompute %main "main"
  1075. %void = OpTypeVoid
  1076. %func = OpTypeFunction %void
  1077. %bool = OpTypeBool
  1078. %f16 = OpTypeFloat 16
  1079. %f32 = OpTypeFloat 32
  1080. %u16 = OpTypeInt 16 0
  1081. %u32 = OpTypeInt 32 0
  1082. %s16 = OpTypeInt 16 1
  1083. %s32 = OpTypeInt 32 1
  1084. %u32_8 = OpConstant %u32 8
  1085. %u32_4 = OpConstant %u32 4
  1086. %subgroup = OpConstant %u32 3
  1087. %use_A = OpConstant %u32 0
  1088. %use_B = OpConstant %u32 1
  1089. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  1090. %f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_B
  1091. %f16_1 = OpConstant %f16 1
  1092. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  1093. %main = OpFunction %void None %func
  1094. %main_entry = OpLabel
  1095. %val1 = OpFConvert %f32mat %f16mat_1
  1096. OpReturn
  1097. OpFunctionEnd)";
  1098. CompileSuccessfully(body.c_str());
  1099. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1100. EXPECT_THAT(
  1101. getDiagnosticString(),
  1102. HasSubstr("Expected Use of Matrix type and Result Type to be identical"));
  1103. }
  1104. TEST_F(ValidateConversion, CoopMatKHRConversionScopeMismatchFail) {
  1105. const std::string body = R"(
  1106. OpCapability Shader
  1107. OpCapability Float16
  1108. OpCapability Int16
  1109. OpCapability CooperativeMatrixKHR
  1110. OpExtension "SPV_KHR_cooperative_matrix"
  1111. OpExtension "SPV_KHR_vulkan_memory_model"
  1112. OpMemoryModel Logical GLSL450
  1113. OpEntryPoint GLCompute %main "main"
  1114. %void = OpTypeVoid
  1115. %func = OpTypeFunction %void
  1116. %bool = OpTypeBool
  1117. %f16 = OpTypeFloat 16
  1118. %f32 = OpTypeFloat 32
  1119. %u16 = OpTypeInt 16 0
  1120. %u32 = OpTypeInt 32 0
  1121. %s16 = OpTypeInt 16 1
  1122. %s32 = OpTypeInt 32 1
  1123. %u32_8 = OpConstant %u32 8
  1124. %u32_4 = OpConstant %u32 4
  1125. %subgroup = OpConstant %u32 3
  1126. %device = OpConstant %u32 1
  1127. %use_A = OpConstant %u32 0
  1128. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  1129. %f32mat = OpTypeCooperativeMatrixKHR %f32 %device %u32_8 %u32_8 %use_A
  1130. %f16_1 = OpConstant %f16 1
  1131. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  1132. %main = OpFunction %void None %func
  1133. %main_entry = OpLabel
  1134. %val1 = OpFConvert %f32mat %f16mat_1
  1135. OpReturn
  1136. OpFunctionEnd)";
  1137. CompileSuccessfully(body.c_str());
  1138. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1139. EXPECT_THAT(
  1140. getDiagnosticString(),
  1141. HasSubstr("Expected scopes of Matrix and Result Type to be identical"));
  1142. }
  1143. TEST_F(ValidateConversion, BitcastSuccess) {
  1144. const std::string body = R"(
  1145. %ptr = OpVariable %f32ptr_func Function
  1146. %val1 = OpBitcast %u32 %ptr
  1147. %val2 = OpBitcast %u64 %ptr
  1148. %val3 = OpBitcast %f32ptr_func %u32_1
  1149. %val4 = OpBitcast %f32ptr_wg %u64_1
  1150. %val5 = OpBitcast %f32 %u32_1
  1151. %val6 = OpBitcast %f32vec2 %u32vec2_12
  1152. %val7 = OpBitcast %f32vec2 %u64_1
  1153. %val8 = OpBitcast %f64 %u32vec2_12
  1154. %val9 = OpBitcast %f32vec4 %f64vec2_12
  1155. )";
  1156. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1157. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1158. }
  1159. TEST_F(ValidateConversion, BitcastSuccessSPV1p5) {
  1160. const std::string body = R"(
  1161. %ptr = OpVariable %f32ptr_func Function
  1162. %val1 = OpBitcast %u32 %ptr
  1163. %val2 = OpBitcast %u64 %ptr
  1164. %val3 = OpBitcast %f32ptr_func %u32_1
  1165. %val4 = OpBitcast %f32ptr_wg %u64_1
  1166. %val5 = OpBitcast %f32 %u32_1
  1167. %val6 = OpBitcast %f32vec2 %u32vec2_12
  1168. %val7 = OpBitcast %f32vec2 %u64_1
  1169. %val8 = OpBitcast %f64 %u32vec2_12
  1170. %val9 = OpBitcast %f32vec4 %f64vec2_12
  1171. %val10 = OpBitcast %u32ptr_func %u32vec2_01
  1172. %val11 = OpBitcast %u32vec2 %ptr
  1173. )";
  1174. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1175. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1176. }
  1177. TEST_F(ValidateConversion, BitcastSuccessPhysicalStorageBufferKHR) {
  1178. const std::string body = R"(
  1179. %ptr = OpVariable %f32ptr_func Function
  1180. %val1 = OpBitcast %u32 %ptr
  1181. %val2 = OpBitcast %u64 %ptr
  1182. %val3 = OpBitcast %f32ptr_func %u32_1
  1183. %val4 = OpBitcast %f32ptr_wg %u64_1
  1184. %val5 = OpBitcast %f32 %u32_1
  1185. %val6 = OpBitcast %f32vec2 %u32vec2_12
  1186. %val7 = OpBitcast %f32vec2 %u64_1
  1187. %val8 = OpBitcast %f64 %u32vec2_12
  1188. %val9 = OpBitcast %f32vec4 %f64vec2_12
  1189. %val10 = OpBitcast %u32ptr_func %u32vec2_01
  1190. %val11 = OpBitcast %u32vec2 %ptr
  1191. )";
  1192. CompileSuccessfully(
  1193. GenerateKernelCode(body,
  1194. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1195. .c_str());
  1196. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1197. }
  1198. TEST_F(ValidateConversion, BitcastInputHasNoType) {
  1199. const std::string body = R"(
  1200. %val = OpBitcast %u32 %f32
  1201. )";
  1202. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1203. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1204. EXPECT_THAT(getDiagnosticString(),
  1205. HasSubstr("Operand '4[%float]' cannot be a "
  1206. "type"));
  1207. }
  1208. TEST_F(ValidateConversion, BitcastWrongResultType) {
  1209. const std::string body = R"(
  1210. %val = OpBitcast %bool %f32_1
  1211. )";
  1212. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1213. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1214. EXPECT_THAT(
  1215. getDiagnosticString(),
  1216. HasSubstr("Expected Result Type to be a pointer or int or float vector "
  1217. "or scalar type: Bitcast"));
  1218. }
  1219. TEST_F(ValidateConversion, BitcastWrongInputType) {
  1220. const std::string body = R"(
  1221. %val = OpBitcast %u32 %true
  1222. )";
  1223. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1224. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1225. EXPECT_THAT(getDiagnosticString(),
  1226. HasSubstr("Expected input to be a pointer or int or float vector "
  1227. "or scalar: Bitcast"));
  1228. }
  1229. TEST_F(ValidateConversion, BitcastPtrWrongInputType) {
  1230. const std::string body = R"(
  1231. %val = OpBitcast %u32ptr_func %f32_1
  1232. )";
  1233. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1234. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1235. EXPECT_THAT(getDiagnosticString(),
  1236. HasSubstr("Expected input to be a pointer or int scalar if "
  1237. "Result Type is pointer: Bitcast"));
  1238. }
  1239. TEST_F(ValidateConversion, BitcastPtrWrongInputTypeSPV1p5) {
  1240. const std::string body = R"(
  1241. %val = OpBitcast %u32ptr_func %f32_1
  1242. )";
  1243. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1244. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1245. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1246. EXPECT_THAT(getDiagnosticString(),
  1247. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1248. "int vector if Result Type is pointer: Bitcast"));
  1249. }
  1250. TEST_F(ValidateConversion, BitcastPtrWrongInputTypePhysicalStorageBufferKHR) {
  1251. const std::string body = R"(
  1252. %val = OpBitcast %u32ptr_func %f32_1
  1253. )";
  1254. CompileSuccessfully(
  1255. GenerateKernelCode(body,
  1256. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1257. .c_str());
  1258. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1259. EXPECT_THAT(getDiagnosticString(),
  1260. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1261. "int vector if Result Type is pointer: Bitcast"));
  1262. }
  1263. TEST_F(ValidateConversion, BitcastPtrWrongInputTypeIntVectorSPV1p5) {
  1264. const std::string body = R"(
  1265. %val = OpBitcast %u32ptr_func %u64vec2_01
  1266. )";
  1267. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1268. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1269. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1270. EXPECT_THAT(getDiagnosticString(),
  1271. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1272. "int vector if Result Type is pointer: Bitcast"));
  1273. }
  1274. TEST_F(ValidateConversion,
  1275. BitcastPtrWrongInputTypeIntVectorPhysicalStorageBufferKHR) {
  1276. const std::string body = R"(
  1277. %val = OpBitcast %u32ptr_func %u64vec2_01
  1278. )";
  1279. CompileSuccessfully(
  1280. GenerateKernelCode(body,
  1281. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1282. .c_str());
  1283. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1284. EXPECT_THAT(getDiagnosticString(),
  1285. HasSubstr("Expected input to be a pointer, int scalar or 32-bit "
  1286. "int vector if Result Type is pointer: Bitcast"));
  1287. }
  1288. TEST_F(ValidateConversion, BitcastPtrWrongResultType) {
  1289. const std::string body = R"(
  1290. %val = OpBitcast %f32 %f32inp
  1291. )";
  1292. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1293. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1294. EXPECT_THAT(getDiagnosticString(),
  1295. HasSubstr("Pointer can only be converted to another pointer or "
  1296. "int scalar: Bitcast"));
  1297. }
  1298. TEST_F(ValidateConversion, BitcastPtrWrongResultTypeSPV1p5) {
  1299. const std::string body = R"(
  1300. %val = OpBitcast %f32 %f32inp
  1301. )";
  1302. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1303. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1304. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1305. EXPECT_THAT(getDiagnosticString(),
  1306. HasSubstr("Pointer can only be converted to another pointer, int "
  1307. "scalar or 32-bit int vector: Bitcast"));
  1308. }
  1309. TEST_F(ValidateConversion, BitcastPtrWrongResultTypePhysicalStorageBufferKHR) {
  1310. const std::string body = R"(
  1311. %val = OpBitcast %f32 %f32inp
  1312. )";
  1313. CompileSuccessfully(
  1314. GenerateKernelCode(body,
  1315. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1316. .c_str());
  1317. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1318. EXPECT_THAT(getDiagnosticString(),
  1319. HasSubstr("Pointer can only be converted to another pointer, int "
  1320. "scalar or 32-bit int vector: Bitcast"));
  1321. }
  1322. TEST_F(ValidateConversion, BitcastPtrWrongResultTypeIntVectorSPV1p5) {
  1323. const std::string body = R"(
  1324. %val = OpBitcast %u64vec2 %f32inp
  1325. )";
  1326. CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5);
  1327. ASSERT_EQ(SPV_ERROR_INVALID_DATA,
  1328. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  1329. EXPECT_THAT(getDiagnosticString(),
  1330. HasSubstr("Pointer can only be converted to another pointer, int "
  1331. "scalar or 32-bit int vector: Bitcast"));
  1332. }
  1333. TEST_F(ValidateConversion,
  1334. BitcastPtrWrongResultTypeIntVectorPhysicalStorageBufferKHR) {
  1335. const std::string body = R"(
  1336. %val = OpBitcast %u64vec2 %f32inp
  1337. )";
  1338. CompileSuccessfully(
  1339. GenerateKernelCode(body,
  1340. "\nOpExtension \"SPV_KHR_physical_storage_buffer\"")
  1341. .c_str());
  1342. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1343. EXPECT_THAT(getDiagnosticString(),
  1344. HasSubstr("Pointer can only be converted to another pointer, int "
  1345. "scalar or 32-bit int vector: Bitcast"));
  1346. }
  1347. TEST_F(ValidateConversion, BitcastDifferentTotalBitWidth) {
  1348. const std::string body = R"(
  1349. %val = OpBitcast %f32 %u64_1
  1350. )";
  1351. CompileSuccessfully(GenerateKernelCode(body).c_str());
  1352. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1353. EXPECT_THAT(
  1354. getDiagnosticString(),
  1355. HasSubstr(
  1356. "Expected input to have the same total bit width as Result Type: "
  1357. "Bitcast"));
  1358. }
  1359. TEST_F(ValidateConversion, ConvertUToPtrInputIsAType) {
  1360. const std::string spirv = R"(
  1361. OpCapability Addresses
  1362. OpCapability Shader
  1363. OpCapability Linkage
  1364. OpMemoryModel Logical GLSL450
  1365. %int = OpTypeInt 32 0
  1366. %ptr_int = OpTypePointer Function %int
  1367. %void = OpTypeVoid
  1368. %voidfn = OpTypeFunction %void
  1369. %func = OpFunction %void None %voidfn
  1370. %entry = OpLabel
  1371. %1 = OpConvertUToPtr %ptr_int %int
  1372. OpReturn
  1373. OpFunctionEnd
  1374. )";
  1375. CompileSuccessfully(spirv);
  1376. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1377. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand '1[%uint]' cannot be a "
  1378. "type"));
  1379. }
  1380. TEST_F(ValidateConversion, ConvertUToPtrPSBSuccess) {
  1381. const std::string body = R"(
  1382. OpCapability PhysicalStorageBufferAddresses
  1383. OpCapability Int64
  1384. OpCapability Shader
  1385. OpExtension "SPV_EXT_physical_storage_buffer"
  1386. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1387. OpEntryPoint Fragment %main "main"
  1388. OpExecutionMode %main OriginUpperLeft
  1389. %uint64 = OpTypeInt 64 0
  1390. %u64_1 = OpConstant %uint64 1
  1391. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1392. %void = OpTypeVoid
  1393. %voidfn = OpTypeFunction %void
  1394. %main = OpFunction %void None %voidfn
  1395. %entry = OpLabel
  1396. %val1 = OpConvertUToPtr %ptr %u64_1
  1397. OpReturn
  1398. OpFunctionEnd
  1399. )";
  1400. CompileSuccessfully(body.c_str());
  1401. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1402. }
  1403. TEST_F(ValidateConversion, ConvertUToPtrPSBStorageClass) {
  1404. const std::string body = R"(
  1405. OpCapability PhysicalStorageBufferAddresses
  1406. OpCapability Int64
  1407. OpCapability Shader
  1408. OpExtension "SPV_EXT_physical_storage_buffer"
  1409. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1410. OpEntryPoint Fragment %main "main"
  1411. OpExecutionMode %main OriginUpperLeft
  1412. %uint64 = OpTypeInt 64 0
  1413. %u64_1 = OpConstant %uint64 1
  1414. %ptr = OpTypePointer Function %uint64
  1415. %void = OpTypeVoid
  1416. %voidfn = OpTypeFunction %void
  1417. %main = OpFunction %void None %voidfn
  1418. %entry = OpLabel
  1419. %val1 = OpConvertUToPtr %ptr %u64_1
  1420. %val2 = OpConvertPtrToU %uint64 %val1
  1421. OpReturn
  1422. OpFunctionEnd
  1423. )";
  1424. CompileSuccessfully(body.c_str());
  1425. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1426. EXPECT_THAT(getDiagnosticString(),
  1427. HasSubstr("Pointer storage class must be "
  1428. "PhysicalStorageBuffer: ConvertUToPtr"));
  1429. }
  1430. TEST_F(ValidateConversion, ConvertUToPtrVulkanWrongWidth) {
  1431. const std::string body = R"(
  1432. OpCapability PhysicalStorageBufferAddresses
  1433. OpCapability Int64
  1434. OpCapability Shader
  1435. OpExtension "SPV_EXT_physical_storage_buffer"
  1436. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1437. OpEntryPoint Fragment %main "main"
  1438. OpExecutionMode %main OriginUpperLeft
  1439. %uint32 = OpTypeInt 32 0
  1440. %uint64 = OpTypeInt 64 0
  1441. %u32_1 = OpConstant %uint32 1
  1442. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1443. %void = OpTypeVoid
  1444. %voidfn = OpTypeFunction %void
  1445. %main = OpFunction %void None %voidfn
  1446. %entry = OpLabel
  1447. %val1 = OpConvertUToPtr %ptr %u32_1
  1448. OpReturn
  1449. OpFunctionEnd
  1450. )";
  1451. CompileSuccessfully(body.c_str());
  1452. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1453. EXPECT_THAT(getDiagnosticString(),
  1454. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710"));
  1455. EXPECT_THAT(
  1456. getDiagnosticString(),
  1457. HasSubstr("PhysicalStorageBuffer64 addressing mode requires the input "
  1458. "integer to have a 64-bit width for Vulkan environment."));
  1459. }
  1460. TEST_F(ValidateConversion, ConvertPtrToUPSBSuccess) {
  1461. const std::string body = R"(
  1462. OpCapability PhysicalStorageBufferAddresses
  1463. OpCapability Int64
  1464. OpCapability Shader
  1465. OpExtension "SPV_EXT_physical_storage_buffer"
  1466. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1467. OpEntryPoint Fragment %main "main"
  1468. OpExecutionMode %main OriginUpperLeft
  1469. OpDecorate %val1 RestrictPointer
  1470. %uint64 = OpTypeInt 64 0
  1471. %u64_1 = OpConstant %uint64 1
  1472. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1473. %pptr_f = OpTypePointer Function %ptr
  1474. %void = OpTypeVoid
  1475. %voidfn = OpTypeFunction %void
  1476. %main = OpFunction %void None %voidfn
  1477. %entry = OpLabel
  1478. %val1 = OpVariable %pptr_f Function
  1479. %val2 = OpLoad %ptr %val1
  1480. %val3 = OpConvertPtrToU %uint64 %val2
  1481. OpReturn
  1482. OpFunctionEnd
  1483. )";
  1484. CompileSuccessfully(body.c_str());
  1485. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1486. }
  1487. TEST_F(ValidateConversion, ConvertPtrToUPSBStorageClass) {
  1488. const std::string body = R"(
  1489. OpCapability PhysicalStorageBufferAddresses
  1490. OpCapability Int64
  1491. OpCapability Shader
  1492. OpExtension "SPV_EXT_physical_storage_buffer"
  1493. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1494. OpEntryPoint Fragment %main "main"
  1495. OpExecutionMode %main OriginUpperLeft
  1496. %uint64 = OpTypeInt 64 0
  1497. %u64_1 = OpConstant %uint64 1
  1498. %ptr = OpTypePointer Function %uint64
  1499. %void = OpTypeVoid
  1500. %voidfn = OpTypeFunction %void
  1501. %main = OpFunction %void None %voidfn
  1502. %entry = OpLabel
  1503. %val1 = OpVariable %ptr Function
  1504. %val2 = OpConvertPtrToU %uint64 %val1
  1505. OpReturn
  1506. OpFunctionEnd
  1507. )";
  1508. CompileSuccessfully(body.c_str());
  1509. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1510. EXPECT_THAT(getDiagnosticString(),
  1511. HasSubstr("Pointer storage class must be "
  1512. "PhysicalStorageBuffer: ConvertPtrToU"));
  1513. }
  1514. TEST_F(ValidateConversion, ConvertPtrToUVulkanWrongWidth) {
  1515. const std::string body = R"(
  1516. OpCapability PhysicalStorageBufferAddresses
  1517. OpCapability Int64
  1518. OpCapability Shader
  1519. OpExtension "SPV_EXT_physical_storage_buffer"
  1520. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1521. OpEntryPoint Fragment %main "main"
  1522. OpExecutionMode %main OriginUpperLeft
  1523. OpDecorate %val1 RestrictPointer
  1524. %uint32 = OpTypeInt 32 0
  1525. %uint64 = OpTypeInt 64 0
  1526. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1527. %pptr_f = OpTypePointer Function %ptr
  1528. %void = OpTypeVoid
  1529. %voidfn = OpTypeFunction %void
  1530. %main = OpFunction %void None %voidfn
  1531. %entry = OpLabel
  1532. %val1 = OpVariable %pptr_f Function
  1533. %val2 = OpLoad %ptr %val1
  1534. %val3 = OpConvertPtrToU %uint32 %val2
  1535. OpReturn
  1536. OpFunctionEnd
  1537. )";
  1538. CompileSuccessfully(body.c_str());
  1539. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1540. EXPECT_THAT(getDiagnosticString(),
  1541. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710"));
  1542. EXPECT_THAT(
  1543. getDiagnosticString(),
  1544. HasSubstr("PhysicalStorageBuffer64 addressing mode requires the result "
  1545. "integer type to have a 64-bit width for Vulkan environment."));
  1546. }
  1547. TEST_F(ValidateConversion, ConvertUToAccelerationStructureU32Vec2) {
  1548. const std::string extensions = R"(
  1549. OpCapability RayQueryKHR
  1550. OpExtension "SPV_KHR_ray_query"
  1551. )";
  1552. const std::string types = R"(
  1553. %u32vec2ptr_func = OpTypePointer Function %u32vec2
  1554. %typeAS = OpTypeAccelerationStructureKHR
  1555. )";
  1556. const std::string body = R"(
  1557. %asHandle = OpVariable %u32vec2ptr_func Function
  1558. %load = OpLoad %u32vec2 %asHandle
  1559. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1560. )";
  1561. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1562. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1563. }
  1564. TEST_F(ValidateConversion, ConvertUToAccelerationStructureSuccessU64) {
  1565. const std::string extensions = R"(
  1566. OpCapability RayQueryKHR
  1567. OpExtension "SPV_KHR_ray_query"
  1568. )";
  1569. const std::string types = R"(
  1570. %u64_func = OpTypePointer Function %u64
  1571. %typeAS = OpTypeAccelerationStructureKHR
  1572. )";
  1573. const std::string body = R"(
  1574. %asHandle = OpVariable %u64_func Function
  1575. %load = OpLoad %u64 %asHandle
  1576. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1577. )";
  1578. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1579. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1580. }
  1581. TEST_F(ValidateConversion, ConvertUToAccelerationStructureResult) {
  1582. const std::string extensions = R"(
  1583. OpCapability RayQueryKHR
  1584. OpExtension "SPV_KHR_ray_query"
  1585. )";
  1586. const std::string types = R"(
  1587. %u32vec2ptr_func = OpTypePointer Function %u32vec2
  1588. %typeRQ = OpTypeRayQueryKHR
  1589. )";
  1590. const std::string body = R"(
  1591. %asHandle = OpVariable %u32vec2ptr_func Function
  1592. %load = OpLoad %u32vec2 %asHandle
  1593. %val = OpConvertUToAccelerationStructureKHR %typeRQ %load
  1594. )";
  1595. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1596. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1597. EXPECT_THAT(getDiagnosticString(),
  1598. HasSubstr("Expected Result Type to be a Acceleration Structure"));
  1599. }
  1600. TEST_F(ValidateConversion, ConvertUToAccelerationStructureU32) {
  1601. const std::string extensions = R"(
  1602. OpCapability RayQueryKHR
  1603. OpExtension "SPV_KHR_ray_query"
  1604. )";
  1605. const std::string types = R"(
  1606. %u32ptr_func = OpTypePointer Function %u32
  1607. %typeAS = OpTypeAccelerationStructureKHR
  1608. )";
  1609. const std::string body = R"(
  1610. %asHandle = OpVariable %u32ptr_func Function
  1611. %load = OpLoad %u32 %asHandle
  1612. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1613. )";
  1614. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1615. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1616. EXPECT_THAT(getDiagnosticString(),
  1617. HasSubstr("Expected 64-bit uint scalar or 2-component 32-bit "
  1618. "uint vector as input"));
  1619. }
  1620. TEST_F(ValidateConversion, ConvertUToAccelerationStructureS64) {
  1621. const std::string extensions = R"(
  1622. OpCapability RayQueryKHR
  1623. OpExtension "SPV_KHR_ray_query"
  1624. )";
  1625. const std::string types = R"(
  1626. %s64ptr_func = OpTypePointer Function %s64
  1627. %typeAS = OpTypeAccelerationStructureKHR
  1628. )";
  1629. const std::string body = R"(
  1630. %asHandle = OpVariable %s64ptr_func Function
  1631. %load = OpLoad %s64 %asHandle
  1632. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1633. )";
  1634. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1635. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1636. EXPECT_THAT(getDiagnosticString(),
  1637. HasSubstr("Expected 64-bit uint scalar or 2-component 32-bit "
  1638. "uint vector as input"));
  1639. }
  1640. TEST_F(ValidateConversion, ConvertUToAccelerationStructureS32Vec2) {
  1641. const std::string extensions = R"(
  1642. OpCapability RayQueryKHR
  1643. OpExtension "SPV_KHR_ray_query"
  1644. )";
  1645. const std::string types = R"(
  1646. %s32vec2ptr_func = OpTypePointer Function %s32vec2
  1647. %typeAS = OpTypeAccelerationStructureKHR
  1648. )";
  1649. const std::string body = R"(
  1650. %asHandle = OpVariable %s32vec2ptr_func Function
  1651. %load = OpLoad %s32vec2 %asHandle
  1652. %val = OpConvertUToAccelerationStructureKHR %typeAS %load
  1653. )";
  1654. CompileSuccessfully(GenerateShaderCode(body, extensions, "", types).c_str());
  1655. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1656. EXPECT_THAT(getDiagnosticString(),
  1657. HasSubstr("Expected 64-bit uint scalar or 2-component 32-bit "
  1658. "uint vector as input"));
  1659. }
  1660. TEST_F(ValidateConversion, BitcastUntypedPointerInput) {
  1661. const std::string spirv = R"(
  1662. OpCapability Shader
  1663. OpCapability VariablePointers
  1664. OpCapability UntypedPointersKHR
  1665. OpCapability WorkgroupMemoryExplicitLayoutKHR
  1666. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  1667. OpExtension "SPV_KHR_variable_pointers"
  1668. OpExtension "SPV_KHR_untyped_pointers"
  1669. OpMemoryModel Logical GLSL450
  1670. OpEntryPoint GLCompute %main "main" %var
  1671. OpDecorate %struct Block
  1672. OpMemberDecorate %struct 0 Offset 0
  1673. %void = OpTypeVoid
  1674. %int = OpTypeInt 32 0
  1675. %struct = OpTypeStruct %int
  1676. %ptr = OpTypeUntypedPointerKHR Workgroup
  1677. %var = OpUntypedVariableKHR %ptr Workgroup %struct
  1678. %void_fn = OpTypeFunction %void
  1679. %main = OpFunction %void None %void_fn
  1680. %entry = OpLabel
  1681. %cast = OpBitcast %int %var
  1682. OpReturn
  1683. OpFunctionEnd
  1684. )";
  1685. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1686. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1687. }
  1688. TEST_F(ValidateConversion, BitcastUntypedPointerOutput) {
  1689. const std::string spirv = R"(
  1690. OpCapability Shader
  1691. OpCapability VariablePointers
  1692. OpCapability UntypedPointersKHR
  1693. OpCapability WorkgroupMemoryExplicitLayoutKHR
  1694. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  1695. OpExtension "SPV_KHR_variable_pointers"
  1696. OpExtension "SPV_KHR_untyped_pointers"
  1697. OpMemoryModel Logical GLSL450
  1698. OpEntryPoint GLCompute %main "main"
  1699. %void = OpTypeVoid
  1700. %int = OpTypeInt 32 0
  1701. %int_0 = OpConstant %int 0
  1702. %ptr = OpTypeUntypedPointerKHR Workgroup
  1703. %var = OpUntypedVariableKHR %ptr Workgroup %int
  1704. %void_fn = OpTypeFunction %void
  1705. %main = OpFunction %void None %void_fn
  1706. %entry = OpLabel
  1707. %cast = OpBitcast %ptr %int_0
  1708. OpReturn
  1709. OpFunctionEnd
  1710. )";
  1711. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1712. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1713. }
  1714. using ValidateSmallConversions = spvtest::ValidateBase<std::string>;
  1715. CodeGenerator GetSmallConversionsCodeGenerator() {
  1716. CodeGenerator generator;
  1717. generator.capabilities_ = R"(
  1718. OpCapability Shader
  1719. OpCapability Linkage
  1720. OpCapability UniformAndStorageBuffer16BitAccess
  1721. OpCapability UniformAndStorageBuffer8BitAccess
  1722. )";
  1723. generator.extensions_ = R"(
  1724. OpExtension "SPV_KHR_16bit_storage"
  1725. OpExtension "SPV_KHR_8bit_storage"
  1726. )";
  1727. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  1728. generator.before_types_ = R"(
  1729. OpDecorate %char_block Block
  1730. OpMemberDecorate %char_block 0 Offset 0
  1731. OpDecorate %short_block Block
  1732. OpMemberDecorate %short_block 0 Offset 0
  1733. OpDecorate %half_block Block
  1734. OpMemberDecorate %half_block 0 Offset 0
  1735. OpDecorate %int_block Block
  1736. OpMemberDecorate %int_block 0 Offset 0
  1737. OpDecorate %float_block Block
  1738. OpMemberDecorate %float_block 0 Offset 0
  1739. )";
  1740. generator.types_ = R"(
  1741. %void = OpTypeVoid
  1742. %int = OpTypeInt 32 0
  1743. %int_0 = OpConstant %int 0
  1744. %int_1 = OpConstant %int 1
  1745. %int2 = OpTypeVector %int 2
  1746. %float = OpTypeFloat 32
  1747. %float_0 = OpConstant %float 0
  1748. %float2 = OpTypeVector %float 2
  1749. %char = OpTypeInt 8 0
  1750. %char2 = OpTypeVector %char 2
  1751. %short = OpTypeInt 16 0
  1752. %short2 = OpTypeVector %short 2
  1753. %half = OpTypeFloat 16
  1754. %half2 = OpTypeVector %half 2
  1755. %char_block = OpTypeStruct %char2
  1756. %short_block = OpTypeStruct %short2
  1757. %half_block = OpTypeStruct %half2
  1758. %int_block = OpTypeStruct %int2
  1759. %float_block = OpTypeStruct %float2
  1760. %ptr_ssbo_char_block = OpTypePointer StorageBuffer %char_block
  1761. %ptr_ssbo_char2 = OpTypePointer StorageBuffer %char2
  1762. %ptr_ssbo_char = OpTypePointer StorageBuffer %char
  1763. %ptr_ssbo_short_block = OpTypePointer StorageBuffer %short_block
  1764. %ptr_ssbo_short2 = OpTypePointer StorageBuffer %short2
  1765. %ptr_ssbo_short = OpTypePointer StorageBuffer %short
  1766. %ptr_ssbo_half_block = OpTypePointer StorageBuffer %half_block
  1767. %ptr_ssbo_half2 = OpTypePointer StorageBuffer %half2
  1768. %ptr_ssbo_half = OpTypePointer StorageBuffer %half
  1769. %ptr_ssbo_int_block = OpTypePointer StorageBuffer %int_block
  1770. %ptr_ssbo_int2 = OpTypePointer StorageBuffer %int2
  1771. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1772. %ptr_ssbo_float_block = OpTypePointer StorageBuffer %float_block
  1773. %ptr_ssbo_float2 = OpTypePointer StorageBuffer %float2
  1774. %ptr_ssbo_float = OpTypePointer StorageBuffer %float
  1775. %void_fn = OpTypeFunction %void
  1776. %char_var = OpVariable %ptr_ssbo_char_block StorageBuffer
  1777. %short_var = OpVariable %ptr_ssbo_short_block StorageBuffer
  1778. %half_var = OpVariable %ptr_ssbo_half_block StorageBuffer
  1779. %int_var = OpVariable %ptr_ssbo_int_block StorageBuffer
  1780. %float_var = OpVariable %ptr_ssbo_float_block StorageBuffer
  1781. )";
  1782. generator.after_types_ = R"(
  1783. %func = OpFunction %void None %void_fn
  1784. %entry = OpLabel
  1785. %char2_gep = OpAccessChain %ptr_ssbo_char2 %char_var %int_0
  1786. %ld_char2 = OpLoad %char2 %char2_gep
  1787. %char_gep = OpAccessChain %ptr_ssbo_char %char_var %int_0 %int_0
  1788. %ld_char = OpLoad %char %char_gep
  1789. %short2_gep = OpAccessChain %ptr_ssbo_short2 %short_var %int_0
  1790. %ld_short2 = OpLoad %short2 %short2_gep
  1791. %short_gep = OpAccessChain %ptr_ssbo_short %short_var %int_0 %int_0
  1792. %ld_short = OpLoad %short %short_gep
  1793. %half2_gep = OpAccessChain %ptr_ssbo_half2 %half_var %int_0
  1794. %ld_half2 = OpLoad %half2 %half2_gep
  1795. %half_gep = OpAccessChain %ptr_ssbo_half %half_var %int_0 %int_0
  1796. %ld_half = OpLoad %half %half_gep
  1797. %int2_gep = OpAccessChain %ptr_ssbo_int2 %int_var %int_0
  1798. %ld_int2 = OpLoad %int2 %int2_gep
  1799. %int_gep = OpAccessChain %ptr_ssbo_int %int_var %int_0 %int_0
  1800. %ld_int = OpLoad %int %int_gep
  1801. %float2_gep = OpAccessChain %ptr_ssbo_float2 %float_var %int_0
  1802. %ld_float2 = OpLoad %float2 %float2_gep
  1803. %float_gep = OpAccessChain %ptr_ssbo_float %float_var %int_0 %int_0
  1804. %ld_float = OpLoad %float %float_gep
  1805. )";
  1806. generator.add_at_the_end_ = R"(
  1807. OpReturn
  1808. OpFunctionEnd
  1809. )";
  1810. return generator;
  1811. }
  1812. TEST_P(ValidateSmallConversions, Instruction) {
  1813. CodeGenerator generator = GetSmallConversionsCodeGenerator();
  1814. generator.after_types_ += GetParam() + "\n";
  1815. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  1816. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1817. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1818. EXPECT_THAT(
  1819. getDiagnosticString(),
  1820. HasSubstr(
  1821. "8- or 16-bit types can only be used with width-only conversions"));
  1822. }
  1823. INSTANTIATE_TEST_SUITE_P(SmallConversionInstructions, ValidateSmallConversions,
  1824. Values("%inst = OpConvertFToU %char %ld_float",
  1825. "%inst = OpConvertFToU %char2 %ld_float2",
  1826. "%inst = OpConvertFToU %short %ld_float",
  1827. "%inst = OpConvertFToU %short2 %ld_float2",
  1828. "%inst = OpConvertFToU %int %ld_half",
  1829. "%inst = OpConvertFToU %int2 %ld_half2",
  1830. "%inst = OpConvertFToS %char %ld_float",
  1831. "%inst = OpConvertFToS %char2 %ld_float2",
  1832. "%inst = OpConvertFToS %short %ld_float",
  1833. "%inst = OpConvertFToS %short2 %ld_float2",
  1834. "%inst = OpConvertFToS %int %ld_half",
  1835. "%inst = OpConvertFToS %int2 %ld_half2",
  1836. "%inst = OpConvertSToF %float %ld_char",
  1837. "%inst = OpConvertSToF %float2 %ld_char2",
  1838. "%inst = OpConvertSToF %float %ld_short",
  1839. "%inst = OpConvertSToF %float2 %ld_short2",
  1840. "%inst = OpConvertSToF %half %ld_int",
  1841. "%inst = OpConvertSToF %half2 %ld_int2",
  1842. "%inst = OpConvertUToF %float %ld_char",
  1843. "%inst = OpConvertUToF %float2 %ld_char2",
  1844. "%inst = OpConvertUToF %float %ld_short",
  1845. "%inst = OpConvertUToF %float2 %ld_short2",
  1846. "%inst = OpConvertUToF %half %ld_int",
  1847. "%inst = OpConvertUToF %half2 %ld_int2",
  1848. "%inst = OpBitcast %half %ld_short",
  1849. "%inst = OpBitcast %half2 %ld_short2",
  1850. "%inst = OpBitcast %short %ld_half",
  1851. "%inst = OpBitcast %short2 %ld_half2"));
  1852. TEST_F(ValidateConversion, CoopMat2ConversionSuccess) {
  1853. const std::string body = R"(
  1854. OpCapability Shader
  1855. OpCapability Float16
  1856. OpCapability Int16
  1857. OpCapability CooperativeMatrixConversionsNV
  1858. OpCapability CooperativeMatrixKHR
  1859. OpExtension "SPV_KHR_cooperative_matrix"
  1860. OpExtension "SPV_NV_cooperative_matrix2"
  1861. OpExtension "SPV_KHR_vulkan_memory_model"
  1862. OpMemoryModel Logical GLSL450
  1863. OpEntryPoint GLCompute %main "main"
  1864. %void = OpTypeVoid
  1865. %func = OpTypeFunction %void
  1866. %bool = OpTypeBool
  1867. %f16 = OpTypeFloat 16
  1868. %f32 = OpTypeFloat 32
  1869. %u16 = OpTypeInt 16 0
  1870. %u32 = OpTypeInt 32 0
  1871. %s16 = OpTypeInt 16 1
  1872. %s32 = OpTypeInt 32 1
  1873. %u32_8 = OpConstant %u32 8
  1874. %u32_16 = OpConstant %u32 16
  1875. %use_A = OpConstant %u32 0
  1876. %use_B = OpConstant %u32 1
  1877. %use_Acc = OpConstant %u32 2
  1878. %subgroup = OpConstant %u32 3
  1879. %f16matA = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  1880. %f32matA = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A
  1881. %u16matA = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_A
  1882. %u32matA = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_A
  1883. %s16matA = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_A
  1884. %s32matA = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_A
  1885. %f16matB = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_B
  1886. %f32matB = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_B
  1887. %u16matB = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_B
  1888. %u32matB = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_B
  1889. %s16matB = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_B
  1890. %s32matB = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_B
  1891. %f16matAcc = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_Acc
  1892. %f32matAcc = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_Acc
  1893. %u16matAcc = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_Acc
  1894. %u32matAcc = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_Acc
  1895. %s16matAcc = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_Acc
  1896. %s32matAcc = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_Acc
  1897. %f16matAcc16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %use_Acc
  1898. %f16matB8x16 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_16 %use_B
  1899. %f16_1 = OpConstant %f16 1
  1900. %f32_1 = OpConstant %f32 1
  1901. %u16_1 = OpConstant %u16 1
  1902. %u32_1 = OpConstant %u32 1
  1903. %s16_1 = OpConstant %s16 1
  1904. %s32_1 = OpConstant %s32 1
  1905. %f16matAcc_1 = OpConstantComposite %f16matAcc %f16_1
  1906. %f32matAcc_1 = OpConstantComposite %f32matAcc %f32_1
  1907. %u16matAcc_1 = OpConstantComposite %u16matAcc %u16_1
  1908. %u32matAcc_1 = OpConstantComposite %u32matAcc %u32_1
  1909. %s16matAcc_1 = OpConstantComposite %s16matAcc %s16_1
  1910. %s32matAcc_1 = OpConstantComposite %s32matAcc %s32_1
  1911. %f16matAcc16x8_1 = OpConstantComposite %f16matAcc16x8 %f16_1
  1912. %main = OpFunction %void None %func
  1913. %main_entry = OpLabel
  1914. %val11A = OpConvertFToU %u16matA %f16matAcc_1
  1915. %val12A = OpConvertFToU %u32matA %f16matAcc_1
  1916. %val13A = OpConvertFToS %s16matA %f16matAcc_1
  1917. %val14A = OpConvertFToS %s32matA %f16matAcc_1
  1918. %val15A = OpFConvert %f32matA %f16matAcc_1
  1919. %val11B = OpConvertFToU %u16matB %f16matAcc_1
  1920. %val12B = OpConvertFToU %u32matB %f16matAcc_1
  1921. %val13B = OpConvertFToS %s16matB %f16matAcc_1
  1922. %val14B = OpConvertFToS %s32matB %f16matAcc_1
  1923. %val15B = OpFConvert %f32matB %f16matAcc_1
  1924. %val21A = OpConvertFToU %u16matA %f32matAcc_1
  1925. %val22A = OpConvertFToU %u32matA %f32matAcc_1
  1926. %val23A = OpConvertFToS %s16matA %f32matAcc_1
  1927. %val24A = OpConvertFToS %s32matA %f32matAcc_1
  1928. %val25A = OpFConvert %f16matA %f32matAcc_1
  1929. %val21B = OpConvertFToU %u16matB %f32matAcc_1
  1930. %val22B = OpConvertFToU %u32matB %f32matAcc_1
  1931. %val23B = OpConvertFToS %s16matB %f32matAcc_1
  1932. %val24B = OpConvertFToS %s32matB %f32matAcc_1
  1933. %val25B = OpFConvert %f16matB %f32matAcc_1
  1934. %val31A = OpConvertUToF %f16matA %u16matAcc_1
  1935. %val32A = OpConvertUToF %f32matA %u16matAcc_1
  1936. %val33A = OpUConvert %u32matA %u16matAcc_1
  1937. %val34A = OpSConvert %s32matA %u16matAcc_1
  1938. %val31B = OpConvertUToF %f16matB %u16matAcc_1
  1939. %val32B = OpConvertUToF %f32matB %u16matAcc_1
  1940. %val33B = OpUConvert %u32matB %u16matAcc_1
  1941. %val34B = OpSConvert %s32matB %u16matAcc_1
  1942. %val41A = OpConvertSToF %f16matA %s16matAcc_1
  1943. %val42A = OpConvertSToF %f32matA %s16matAcc_1
  1944. %val43A = OpUConvert %u32matA %s16matAcc_1
  1945. %val44A = OpSConvert %s32matA %s16matAcc_1
  1946. %val41B = OpConvertSToF %f16matB %s16matAcc_1
  1947. %val42B = OpConvertSToF %f32matB %s16matAcc_1
  1948. %val43B = OpUConvert %u32matB %s16matAcc_1
  1949. %val44B = OpSConvert %s32matB %s16matAcc_1
  1950. %val51A = OpCooperativeMatrixConvertNV %f16matA %f16matAcc_1
  1951. %val52A = OpCooperativeMatrixConvertNV %f32matA %f32matAcc_1
  1952. %val53A = OpCooperativeMatrixConvertNV %u16matA %u16matAcc_1
  1953. %val54A = OpCooperativeMatrixConvertNV %s16matA %s16matAcc_1
  1954. %val51B = OpCooperativeMatrixConvertNV %f16matB %f16matAcc_1
  1955. %val52B = OpCooperativeMatrixConvertNV %f32matB %f32matAcc_1
  1956. %val53B = OpCooperativeMatrixConvertNV %u16matB %u16matAcc_1
  1957. %val54B = OpCooperativeMatrixConvertNV %s16matB %s16matAcc_1
  1958. %val61B = OpCooperativeMatrixTransposeNV %f16matB %f16matAcc_1
  1959. %val62B = OpCooperativeMatrixTransposeNV %f32matB %f32matAcc_1
  1960. %val63B = OpCooperativeMatrixTransposeNV %u16matB %u16matAcc_1
  1961. %val64B = OpCooperativeMatrixTransposeNV %s16matB %s16matAcc_1
  1962. %val71B = OpCooperativeMatrixTransposeNV %f16matB8x16 %f16matAcc16x8_1
  1963. OpReturn
  1964. OpFunctionEnd)";
  1965. CompileSuccessfully(body.c_str());
  1966. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1967. }
  1968. TEST_F(ValidateConversion, CoopMat2TransposeShapeFail) {
  1969. const std::string body = R"(
  1970. OpCapability Shader
  1971. OpCapability Float16
  1972. OpCapability Int16
  1973. OpCapability CooperativeMatrixConversionsNV
  1974. OpCapability CooperativeMatrixKHR
  1975. OpExtension "SPV_KHR_cooperative_matrix"
  1976. OpExtension "SPV_NV_cooperative_matrix2"
  1977. OpExtension "SPV_KHR_vulkan_memory_model"
  1978. OpMemoryModel Logical GLSL450
  1979. OpEntryPoint GLCompute %main "main"
  1980. %void = OpTypeVoid
  1981. %func = OpTypeFunction %void
  1982. %bool = OpTypeBool
  1983. %f16 = OpTypeFloat 16
  1984. %u32 = OpTypeInt 32 0
  1985. %u32_8 = OpConstant %u32 8
  1986. %u32_16 = OpConstant %u32 16
  1987. %use_B = OpConstant %u32 1
  1988. %use_Acc = OpConstant %u32 2
  1989. %subgroup = OpConstant %u32 3
  1990. %f16matAcc16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %use_Acc
  1991. %f16matB16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %use_B
  1992. %f16_1 = OpConstant %f16 1
  1993. %f16matAcc16x8_1 = OpConstantComposite %f16matAcc16x8 %f16_1
  1994. %main = OpFunction %void None %func
  1995. %main_entry = OpLabel
  1996. %val71B = OpCooperativeMatrixTransposeNV %f16matB16x8 %f16matAcc16x8_1
  1997. OpReturn
  1998. OpFunctionEnd)";
  1999. CompileSuccessfully(body.c_str());
  2000. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2001. EXPECT_THAT(getDiagnosticString(),
  2002. HasSubstr("Expected rows of Matrix type and Result Type to be "
  2003. "swapped with columns"));
  2004. }
  2005. TEST_F(ValidateConversion, CoopVecConversionSuccess) {
  2006. const std::string body = R"(
  2007. OpCapability Shader
  2008. OpCapability Float16
  2009. OpCapability Int16
  2010. OpCapability CooperativeVectorNV
  2011. OpCapability ReplicatedCompositesEXT
  2012. OpExtension "SPV_NV_cooperative_vector"
  2013. OpExtension "SPV_EXT_replicated_composites"
  2014. OpExtension "SPV_KHR_vulkan_memory_model"
  2015. OpMemoryModel Logical GLSL450
  2016. OpEntryPoint GLCompute %main "main"
  2017. %void = OpTypeVoid
  2018. %func = OpTypeFunction %void
  2019. %bool = OpTypeBool
  2020. %f16 = OpTypeFloat 16
  2021. %f32 = OpTypeFloat 32
  2022. %u16 = OpTypeInt 16 0
  2023. %u32 = OpTypeInt 32 0
  2024. %s16 = OpTypeInt 16 1
  2025. %s32 = OpTypeInt 32 1
  2026. %u32_8 = OpConstant %u32 8
  2027. %use_A = OpConstant %u32 0
  2028. %subgroup = OpConstant %u32 3
  2029. %f16vec = OpTypeCooperativeVectorNV %f16 %u32_8
  2030. %f32vec = OpTypeCooperativeVectorNV %f32 %u32_8
  2031. %u16vec = OpTypeCooperativeVectorNV %u16 %u32_8
  2032. %u32vec = OpTypeCooperativeVectorNV %u32 %u32_8
  2033. %s16vec = OpTypeCooperativeVectorNV %s16 %u32_8
  2034. %s32vec = OpTypeCooperativeVectorNV %s32 %u32_8
  2035. %f16_1 = OpConstant %f16 1
  2036. %f32_1 = OpConstant %f32 1
  2037. %u16_1 = OpConstant %u16 1
  2038. %u32_1 = OpConstant %u32 1
  2039. %s16_1 = OpConstant %s16 1
  2040. %s32_1 = OpConstant %s32 1
  2041. %f16vec_1 = OpConstantCompositeReplicateEXT %f16vec %f16_1
  2042. %f32vec_1 = OpConstantCompositeReplicateEXT %f32vec %f32_1
  2043. %u16vec_1 = OpConstantCompositeReplicateEXT %u16vec %u16_1
  2044. %u32vec_1 = OpConstantCompositeReplicateEXT %u32vec %u32_1
  2045. %s16vec_1 = OpConstantCompositeReplicateEXT %s16vec %s16_1
  2046. %s32vec_1 = OpConstantCompositeReplicateEXT %s32vec %s32_1
  2047. %main = OpFunction %void None %func
  2048. %main_entry = OpLabel
  2049. %val11 = OpConvertFToU %u16vec %f16vec_1
  2050. %val12 = OpConvertFToU %u32vec %f16vec_1
  2051. %val13 = OpConvertFToS %s16vec %f16vec_1
  2052. %val14 = OpConvertFToS %s32vec %f16vec_1
  2053. %val15 = OpFConvert %f32vec %f16vec_1
  2054. %val21 = OpConvertFToU %u16vec %f32vec_1
  2055. %val22 = OpConvertFToU %u32vec %f32vec_1
  2056. %val23 = OpConvertFToS %s16vec %f32vec_1
  2057. %val24 = OpConvertFToS %s32vec %f32vec_1
  2058. %val25 = OpFConvert %f16vec %f32vec_1
  2059. %val31 = OpConvertUToF %f16vec %u16vec_1
  2060. %val32 = OpConvertUToF %f32vec %u16vec_1
  2061. %val33 = OpUConvert %u32vec %u16vec_1
  2062. %val34 = OpSConvert %s32vec %u16vec_1
  2063. %val41 = OpConvertSToF %f16vec %s16vec_1
  2064. %val42 = OpConvertSToF %f32vec %s16vec_1
  2065. %val43 = OpUConvert %u32vec %s16vec_1
  2066. %val44 = OpSConvert %s32vec %s16vec_1
  2067. OpReturn
  2068. OpFunctionEnd)";
  2069. CompileSuccessfully(body.c_str());
  2070. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2071. }
  2072. TEST_F(ValidateConversion, CoopVecConversionDimMismatchFail) {
  2073. const std::string body = R"(
  2074. OpCapability Shader
  2075. OpCapability Float16
  2076. OpCapability Int16
  2077. OpCapability CooperativeVectorNV
  2078. OpCapability ReplicatedCompositesEXT
  2079. OpExtension "SPV_NV_cooperative_vector"
  2080. OpExtension "SPV_EXT_replicated_composites"
  2081. OpExtension "SPV_KHR_vulkan_memory_model"
  2082. OpMemoryModel Logical GLSL450
  2083. OpEntryPoint GLCompute %main "main"
  2084. %void = OpTypeVoid
  2085. %func = OpTypeFunction %void
  2086. %bool = OpTypeBool
  2087. %f16 = OpTypeFloat 16
  2088. %f32 = OpTypeFloat 32
  2089. %u16 = OpTypeInt 16 0
  2090. %u32 = OpTypeInt 32 0
  2091. %s16 = OpTypeInt 16 1
  2092. %s32 = OpTypeInt 32 1
  2093. %u32_8 = OpConstant %u32 8
  2094. %u32_4 = OpConstant %u32 4
  2095. %subgroup = OpConstant %u32 3
  2096. %use_A = OpConstant %u32 0
  2097. %use_B = OpConstant %u32 1
  2098. %f16vec = OpTypeCooperativeVectorNV %f16 %u32_8
  2099. %f32vec = OpTypeCooperativeVectorNV %f32 %u32_4
  2100. %f16_1 = OpConstant %f16 1
  2101. %f16vec_1 = OpConstantCompositeReplicateEXT %f16vec %f16_1
  2102. %main = OpFunction %void None %func
  2103. %main_entry = OpLabel
  2104. %val1 = OpFConvert %f32vec %f16vec_1
  2105. OpReturn
  2106. OpFunctionEnd)";
  2107. CompileSuccessfully(body.c_str());
  2108. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2109. EXPECT_THAT(getDiagnosticString(),
  2110. HasSubstr("Expected number of components to be identical"));
  2111. }
  2112. } // namespace
  2113. } // namespace val
  2114. } // namespace spvtools