validate_extensions.cpp 123 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160
  1. // Copyright (c) 2018 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. // Validates correctness of extension SPIR-V instructions.
  15. #include <cstdlib>
  16. #include <sstream>
  17. #include <string>
  18. #include <vector>
  19. #include "spirv/unified1/NonSemanticClspvReflection.h"
  20. #include "OpenCLDebugInfo100.h"
  21. #include "source/diagnostic.h"
  22. #include "source/enum_string_mapping.h"
  23. #include "source/extensions.h"
  24. #include "source/latest_version_glsl_std_450_header.h"
  25. #include "source/latest_version_opencl_std_header.h"
  26. #include "source/opcode.h"
  27. #include "source/spirv_constant.h"
  28. #include "source/spirv_target_env.h"
  29. #include "source/val/instruction.h"
  30. #include "source/val/validate.h"
  31. #include "source/val/validation_state.h"
  32. namespace spvtools {
  33. namespace val {
  34. namespace {
  35. uint32_t GetSizeTBitWidth(const ValidationState_t& _) {
  36. if (_.addressing_model() == SpvAddressingModelPhysical32) return 32;
  37. if (_.addressing_model() == SpvAddressingModelPhysical64) return 64;
  38. return 0;
  39. }
  40. // Check that the operand of a debug info instruction |inst| at |word_index|
  41. // is a result id of an instruction with |expected_opcode|.
  42. spv_result_t ValidateOperandForDebugInfo(
  43. ValidationState_t& _, const std::string& operand_name,
  44. SpvOp expected_opcode, const Instruction* inst, uint32_t word_index,
  45. const std::function<std::string()>& ext_inst_name) {
  46. auto* operand = _.FindDef(inst->word(word_index));
  47. if (operand->opcode() != expected_opcode) {
  48. spv_opcode_desc desc = nullptr;
  49. if (_.grammar().lookupOpcode(expected_opcode, &desc) != SPV_SUCCESS ||
  50. !desc) {
  51. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  52. << ext_inst_name() << ": "
  53. << "expected operand " << operand_name << " is invalid";
  54. }
  55. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  56. << ext_inst_name() << ": "
  57. << "expected operand " << operand_name << " must be a result id of "
  58. << "Op" << desc->name;
  59. }
  60. return SPV_SUCCESS;
  61. }
  62. #define CHECK_OPERAND(NAME, opcode, index) \
  63. do { \
  64. auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  65. ext_inst_name); \
  66. if (result != SPV_SUCCESS) return result; \
  67. } while (0)
  68. // True if the operand of a debug info instruction |inst| at |word_index|
  69. // satisifies |expectation| that is given as a function. Otherwise,
  70. // returns false.
  71. bool DoesDebugInfoOperandMatchExpectation(
  72. const ValidationState_t& _,
  73. const std::function<bool(OpenCLDebugInfo100Instructions)>& expectation,
  74. const Instruction* inst, uint32_t word_index) {
  75. if (inst->words().size() <= word_index) return false;
  76. auto* debug_inst = _.FindDef(inst->word(word_index));
  77. if (debug_inst->opcode() != SpvOpExtInst ||
  78. debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
  79. !expectation(OpenCLDebugInfo100Instructions(debug_inst->word(4)))) {
  80. return false;
  81. }
  82. return true;
  83. }
  84. // Check that the operand of a debug info instruction |inst| at |word_index|
  85. // is a result id of an debug info instruction whose debug instruction type
  86. // is |expected_debug_inst|.
  87. spv_result_t ValidateDebugInfoOperand(
  88. ValidationState_t& _, const std::string& debug_inst_name,
  89. OpenCLDebugInfo100Instructions expected_debug_inst, const Instruction* inst,
  90. uint32_t word_index, const std::function<std::string()>& ext_inst_name) {
  91. std::function<bool(OpenCLDebugInfo100Instructions)> expectation =
  92. [expected_debug_inst](OpenCLDebugInfo100Instructions dbg_inst) {
  93. return dbg_inst == expected_debug_inst;
  94. };
  95. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  96. return SPV_SUCCESS;
  97. spv_ext_inst_desc desc = nullptr;
  98. _.grammar().lookupExtInst(SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
  99. expected_debug_inst, &desc);
  100. if (_.grammar().lookupExtInst(SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
  101. expected_debug_inst, &desc) != SPV_SUCCESS ||
  102. !desc) {
  103. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  104. << ext_inst_name() << ": "
  105. << "expected operand " << debug_inst_name << " is invalid";
  106. }
  107. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  108. << ext_inst_name() << ": "
  109. << "expected operand " << debug_inst_name << " must be a result id of "
  110. << desc->name;
  111. }
  112. #define CHECK_DEBUG_OPERAND(NAME, debug_opcode, index) \
  113. do { \
  114. auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  115. ext_inst_name); \
  116. if (result != SPV_SUCCESS) return result; \
  117. } while (0)
  118. // Check that the operand of a debug info instruction |inst| at |word_index|
  119. // is a result id of an debug info instruction with DebugTypeBasic.
  120. spv_result_t ValidateOperandBaseType(
  121. ValidationState_t& _, const Instruction* inst, uint32_t word_index,
  122. const std::function<std::string()>& ext_inst_name) {
  123. return ValidateDebugInfoOperand(_, "Base Type",
  124. OpenCLDebugInfo100DebugTypeBasic, inst,
  125. word_index, ext_inst_name);
  126. }
  127. // Check that the operand of a debug info instruction |inst| at |word_index|
  128. // is a result id of a debug lexical scope instruction which is one of
  129. // DebugCompilationUnit, DebugFunction, DebugLexicalBlock, or
  130. // DebugTypeComposite.
  131. spv_result_t ValidateOperandLexicalScope(
  132. ValidationState_t& _, const std::string& debug_inst_name,
  133. const Instruction* inst, uint32_t word_index,
  134. const std::function<std::string()>& ext_inst_name) {
  135. std::function<bool(OpenCLDebugInfo100Instructions)> expectation =
  136. [](OpenCLDebugInfo100Instructions dbg_inst) {
  137. return dbg_inst == OpenCLDebugInfo100DebugCompilationUnit ||
  138. dbg_inst == OpenCLDebugInfo100DebugFunction ||
  139. dbg_inst == OpenCLDebugInfo100DebugLexicalBlock ||
  140. dbg_inst == OpenCLDebugInfo100DebugTypeComposite;
  141. };
  142. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  143. return SPV_SUCCESS;
  144. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  145. << ext_inst_name() << ": "
  146. << "expected operand " << debug_inst_name
  147. << " must be a result id of a lexical scope";
  148. }
  149. // Check that the operand of a debug info instruction |inst| at |word_index|
  150. // is a result id of a debug type instruction (See DebugTypeXXX in
  151. // "4.3. Type instructions" section of OpenCL.DebugInfo.100 spec.
  152. spv_result_t ValidateOperandDebugType(
  153. ValidationState_t& _, const std::string& debug_inst_name,
  154. const Instruction* inst, uint32_t word_index,
  155. const std::function<std::string()>& ext_inst_name,
  156. bool allow_template_param) {
  157. std::function<bool(OpenCLDebugInfo100Instructions)> expectation =
  158. [&allow_template_param](OpenCLDebugInfo100Instructions dbg_inst) {
  159. if (allow_template_param &&
  160. (dbg_inst == OpenCLDebugInfo100DebugTypeTemplateParameter ||
  161. dbg_inst ==
  162. OpenCLDebugInfo100DebugTypeTemplateTemplateParameter)) {
  163. return true;
  164. }
  165. return OpenCLDebugInfo100DebugTypeBasic <= dbg_inst &&
  166. dbg_inst <= OpenCLDebugInfo100DebugTypeTemplate;
  167. };
  168. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  169. return SPV_SUCCESS;
  170. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  171. << ext_inst_name() << ": "
  172. << "expected operand " << debug_inst_name
  173. << " is not a valid debug type";
  174. }
  175. bool IsUint32Constant(ValidationState_t& _, uint32_t id) {
  176. auto inst = _.FindDef(id);
  177. if (!inst || inst->opcode() != SpvOpConstant) {
  178. return false;
  179. }
  180. auto type = _.FindDef(inst->type_id());
  181. if (!type || type->opcode() != SpvOpTypeInt) {
  182. return false;
  183. }
  184. if (type->GetOperandAs<uint32_t>(1) != 32) {
  185. return false;
  186. }
  187. if (type->GetOperandAs<uint32_t>(2) != 0) {
  188. return false;
  189. }
  190. return true;
  191. }
  192. spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _,
  193. const Instruction* inst) {
  194. const auto kernel_id = inst->GetOperandAs<uint32_t>(4);
  195. const auto kernel = _.FindDef(kernel_id);
  196. if (kernel->opcode() != SpvOpFunction) {
  197. return _.diag(SPV_ERROR_INVALID_ID, inst)
  198. << "Kernel does not reference a function";
  199. }
  200. bool found_kernel = false;
  201. for (auto entry_point : _.entry_points()) {
  202. if (entry_point == kernel_id) {
  203. found_kernel = true;
  204. break;
  205. }
  206. }
  207. if (!found_kernel) {
  208. return _.diag(SPV_ERROR_INVALID_ID, inst)
  209. << "Kernel does not reference an entry-point";
  210. }
  211. const auto* exec_models = _.GetExecutionModels(kernel_id);
  212. if (!exec_models || exec_models->empty()) {
  213. return _.diag(SPV_ERROR_INVALID_ID, inst)
  214. << "Kernel does not reference an entry-point";
  215. }
  216. for (auto exec_model : *exec_models) {
  217. if (exec_model != SpvExecutionModelGLCompute) {
  218. return _.diag(SPV_ERROR_INVALID_ID, inst)
  219. << "Kernel must refer only to GLCompute entry-points";
  220. }
  221. }
  222. auto name = _.FindDef(inst->GetOperandAs<uint32_t>(5));
  223. if (!name || name->opcode() != SpvOpString) {
  224. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString";
  225. }
  226. const std::string name_str = reinterpret_cast<const char*>(
  227. name->words().data() + name->operands()[1].offset);
  228. bool found = false;
  229. for (auto& desc : _.entry_point_descriptions(kernel_id)) {
  230. if (name_str == desc.name) {
  231. found = true;
  232. break;
  233. }
  234. }
  235. if (!found) {
  236. return _.diag(SPV_ERROR_INVALID_ID, inst)
  237. << "Name must match an entry-point for Kernel";
  238. }
  239. return SPV_SUCCESS;
  240. }
  241. spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _,
  242. const Instruction* inst) {
  243. const auto num_operands = inst->operands().size();
  244. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(4)) != SpvOpString) {
  245. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString";
  246. }
  247. if (num_operands > 5) {
  248. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(5)) != SpvOpString) {
  249. return _.diag(SPV_ERROR_INVALID_ID, inst)
  250. << "TypeName must be an OpString";
  251. }
  252. }
  253. if (num_operands > 6) {
  254. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  255. return _.diag(SPV_ERROR_INVALID_ID, inst)
  256. << "AddressQualifier must be a 32-bit unsigned integer "
  257. "OpConstant";
  258. }
  259. }
  260. if (num_operands > 7) {
  261. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  262. return _.diag(SPV_ERROR_INVALID_ID, inst)
  263. << "AccessQualifier must be a 32-bit unsigned integer "
  264. "OpConstant";
  265. }
  266. }
  267. if (num_operands > 8) {
  268. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(8))) {
  269. return _.diag(SPV_ERROR_INVALID_ID, inst)
  270. << "TypeQualifier must be a 32-bit unsigned integer "
  271. "OpConstant";
  272. }
  273. }
  274. return SPV_SUCCESS;
  275. }
  276. spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) {
  277. const auto decl_id = inst->GetOperandAs<uint32_t>(4);
  278. const auto decl = _.FindDef(decl_id);
  279. if (!decl || decl->opcode() != SpvOpExtInst) {
  280. return _.diag(SPV_ERROR_INVALID_ID, inst)
  281. << "Kernel must be a Kernel extended instruction";
  282. }
  283. if (decl->GetOperandAs<uint32_t>(2) != inst->GetOperandAs<uint32_t>(2)) {
  284. return _.diag(SPV_ERROR_INVALID_ID, inst)
  285. << "Kernel must be from the same extended instruction import";
  286. }
  287. const auto ext_inst =
  288. decl->GetOperandAs<NonSemanticClspvReflectionInstructions>(3);
  289. if (ext_inst != NonSemanticClspvReflectionKernel) {
  290. return _.diag(SPV_ERROR_INVALID_ID, inst)
  291. << "Kernel must be a Kernel extended instruction";
  292. }
  293. return SPV_SUCCESS;
  294. }
  295. spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst,
  296. uint32_t info_index) {
  297. auto info = _.FindDef(inst->GetOperandAs<uint32_t>(info_index));
  298. if (!info || info->opcode() != SpvOpExtInst) {
  299. return _.diag(SPV_ERROR_INVALID_ID, inst)
  300. << "ArgInfo must be an ArgumentInfo extended instruction";
  301. }
  302. if (info->GetOperandAs<uint32_t>(2) != inst->GetOperandAs<uint32_t>(2)) {
  303. return _.diag(SPV_ERROR_INVALID_ID, inst)
  304. << "ArgInfo must be from the same extended instruction import";
  305. }
  306. auto ext_inst = info->GetOperandAs<NonSemanticClspvReflectionInstructions>(3);
  307. if (ext_inst != NonSemanticClspvReflectionArgumentInfo) {
  308. return _.diag(SPV_ERROR_INVALID_ID, inst)
  309. << "ArgInfo must be an ArgumentInfo extended instruction";
  310. }
  311. return SPV_SUCCESS;
  312. }
  313. spv_result_t ValidateClspvReflectionArgumentBuffer(ValidationState_t& _,
  314. const Instruction* inst) {
  315. const auto num_operands = inst->operands().size();
  316. if (auto error = ValidateKernelDecl(_, inst)) {
  317. return error;
  318. }
  319. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  320. return _.diag(SPV_ERROR_INVALID_ID, inst)
  321. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  322. }
  323. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  324. return _.diag(SPV_ERROR_INVALID_ID, inst)
  325. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  326. }
  327. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  328. return _.diag(SPV_ERROR_INVALID_ID, inst)
  329. << "Binding must be a 32-bit unsigned integer OpConstant";
  330. }
  331. if (num_operands == 9) {
  332. if (auto error = ValidateArgInfo(_, inst, 8)) {
  333. return error;
  334. }
  335. }
  336. return SPV_SUCCESS;
  337. }
  338. spv_result_t ValidateClspvReflectionArgumentPodBuffer(ValidationState_t& _,
  339. const Instruction* inst) {
  340. const auto num_operands = inst->operands().size();
  341. if (auto error = ValidateKernelDecl(_, inst)) {
  342. return error;
  343. }
  344. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  345. return _.diag(SPV_ERROR_INVALID_ID, inst)
  346. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  347. }
  348. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  349. return _.diag(SPV_ERROR_INVALID_ID, inst)
  350. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  351. }
  352. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  353. return _.diag(SPV_ERROR_INVALID_ID, inst)
  354. << "Binding must be a 32-bit unsigned integer OpConstant";
  355. }
  356. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(8))) {
  357. return _.diag(SPV_ERROR_INVALID_ID, inst)
  358. << "Offset must be a 32-bit unsigned integer OpConstant";
  359. }
  360. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(9))) {
  361. return _.diag(SPV_ERROR_INVALID_ID, inst)
  362. << "Size must be a 32-bit unsigned integer OpConstant";
  363. }
  364. if (num_operands == 11) {
  365. if (auto error = ValidateArgInfo(_, inst, 10)) {
  366. return error;
  367. }
  368. }
  369. return SPV_SUCCESS;
  370. }
  371. spv_result_t ValidateClspvReflectionArgumentPodPushConstant(
  372. ValidationState_t& _, const Instruction* inst) {
  373. const auto num_operands = inst->operands().size();
  374. if (auto error = ValidateKernelDecl(_, inst)) {
  375. return error;
  376. }
  377. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  378. return _.diag(SPV_ERROR_INVALID_ID, inst)
  379. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  380. }
  381. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  382. return _.diag(SPV_ERROR_INVALID_ID, inst)
  383. << "Offset must be a 32-bit unsigned integer OpConstant";
  384. }
  385. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  386. return _.diag(SPV_ERROR_INVALID_ID, inst)
  387. << "Size must be a 32-bit unsigned integer OpConstant";
  388. }
  389. if (num_operands == 9) {
  390. if (auto error = ValidateArgInfo(_, inst, 8)) {
  391. return error;
  392. }
  393. }
  394. return SPV_SUCCESS;
  395. }
  396. spv_result_t ValidateClspvReflectionArgumentWorkgroup(ValidationState_t& _,
  397. const Instruction* inst) {
  398. const auto num_operands = inst->operands().size();
  399. if (auto error = ValidateKernelDecl(_, inst)) {
  400. return error;
  401. }
  402. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  403. return _.diag(SPV_ERROR_INVALID_ID, inst)
  404. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  405. }
  406. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  407. return _.diag(SPV_ERROR_INVALID_ID, inst)
  408. << "SpecId must be a 32-bit unsigned integer OpConstant";
  409. }
  410. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  411. return _.diag(SPV_ERROR_INVALID_ID, inst)
  412. << "ElemSize must be a 32-bit unsigned integer OpConstant";
  413. }
  414. if (num_operands == 9) {
  415. if (auto error = ValidateArgInfo(_, inst, 8)) {
  416. return error;
  417. }
  418. }
  419. return SPV_SUCCESS;
  420. }
  421. spv_result_t ValidateClspvReflectionSpecConstantTriple(
  422. ValidationState_t& _, const Instruction* inst) {
  423. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  424. return _.diag(SPV_ERROR_INVALID_ID, inst)
  425. << "X must be a 32-bit unsigned integer OpConstant";
  426. }
  427. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  428. return _.diag(SPV_ERROR_INVALID_ID, inst)
  429. << "Y must be a 32-bit unsigned integer OpConstant";
  430. }
  431. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  432. return _.diag(SPV_ERROR_INVALID_ID, inst)
  433. << "Z must be a 32-bit unsigned integer OpConstant";
  434. }
  435. return SPV_SUCCESS;
  436. }
  437. spv_result_t ValidateClspvReflectionSpecConstantWorkDim(
  438. ValidationState_t& _, const Instruction* inst) {
  439. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  440. return _.diag(SPV_ERROR_INVALID_ID, inst)
  441. << "Dim must be a 32-bit unsigned integer OpConstant";
  442. }
  443. return SPV_SUCCESS;
  444. }
  445. spv_result_t ValidateClspvReflectionPushConstant(ValidationState_t& _,
  446. const Instruction* inst) {
  447. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  448. return _.diag(SPV_ERROR_INVALID_ID, inst)
  449. << "Offset must be a 32-bit unsigned integer OpConstant";
  450. }
  451. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  452. return _.diag(SPV_ERROR_INVALID_ID, inst)
  453. << "Size must be a 32-bit unsigned integer OpConstant";
  454. }
  455. return SPV_SUCCESS;
  456. }
  457. spv_result_t ValidateClspvReflectionConstantData(ValidationState_t& _,
  458. const Instruction* inst) {
  459. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  460. return _.diag(SPV_ERROR_INVALID_ID, inst)
  461. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  462. }
  463. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  464. return _.diag(SPV_ERROR_INVALID_ID, inst)
  465. << "Binding must be a 32-bit unsigned integer OpConstant";
  466. }
  467. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(6)) != SpvOpString) {
  468. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString";
  469. }
  470. return SPV_SUCCESS;
  471. }
  472. spv_result_t ValidateClspvReflectionSampler(ValidationState_t& _,
  473. const Instruction* inst) {
  474. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  475. return _.diag(SPV_ERROR_INVALID_ID, inst)
  476. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  477. }
  478. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  479. return _.diag(SPV_ERROR_INVALID_ID, inst)
  480. << "Binding must be a 32-bit unsigned integer OpConstant";
  481. }
  482. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  483. return _.diag(SPV_ERROR_INVALID_ID, inst)
  484. << "Mask must be a 32-bit unsigned integer OpConstant";
  485. }
  486. return SPV_SUCCESS;
  487. }
  488. spv_result_t ValidateClspvReflectionPropertyRequiredWorkgroupSize(
  489. ValidationState_t& _, const Instruction* inst) {
  490. if (auto error = ValidateKernelDecl(_, inst)) {
  491. return error;
  492. }
  493. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  494. return _.diag(SPV_ERROR_INVALID_ID, inst)
  495. << "X must be a 32-bit unsigned integer OpConstant";
  496. }
  497. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  498. return _.diag(SPV_ERROR_INVALID_ID, inst)
  499. << "Y must be a 32-bit unsigned integer OpConstant";
  500. }
  501. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  502. return _.diag(SPV_ERROR_INVALID_ID, inst)
  503. << "Z must be a 32-bit unsigned integer OpConstant";
  504. }
  505. return SPV_SUCCESS;
  506. }
  507. spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _,
  508. const Instruction* inst,
  509. uint32_t /*version*/) {
  510. if (!_.IsVoidType(inst->type_id())) {
  511. return _.diag(SPV_ERROR_INVALID_ID, inst)
  512. << "Return Type must be OpTypeVoid";
  513. }
  514. auto ext_inst = inst->GetOperandAs<NonSemanticClspvReflectionInstructions>(3);
  515. switch (ext_inst) {
  516. case NonSemanticClspvReflectionKernel:
  517. return ValidateClspvReflectionKernel(_, inst);
  518. case NonSemanticClspvReflectionArgumentInfo:
  519. return ValidateClspvReflectionArgumentInfo(_, inst);
  520. case NonSemanticClspvReflectionArgumentStorageBuffer:
  521. case NonSemanticClspvReflectionArgumentUniform:
  522. case NonSemanticClspvReflectionArgumentSampledImage:
  523. case NonSemanticClspvReflectionArgumentStorageImage:
  524. case NonSemanticClspvReflectionArgumentSampler:
  525. return ValidateClspvReflectionArgumentBuffer(_, inst);
  526. case NonSemanticClspvReflectionArgumentPodStorageBuffer:
  527. case NonSemanticClspvReflectionArgumentPodUniform:
  528. return ValidateClspvReflectionArgumentPodBuffer(_, inst);
  529. case NonSemanticClspvReflectionArgumentPodPushConstant:
  530. return ValidateClspvReflectionArgumentPodPushConstant(_, inst);
  531. case NonSemanticClspvReflectionArgumentWorkgroup:
  532. return ValidateClspvReflectionArgumentWorkgroup(_, inst);
  533. case NonSemanticClspvReflectionSpecConstantWorkgroupSize:
  534. case NonSemanticClspvReflectionSpecConstantGlobalOffset:
  535. return ValidateClspvReflectionSpecConstantTriple(_, inst);
  536. case NonSemanticClspvReflectionSpecConstantWorkDim:
  537. return ValidateClspvReflectionSpecConstantWorkDim(_, inst);
  538. case NonSemanticClspvReflectionPushConstantGlobalOffset:
  539. case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize:
  540. case NonSemanticClspvReflectionPushConstantGlobalSize:
  541. case NonSemanticClspvReflectionPushConstantRegionOffset:
  542. case NonSemanticClspvReflectionPushConstantNumWorkgroups:
  543. case NonSemanticClspvReflectionPushConstantRegionGroupOffset:
  544. return ValidateClspvReflectionPushConstant(_, inst);
  545. case NonSemanticClspvReflectionConstantDataStorageBuffer:
  546. case NonSemanticClspvReflectionConstantDataUniform:
  547. return ValidateClspvReflectionConstantData(_, inst);
  548. case NonSemanticClspvReflectionLiteralSampler:
  549. return ValidateClspvReflectionSampler(_, inst);
  550. case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize:
  551. return ValidateClspvReflectionPropertyRequiredWorkgroupSize(_, inst);
  552. default:
  553. break;
  554. }
  555. return SPV_SUCCESS;
  556. }
  557. bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _,
  558. Instruction* instr) {
  559. if (instr->opcode() != SpvOpConstant) return false;
  560. if (!_.IsIntScalarType(instr->type_id())) return false;
  561. uint32_t size_in_bits = _.GetBitWidth(instr->type_id());
  562. return size_in_bits == 32 || size_in_bits == 64;
  563. }
  564. bool IsConstWithIntScalarType(ValidationState_t& _, const Instruction* inst,
  565. uint32_t word_index) {
  566. auto* int_scalar_const = _.FindDef(inst->word(word_index));
  567. if (int_scalar_const->opcode() == SpvOpConstant &&
  568. _.IsIntScalarType(int_scalar_const->type_id())) {
  569. return true;
  570. }
  571. return false;
  572. }
  573. bool IsDebugVariableWithIntScalarType(ValidationState_t& _,
  574. const Instruction* inst,
  575. uint32_t word_index) {
  576. auto* dbg_int_scalar_var = _.FindDef(inst->word(word_index));
  577. if (OpenCLDebugInfo100Instructions(dbg_int_scalar_var->word(4)) ==
  578. OpenCLDebugInfo100DebugLocalVariable ||
  579. OpenCLDebugInfo100Instructions(dbg_int_scalar_var->word(4)) ==
  580. OpenCLDebugInfo100DebugGlobalVariable) {
  581. auto* dbg_type = _.FindDef(dbg_int_scalar_var->word(6));
  582. if (OpenCLDebugInfo100Instructions(dbg_type->word(4)) ==
  583. OpenCLDebugInfo100DebugTypeBasic &&
  584. (OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(dbg_type->word(7)) ==
  585. OpenCLDebugInfo100Signed ||
  586. OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(dbg_type->word(7)) ==
  587. OpenCLDebugInfo100Unsigned)) {
  588. return true;
  589. }
  590. }
  591. return false;
  592. }
  593. } // anonymous namespace
  594. spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) {
  595. if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) {
  596. std::string extension = GetExtensionString(&(inst->c_inst()));
  597. if (extension ==
  598. ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout)) {
  599. return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  600. << "SPV_KHR_workgroup_memory_explicit_layout extension "
  601. "requires SPIR-V version 1.4 or later.";
  602. }
  603. }
  604. return SPV_SUCCESS;
  605. }
  606. spv_result_t ValidateExtInstImport(ValidationState_t& _,
  607. const Instruction* inst) {
  608. const auto name_id = 1;
  609. if (!_.HasExtension(kSPV_KHR_non_semantic_info)) {
  610. const std::string name(reinterpret_cast<const char*>(
  611. inst->words().data() + inst->operands()[name_id].offset));
  612. if (name.find("NonSemantic.") == 0) {
  613. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  614. << "NonSemantic extended instruction sets cannot be declared "
  615. "without SPV_KHR_non_semantic_info.";
  616. }
  617. }
  618. return SPV_SUCCESS;
  619. }
  620. spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
  621. const uint32_t result_type = inst->type_id();
  622. const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size());
  623. const uint32_t ext_inst_set = inst->word(3);
  624. const uint32_t ext_inst_index = inst->word(4);
  625. const spv_ext_inst_type_t ext_inst_type =
  626. spv_ext_inst_type_t(inst->ext_inst_type());
  627. auto ext_inst_name = [&_, ext_inst_set, ext_inst_type, ext_inst_index]() {
  628. spv_ext_inst_desc desc = nullptr;
  629. if (_.grammar().lookupExtInst(ext_inst_type, ext_inst_index, &desc) !=
  630. SPV_SUCCESS ||
  631. !desc) {
  632. return std::string("Unknown ExtInst");
  633. }
  634. auto* import_inst = _.FindDef(ext_inst_set);
  635. assert(import_inst);
  636. std::ostringstream ss;
  637. ss << reinterpret_cast<const char*>(import_inst->words().data() + 2);
  638. ss << " ";
  639. ss << desc->name;
  640. return ss.str();
  641. };
  642. if (ext_inst_type == SPV_EXT_INST_TYPE_GLSL_STD_450) {
  643. const GLSLstd450 ext_inst_key = GLSLstd450(ext_inst_index);
  644. switch (ext_inst_key) {
  645. case GLSLstd450Round:
  646. case GLSLstd450RoundEven:
  647. case GLSLstd450FAbs:
  648. case GLSLstd450Trunc:
  649. case GLSLstd450FSign:
  650. case GLSLstd450Floor:
  651. case GLSLstd450Ceil:
  652. case GLSLstd450Fract:
  653. case GLSLstd450Sqrt:
  654. case GLSLstd450InverseSqrt:
  655. case GLSLstd450FMin:
  656. case GLSLstd450FMax:
  657. case GLSLstd450FClamp:
  658. case GLSLstd450FMix:
  659. case GLSLstd450Step:
  660. case GLSLstd450SmoothStep:
  661. case GLSLstd450Fma:
  662. case GLSLstd450Normalize:
  663. case GLSLstd450FaceForward:
  664. case GLSLstd450Reflect:
  665. case GLSLstd450NMin:
  666. case GLSLstd450NMax:
  667. case GLSLstd450NClamp: {
  668. if (!_.IsFloatScalarOrVectorType(result_type)) {
  669. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  670. << ext_inst_name() << ": "
  671. << "expected Result Type to be a float scalar or vector type";
  672. }
  673. for (uint32_t operand_index = 4; operand_index < num_operands;
  674. ++operand_index) {
  675. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  676. if (result_type != operand_type) {
  677. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  678. << ext_inst_name() << ": "
  679. << "expected types of all operands to be equal to Result "
  680. "Type";
  681. }
  682. }
  683. break;
  684. }
  685. case GLSLstd450SAbs:
  686. case GLSLstd450SSign:
  687. case GLSLstd450UMin:
  688. case GLSLstd450SMin:
  689. case GLSLstd450UMax:
  690. case GLSLstd450SMax:
  691. case GLSLstd450UClamp:
  692. case GLSLstd450SClamp:
  693. case GLSLstd450FindILsb:
  694. case GLSLstd450FindUMsb:
  695. case GLSLstd450FindSMsb: {
  696. if (!_.IsIntScalarOrVectorType(result_type)) {
  697. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  698. << ext_inst_name() << ": "
  699. << "expected Result Type to be an int scalar or vector type";
  700. }
  701. const uint32_t result_type_bit_width = _.GetBitWidth(result_type);
  702. const uint32_t result_type_dimension = _.GetDimension(result_type);
  703. for (uint32_t operand_index = 4; operand_index < num_operands;
  704. ++operand_index) {
  705. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  706. if (!_.IsIntScalarOrVectorType(operand_type)) {
  707. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  708. << ext_inst_name() << ": "
  709. << "expected all operands to be int scalars or vectors";
  710. }
  711. if (result_type_dimension != _.GetDimension(operand_type)) {
  712. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  713. << ext_inst_name() << ": "
  714. << "expected all operands to have the same dimension as "
  715. << "Result Type";
  716. }
  717. if (result_type_bit_width != _.GetBitWidth(operand_type)) {
  718. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  719. << ext_inst_name() << ": "
  720. << "expected all operands to have the same bit width as "
  721. << "Result Type";
  722. }
  723. if (ext_inst_key == GLSLstd450FindUMsb ||
  724. ext_inst_key == GLSLstd450FindSMsb) {
  725. if (result_type_bit_width != 32) {
  726. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  727. << ext_inst_name() << ": "
  728. << "this instruction is currently limited to 32-bit width "
  729. << "components";
  730. }
  731. }
  732. }
  733. break;
  734. }
  735. case GLSLstd450Radians:
  736. case GLSLstd450Degrees:
  737. case GLSLstd450Sin:
  738. case GLSLstd450Cos:
  739. case GLSLstd450Tan:
  740. case GLSLstd450Asin:
  741. case GLSLstd450Acos:
  742. case GLSLstd450Atan:
  743. case GLSLstd450Sinh:
  744. case GLSLstd450Cosh:
  745. case GLSLstd450Tanh:
  746. case GLSLstd450Asinh:
  747. case GLSLstd450Acosh:
  748. case GLSLstd450Atanh:
  749. case GLSLstd450Exp:
  750. case GLSLstd450Exp2:
  751. case GLSLstd450Log:
  752. case GLSLstd450Log2:
  753. case GLSLstd450Atan2:
  754. case GLSLstd450Pow: {
  755. if (!_.IsFloatScalarOrVectorType(result_type)) {
  756. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  757. << ext_inst_name() << ": "
  758. << "expected Result Type to be a 16 or 32-bit scalar or "
  759. "vector float type";
  760. }
  761. const uint32_t result_type_bit_width = _.GetBitWidth(result_type);
  762. if (result_type_bit_width != 16 && result_type_bit_width != 32) {
  763. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  764. << ext_inst_name() << ": "
  765. << "expected Result Type to be a 16 or 32-bit scalar or "
  766. "vector float type";
  767. }
  768. for (uint32_t operand_index = 4; operand_index < num_operands;
  769. ++operand_index) {
  770. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  771. if (result_type != operand_type) {
  772. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  773. << ext_inst_name() << ": "
  774. << "expected types of all operands to be equal to Result "
  775. "Type";
  776. }
  777. }
  778. break;
  779. }
  780. case GLSLstd450Determinant: {
  781. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  782. uint32_t num_rows = 0;
  783. uint32_t num_cols = 0;
  784. uint32_t col_type = 0;
  785. uint32_t component_type = 0;
  786. if (!_.GetMatrixTypeInfo(x_type, &num_rows, &num_cols, &col_type,
  787. &component_type) ||
  788. num_rows != num_cols) {
  789. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  790. << ext_inst_name() << ": "
  791. << "expected operand X to be a square matrix";
  792. }
  793. if (result_type != component_type) {
  794. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  795. << ext_inst_name() << ": "
  796. << "expected operand X component type to be equal to "
  797. << "Result Type";
  798. }
  799. break;
  800. }
  801. case GLSLstd450MatrixInverse: {
  802. uint32_t num_rows = 0;
  803. uint32_t num_cols = 0;
  804. uint32_t col_type = 0;
  805. uint32_t component_type = 0;
  806. if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type,
  807. &component_type) ||
  808. num_rows != num_cols) {
  809. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  810. << ext_inst_name() << ": "
  811. << "expected Result Type to be a square matrix";
  812. }
  813. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  814. if (result_type != x_type) {
  815. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  816. << ext_inst_name() << ": "
  817. << "expected operand X type to be equal to Result Type";
  818. }
  819. break;
  820. }
  821. case GLSLstd450Modf: {
  822. if (!_.IsFloatScalarOrVectorType(result_type)) {
  823. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  824. << ext_inst_name() << ": "
  825. << "expected Result Type to be a scalar or vector float type";
  826. }
  827. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  828. const uint32_t i_type = _.GetOperandTypeId(inst, 5);
  829. if (x_type != result_type) {
  830. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  831. << ext_inst_name() << ": "
  832. << "expected operand X type to be equal to Result Type";
  833. }
  834. uint32_t i_storage_class = 0;
  835. uint32_t i_data_type = 0;
  836. if (!_.GetPointerTypeInfo(i_type, &i_data_type, &i_storage_class)) {
  837. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  838. << ext_inst_name() << ": "
  839. << "expected operand I to be a pointer";
  840. }
  841. if (i_data_type != result_type) {
  842. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  843. << ext_inst_name() << ": "
  844. << "expected operand I data type to be equal to Result Type";
  845. }
  846. break;
  847. }
  848. case GLSLstd450ModfStruct: {
  849. std::vector<uint32_t> result_types;
  850. if (!_.GetStructMemberTypes(result_type, &result_types) ||
  851. result_types.size() != 2 ||
  852. !_.IsFloatScalarOrVectorType(result_types[0]) ||
  853. result_types[1] != result_types[0]) {
  854. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  855. << ext_inst_name() << ": "
  856. << "expected Result Type to be a struct with two identical "
  857. << "scalar or vector float type members";
  858. }
  859. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  860. if (x_type != result_types[0]) {
  861. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  862. << ext_inst_name() << ": "
  863. << "expected operand X type to be equal to members of "
  864. << "Result Type struct";
  865. }
  866. break;
  867. }
  868. case GLSLstd450Frexp: {
  869. if (!_.IsFloatScalarOrVectorType(result_type)) {
  870. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  871. << ext_inst_name() << ": "
  872. << "expected Result Type to be a scalar or vector float type";
  873. }
  874. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  875. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  876. if (x_type != result_type) {
  877. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  878. << ext_inst_name() << ": "
  879. << "expected operand X type to be equal to Result Type";
  880. }
  881. uint32_t exp_storage_class = 0;
  882. uint32_t exp_data_type = 0;
  883. if (!_.GetPointerTypeInfo(exp_type, &exp_data_type,
  884. &exp_storage_class)) {
  885. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  886. << ext_inst_name() << ": "
  887. << "expected operand Exp to be a pointer";
  888. }
  889. if (!_.IsIntScalarOrVectorType(exp_data_type) ||
  890. (!_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  891. _.GetBitWidth(exp_data_type) != 32) ||
  892. (_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  893. _.GetBitWidth(exp_data_type) != 16 &&
  894. _.GetBitWidth(exp_data_type) != 32)) {
  895. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  896. << ext_inst_name() << ": "
  897. << "expected operand Exp data type to be a "
  898. << (_.HasExtension(kSPV_AMD_gpu_shader_int16)
  899. ? "16-bit or 32-bit "
  900. : "32-bit ")
  901. << "int scalar or vector type";
  902. }
  903. if (_.GetDimension(result_type) != _.GetDimension(exp_data_type)) {
  904. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  905. << ext_inst_name() << ": "
  906. << "expected operand Exp data type to have the same component "
  907. << "number as Result Type";
  908. }
  909. break;
  910. }
  911. case GLSLstd450Ldexp: {
  912. if (!_.IsFloatScalarOrVectorType(result_type)) {
  913. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  914. << ext_inst_name() << ": "
  915. << "expected Result Type to be a scalar or vector float type";
  916. }
  917. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  918. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  919. if (x_type != result_type) {
  920. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  921. << ext_inst_name() << ": "
  922. << "expected operand X type to be equal to Result Type";
  923. }
  924. if (!_.IsIntScalarOrVectorType(exp_type)) {
  925. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  926. << ext_inst_name() << ": "
  927. << "expected operand Exp to be a 32-bit int scalar "
  928. << "or vector type";
  929. }
  930. if (_.GetDimension(result_type) != _.GetDimension(exp_type)) {
  931. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  932. << ext_inst_name() << ": "
  933. << "expected operand Exp to have the same component "
  934. << "number as Result Type";
  935. }
  936. break;
  937. }
  938. case GLSLstd450FrexpStruct: {
  939. std::vector<uint32_t> result_types;
  940. if (!_.GetStructMemberTypes(result_type, &result_types) ||
  941. result_types.size() != 2 ||
  942. !_.IsFloatScalarOrVectorType(result_types[0]) ||
  943. !_.IsIntScalarOrVectorType(result_types[1]) ||
  944. (!_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  945. _.GetBitWidth(result_types[1]) != 32) ||
  946. (_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  947. _.GetBitWidth(result_types[1]) != 16 &&
  948. _.GetBitWidth(result_types[1]) != 32) ||
  949. _.GetDimension(result_types[0]) !=
  950. _.GetDimension(result_types[1])) {
  951. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  952. << ext_inst_name() << ": "
  953. << "expected Result Type to be a struct with two members, "
  954. << "first member a float scalar or vector, second member a "
  955. << (_.HasExtension(kSPV_AMD_gpu_shader_int16)
  956. ? "16-bit or 32-bit "
  957. : "32-bit ")
  958. << "int scalar or vector with the same number of "
  959. << "components as the first member";
  960. }
  961. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  962. if (x_type != result_types[0]) {
  963. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  964. << ext_inst_name() << ": "
  965. << "expected operand X type to be equal to the first member "
  966. << "of Result Type struct";
  967. }
  968. break;
  969. }
  970. case GLSLstd450PackSnorm4x8:
  971. case GLSLstd450PackUnorm4x8: {
  972. if (!_.IsIntScalarType(result_type) ||
  973. _.GetBitWidth(result_type) != 32) {
  974. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  975. << ext_inst_name() << ": "
  976. << "expected Result Type to be 32-bit int scalar type";
  977. }
  978. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  979. if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 4 ||
  980. _.GetBitWidth(v_type) != 32) {
  981. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  982. << ext_inst_name() << ": "
  983. << "expected operand V to be a 32-bit float vector of size 4";
  984. }
  985. break;
  986. }
  987. case GLSLstd450PackSnorm2x16:
  988. case GLSLstd450PackUnorm2x16:
  989. case GLSLstd450PackHalf2x16: {
  990. if (!_.IsIntScalarType(result_type) ||
  991. _.GetBitWidth(result_type) != 32) {
  992. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  993. << ext_inst_name() << ": "
  994. << "expected Result Type to be 32-bit int scalar type";
  995. }
  996. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  997. if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 2 ||
  998. _.GetBitWidth(v_type) != 32) {
  999. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1000. << ext_inst_name() << ": "
  1001. << "expected operand V to be a 32-bit float vector of size 2";
  1002. }
  1003. break;
  1004. }
  1005. case GLSLstd450PackDouble2x32: {
  1006. if (!_.IsFloatScalarType(result_type) ||
  1007. _.GetBitWidth(result_type) != 64) {
  1008. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1009. << ext_inst_name() << ": "
  1010. << "expected Result Type to be 64-bit float scalar type";
  1011. }
  1012. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1013. if (!_.IsIntVectorType(v_type) || _.GetDimension(v_type) != 2 ||
  1014. _.GetBitWidth(v_type) != 32) {
  1015. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1016. << ext_inst_name() << ": "
  1017. << "expected operand V to be a 32-bit int vector of size 2";
  1018. }
  1019. break;
  1020. }
  1021. case GLSLstd450UnpackSnorm4x8:
  1022. case GLSLstd450UnpackUnorm4x8: {
  1023. if (!_.IsFloatVectorType(result_type) ||
  1024. _.GetDimension(result_type) != 4 ||
  1025. _.GetBitWidth(result_type) != 32) {
  1026. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1027. << ext_inst_name() << ": "
  1028. << "expected Result Type to be a 32-bit float vector of size "
  1029. "4";
  1030. }
  1031. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1032. if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) {
  1033. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1034. << ext_inst_name() << ": "
  1035. << "expected operand P to be a 32-bit int scalar";
  1036. }
  1037. break;
  1038. }
  1039. case GLSLstd450UnpackSnorm2x16:
  1040. case GLSLstd450UnpackUnorm2x16:
  1041. case GLSLstd450UnpackHalf2x16: {
  1042. if (!_.IsFloatVectorType(result_type) ||
  1043. _.GetDimension(result_type) != 2 ||
  1044. _.GetBitWidth(result_type) != 32) {
  1045. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1046. << ext_inst_name() << ": "
  1047. << "expected Result Type to be a 32-bit float vector of size "
  1048. "2";
  1049. }
  1050. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1051. if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) {
  1052. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1053. << ext_inst_name() << ": "
  1054. << "expected operand P to be a 32-bit int scalar";
  1055. }
  1056. break;
  1057. }
  1058. case GLSLstd450UnpackDouble2x32: {
  1059. if (!_.IsIntVectorType(result_type) ||
  1060. _.GetDimension(result_type) != 2 ||
  1061. _.GetBitWidth(result_type) != 32) {
  1062. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1063. << ext_inst_name() << ": "
  1064. << "expected Result Type to be a 32-bit int vector of size "
  1065. "2";
  1066. }
  1067. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1068. if (!_.IsFloatScalarType(v_type) || _.GetBitWidth(v_type) != 64) {
  1069. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1070. << ext_inst_name() << ": "
  1071. << "expected operand V to be a 64-bit float scalar";
  1072. }
  1073. break;
  1074. }
  1075. case GLSLstd450Length: {
  1076. if (!_.IsFloatScalarType(result_type)) {
  1077. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1078. << ext_inst_name() << ": "
  1079. << "expected Result Type to be a float scalar type";
  1080. }
  1081. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1082. if (!_.IsFloatScalarOrVectorType(x_type)) {
  1083. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1084. << ext_inst_name() << ": "
  1085. << "expected operand X to be of float scalar or vector type";
  1086. }
  1087. if (result_type != _.GetComponentType(x_type)) {
  1088. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1089. << ext_inst_name() << ": "
  1090. << "expected operand X component type to be equal to Result "
  1091. "Type";
  1092. }
  1093. break;
  1094. }
  1095. case GLSLstd450Distance: {
  1096. if (!_.IsFloatScalarType(result_type)) {
  1097. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1098. << ext_inst_name() << ": "
  1099. << "expected Result Type to be a float scalar type";
  1100. }
  1101. const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
  1102. if (!_.IsFloatScalarOrVectorType(p0_type)) {
  1103. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1104. << ext_inst_name() << ": "
  1105. << "expected operand P0 to be of float scalar or vector type";
  1106. }
  1107. if (result_type != _.GetComponentType(p0_type)) {
  1108. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1109. << ext_inst_name() << ": "
  1110. << "expected operand P0 component type to be equal to "
  1111. << "Result Type";
  1112. }
  1113. const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
  1114. if (!_.IsFloatScalarOrVectorType(p1_type)) {
  1115. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1116. << ext_inst_name() << ": "
  1117. << "expected operand P1 to be of float scalar or vector type";
  1118. }
  1119. if (result_type != _.GetComponentType(p1_type)) {
  1120. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1121. << ext_inst_name() << ": "
  1122. << "expected operand P1 component type to be equal to "
  1123. << "Result Type";
  1124. }
  1125. if (_.GetDimension(p0_type) != _.GetDimension(p1_type)) {
  1126. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1127. << ext_inst_name() << ": "
  1128. << "expected operands P0 and P1 to have the same number of "
  1129. << "components";
  1130. }
  1131. break;
  1132. }
  1133. case GLSLstd450Cross: {
  1134. if (!_.IsFloatVectorType(result_type)) {
  1135. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1136. << ext_inst_name() << ": "
  1137. << "expected Result Type to be a float vector type";
  1138. }
  1139. if (_.GetDimension(result_type) != 3) {
  1140. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1141. << ext_inst_name() << ": "
  1142. << "expected Result Type to have 3 components";
  1143. }
  1144. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1145. const uint32_t y_type = _.GetOperandTypeId(inst, 5);
  1146. if (x_type != result_type) {
  1147. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1148. << ext_inst_name() << ": "
  1149. << "expected operand X type to be equal to Result Type";
  1150. }
  1151. if (y_type != result_type) {
  1152. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1153. << ext_inst_name() << ": "
  1154. << "expected operand Y type to be equal to Result Type";
  1155. }
  1156. break;
  1157. }
  1158. case GLSLstd450Refract: {
  1159. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1160. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1161. << ext_inst_name() << ": "
  1162. << "expected Result Type to be a float scalar or vector type";
  1163. }
  1164. const uint32_t i_type = _.GetOperandTypeId(inst, 4);
  1165. const uint32_t n_type = _.GetOperandTypeId(inst, 5);
  1166. const uint32_t eta_type = _.GetOperandTypeId(inst, 6);
  1167. if (result_type != i_type) {
  1168. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1169. << ext_inst_name() << ": "
  1170. << "expected operand I to be of type equal to Result Type";
  1171. }
  1172. if (result_type != n_type) {
  1173. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1174. << ext_inst_name() << ": "
  1175. << "expected operand N to be of type equal to Result Type";
  1176. }
  1177. if (!_.IsFloatScalarType(eta_type)) {
  1178. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1179. << ext_inst_name() << ": "
  1180. << "expected operand Eta to be a float scalar";
  1181. }
  1182. break;
  1183. }
  1184. case GLSLstd450InterpolateAtCentroid:
  1185. case GLSLstd450InterpolateAtSample:
  1186. case GLSLstd450InterpolateAtOffset: {
  1187. if (!_.HasCapability(SpvCapabilityInterpolationFunction)) {
  1188. return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  1189. << ext_inst_name()
  1190. << " requires capability InterpolationFunction";
  1191. }
  1192. if (!_.IsFloatScalarOrVectorType(result_type) ||
  1193. _.GetBitWidth(result_type) != 32) {
  1194. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1195. << ext_inst_name() << ": "
  1196. << "expected Result Type to be a 32-bit float scalar "
  1197. << "or vector type";
  1198. }
  1199. // If HLSL legalization and first operand is an OpLoad, use load
  1200. // pointer as the interpolant lvalue. Else use interpolate first
  1201. // operand.
  1202. uint32_t interp_id = inst->GetOperandAs<uint32_t>(4);
  1203. auto* interp_inst = _.FindDef(interp_id);
  1204. uint32_t interpolant_type = (_.options()->before_hlsl_legalization &&
  1205. interp_inst->opcode() == SpvOpLoad)
  1206. ? _.GetOperandTypeId(interp_inst, 2)
  1207. : _.GetOperandTypeId(inst, 4);
  1208. uint32_t interpolant_storage_class = 0;
  1209. uint32_t interpolant_data_type = 0;
  1210. if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type,
  1211. &interpolant_storage_class)) {
  1212. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1213. << ext_inst_name() << ": "
  1214. << "expected Interpolant to be a pointer";
  1215. }
  1216. if (result_type != interpolant_data_type) {
  1217. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1218. << ext_inst_name() << ": "
  1219. << "expected Interpolant data type to be equal to Result Type";
  1220. }
  1221. if (interpolant_storage_class != SpvStorageClassInput) {
  1222. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1223. << ext_inst_name() << ": "
  1224. << "expected Interpolant storage class to be Input";
  1225. }
  1226. if (ext_inst_key == GLSLstd450InterpolateAtSample) {
  1227. const uint32_t sample_type = _.GetOperandTypeId(inst, 5);
  1228. if (!_.IsIntScalarType(sample_type) ||
  1229. _.GetBitWidth(sample_type) != 32) {
  1230. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1231. << ext_inst_name() << ": "
  1232. << "expected Sample to be 32-bit integer";
  1233. }
  1234. }
  1235. if (ext_inst_key == GLSLstd450InterpolateAtOffset) {
  1236. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  1237. if (!_.IsFloatVectorType(offset_type) ||
  1238. _.GetDimension(offset_type) != 2 ||
  1239. _.GetBitWidth(offset_type) != 32) {
  1240. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1241. << ext_inst_name() << ": "
  1242. << "expected Offset to be a vector of 2 32-bit floats";
  1243. }
  1244. }
  1245. _.function(inst->function()->id())
  1246. ->RegisterExecutionModelLimitation(
  1247. SpvExecutionModelFragment,
  1248. ext_inst_name() +
  1249. std::string(" requires Fragment execution model"));
  1250. break;
  1251. }
  1252. case GLSLstd450IMix: {
  1253. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1254. << "Extended instruction GLSLstd450IMix is not supported";
  1255. }
  1256. case GLSLstd450Bad: {
  1257. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1258. << "Encountered extended instruction GLSLstd450Bad";
  1259. }
  1260. case GLSLstd450Count: {
  1261. assert(0);
  1262. break;
  1263. }
  1264. }
  1265. } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_STD) {
  1266. const OpenCLLIB::Entrypoints ext_inst_key =
  1267. OpenCLLIB::Entrypoints(ext_inst_index);
  1268. switch (ext_inst_key) {
  1269. case OpenCLLIB::Acos:
  1270. case OpenCLLIB::Acosh:
  1271. case OpenCLLIB::Acospi:
  1272. case OpenCLLIB::Asin:
  1273. case OpenCLLIB::Asinh:
  1274. case OpenCLLIB::Asinpi:
  1275. case OpenCLLIB::Atan:
  1276. case OpenCLLIB::Atan2:
  1277. case OpenCLLIB::Atanh:
  1278. case OpenCLLIB::Atanpi:
  1279. case OpenCLLIB::Atan2pi:
  1280. case OpenCLLIB::Cbrt:
  1281. case OpenCLLIB::Ceil:
  1282. case OpenCLLIB::Copysign:
  1283. case OpenCLLIB::Cos:
  1284. case OpenCLLIB::Cosh:
  1285. case OpenCLLIB::Cospi:
  1286. case OpenCLLIB::Erfc:
  1287. case OpenCLLIB::Erf:
  1288. case OpenCLLIB::Exp:
  1289. case OpenCLLIB::Exp2:
  1290. case OpenCLLIB::Exp10:
  1291. case OpenCLLIB::Expm1:
  1292. case OpenCLLIB::Fabs:
  1293. case OpenCLLIB::Fdim:
  1294. case OpenCLLIB::Floor:
  1295. case OpenCLLIB::Fma:
  1296. case OpenCLLIB::Fmax:
  1297. case OpenCLLIB::Fmin:
  1298. case OpenCLLIB::Fmod:
  1299. case OpenCLLIB::Hypot:
  1300. case OpenCLLIB::Lgamma:
  1301. case OpenCLLIB::Log:
  1302. case OpenCLLIB::Log2:
  1303. case OpenCLLIB::Log10:
  1304. case OpenCLLIB::Log1p:
  1305. case OpenCLLIB::Logb:
  1306. case OpenCLLIB::Mad:
  1307. case OpenCLLIB::Maxmag:
  1308. case OpenCLLIB::Minmag:
  1309. case OpenCLLIB::Nextafter:
  1310. case OpenCLLIB::Pow:
  1311. case OpenCLLIB::Powr:
  1312. case OpenCLLIB::Remainder:
  1313. case OpenCLLIB::Rint:
  1314. case OpenCLLIB::Round:
  1315. case OpenCLLIB::Rsqrt:
  1316. case OpenCLLIB::Sin:
  1317. case OpenCLLIB::Sinh:
  1318. case OpenCLLIB::Sinpi:
  1319. case OpenCLLIB::Sqrt:
  1320. case OpenCLLIB::Tan:
  1321. case OpenCLLIB::Tanh:
  1322. case OpenCLLIB::Tanpi:
  1323. case OpenCLLIB::Tgamma:
  1324. case OpenCLLIB::Trunc:
  1325. case OpenCLLIB::Half_cos:
  1326. case OpenCLLIB::Half_divide:
  1327. case OpenCLLIB::Half_exp:
  1328. case OpenCLLIB::Half_exp2:
  1329. case OpenCLLIB::Half_exp10:
  1330. case OpenCLLIB::Half_log:
  1331. case OpenCLLIB::Half_log2:
  1332. case OpenCLLIB::Half_log10:
  1333. case OpenCLLIB::Half_powr:
  1334. case OpenCLLIB::Half_recip:
  1335. case OpenCLLIB::Half_rsqrt:
  1336. case OpenCLLIB::Half_sin:
  1337. case OpenCLLIB::Half_sqrt:
  1338. case OpenCLLIB::Half_tan:
  1339. case OpenCLLIB::Native_cos:
  1340. case OpenCLLIB::Native_divide:
  1341. case OpenCLLIB::Native_exp:
  1342. case OpenCLLIB::Native_exp2:
  1343. case OpenCLLIB::Native_exp10:
  1344. case OpenCLLIB::Native_log:
  1345. case OpenCLLIB::Native_log2:
  1346. case OpenCLLIB::Native_log10:
  1347. case OpenCLLIB::Native_powr:
  1348. case OpenCLLIB::Native_recip:
  1349. case OpenCLLIB::Native_rsqrt:
  1350. case OpenCLLIB::Native_sin:
  1351. case OpenCLLIB::Native_sqrt:
  1352. case OpenCLLIB::Native_tan:
  1353. case OpenCLLIB::FClamp:
  1354. case OpenCLLIB::Degrees:
  1355. case OpenCLLIB::FMax_common:
  1356. case OpenCLLIB::FMin_common:
  1357. case OpenCLLIB::Mix:
  1358. case OpenCLLIB::Radians:
  1359. case OpenCLLIB::Step:
  1360. case OpenCLLIB::Smoothstep:
  1361. case OpenCLLIB::Sign: {
  1362. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1363. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1364. << ext_inst_name() << ": "
  1365. << "expected Result Type to be a float scalar or vector type";
  1366. }
  1367. const uint32_t num_components = _.GetDimension(result_type);
  1368. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1369. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1370. << ext_inst_name() << ": "
  1371. << "expected Result Type to be a scalar or a vector with 2, "
  1372. "3, 4, 8 or 16 components";
  1373. }
  1374. for (uint32_t operand_index = 4; operand_index < num_operands;
  1375. ++operand_index) {
  1376. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1377. if (result_type != operand_type) {
  1378. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1379. << ext_inst_name() << ": "
  1380. << "expected types of all operands to be equal to Result "
  1381. "Type";
  1382. }
  1383. }
  1384. break;
  1385. }
  1386. case OpenCLLIB::Fract:
  1387. case OpenCLLIB::Modf:
  1388. case OpenCLLIB::Sincos: {
  1389. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1390. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1391. << ext_inst_name() << ": "
  1392. << "expected Result Type to be a float scalar or vector type";
  1393. }
  1394. const uint32_t num_components = _.GetDimension(result_type);
  1395. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1396. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1397. << ext_inst_name() << ": "
  1398. << "expected Result Type to be a scalar or a vector with 2, "
  1399. "3, 4, 8 or 16 components";
  1400. }
  1401. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1402. if (result_type != x_type) {
  1403. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1404. << ext_inst_name() << ": "
  1405. << "expected type of operand X to be equal to Result Type";
  1406. }
  1407. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  1408. uint32_t p_storage_class = 0;
  1409. uint32_t p_data_type = 0;
  1410. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1411. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1412. << ext_inst_name() << ": "
  1413. << "expected the last operand to be a pointer";
  1414. }
  1415. if (p_storage_class != SpvStorageClassGeneric &&
  1416. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1417. p_storage_class != SpvStorageClassWorkgroup &&
  1418. p_storage_class != SpvStorageClassFunction) {
  1419. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1420. << ext_inst_name() << ": "
  1421. << "expected storage class of the pointer to be Generic, "
  1422. "CrossWorkgroup, Workgroup or Function";
  1423. }
  1424. if (result_type != p_data_type) {
  1425. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1426. << ext_inst_name() << ": "
  1427. << "expected data type of the pointer to be equal to Result "
  1428. "Type";
  1429. }
  1430. break;
  1431. }
  1432. case OpenCLLIB::Frexp:
  1433. case OpenCLLIB::Lgamma_r:
  1434. case OpenCLLIB::Remquo: {
  1435. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1436. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1437. << ext_inst_name() << ": "
  1438. << "expected Result Type to be a float scalar or vector type";
  1439. }
  1440. const uint32_t num_components = _.GetDimension(result_type);
  1441. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1442. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1443. << ext_inst_name() << ": "
  1444. << "expected Result Type to be a scalar or a vector with 2, "
  1445. "3, 4, 8 or 16 components";
  1446. }
  1447. uint32_t operand_index = 4;
  1448. const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
  1449. if (result_type != x_type) {
  1450. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1451. << ext_inst_name() << ": "
  1452. << "expected type of operand X to be equal to Result Type";
  1453. }
  1454. if (ext_inst_key == OpenCLLIB::Remquo) {
  1455. const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
  1456. if (result_type != y_type) {
  1457. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1458. << ext_inst_name() << ": "
  1459. << "expected type of operand Y to be equal to Result Type";
  1460. }
  1461. }
  1462. const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++);
  1463. uint32_t p_storage_class = 0;
  1464. uint32_t p_data_type = 0;
  1465. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1466. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1467. << ext_inst_name() << ": "
  1468. << "expected the last operand to be a pointer";
  1469. }
  1470. if (p_storage_class != SpvStorageClassGeneric &&
  1471. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1472. p_storage_class != SpvStorageClassWorkgroup &&
  1473. p_storage_class != SpvStorageClassFunction) {
  1474. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1475. << ext_inst_name() << ": "
  1476. << "expected storage class of the pointer to be Generic, "
  1477. "CrossWorkgroup, Workgroup or Function";
  1478. }
  1479. if (!_.IsIntScalarOrVectorType(p_data_type) ||
  1480. _.GetBitWidth(p_data_type) != 32) {
  1481. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1482. << ext_inst_name() << ": "
  1483. << "expected data type of the pointer to be a 32-bit int "
  1484. "scalar or vector type";
  1485. }
  1486. if (_.GetDimension(p_data_type) != num_components) {
  1487. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1488. << ext_inst_name() << ": "
  1489. << "expected data type of the pointer to have the same number "
  1490. "of components as Result Type";
  1491. }
  1492. break;
  1493. }
  1494. case OpenCLLIB::Ilogb: {
  1495. if (!_.IsIntScalarOrVectorType(result_type) ||
  1496. _.GetBitWidth(result_type) != 32) {
  1497. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1498. << ext_inst_name() << ": "
  1499. << "expected Result Type to be a 32-bit int scalar or vector "
  1500. "type";
  1501. }
  1502. const uint32_t num_components = _.GetDimension(result_type);
  1503. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1504. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1505. << ext_inst_name() << ": "
  1506. << "expected Result Type to be a scalar or a vector with 2, "
  1507. "3, 4, 8 or 16 components";
  1508. }
  1509. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1510. if (!_.IsFloatScalarOrVectorType(x_type)) {
  1511. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1512. << ext_inst_name() << ": "
  1513. << "expected operand X to be a float scalar or vector";
  1514. }
  1515. if (_.GetDimension(x_type) != num_components) {
  1516. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1517. << ext_inst_name() << ": "
  1518. << "expected operand X to have the same number of components "
  1519. "as Result Type";
  1520. }
  1521. break;
  1522. }
  1523. case OpenCLLIB::Ldexp:
  1524. case OpenCLLIB::Pown:
  1525. case OpenCLLIB::Rootn: {
  1526. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1527. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1528. << ext_inst_name() << ": "
  1529. << "expected Result Type to be a float scalar or vector type";
  1530. }
  1531. const uint32_t num_components = _.GetDimension(result_type);
  1532. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1533. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1534. << ext_inst_name() << ": "
  1535. << "expected Result Type to be a scalar or a vector with 2, "
  1536. "3, 4, 8 or 16 components";
  1537. }
  1538. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1539. if (result_type != x_type) {
  1540. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1541. << ext_inst_name() << ": "
  1542. << "expected type of operand X to be equal to Result Type";
  1543. }
  1544. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  1545. if (!_.IsIntScalarOrVectorType(exp_type) ||
  1546. _.GetBitWidth(exp_type) != 32) {
  1547. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1548. << ext_inst_name() << ": "
  1549. << "expected the exponent to be a 32-bit int scalar or vector";
  1550. }
  1551. if (_.GetDimension(exp_type) != num_components) {
  1552. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1553. << ext_inst_name() << ": "
  1554. << "expected the exponent to have the same number of "
  1555. "components as Result Type";
  1556. }
  1557. break;
  1558. }
  1559. case OpenCLLIB::Nan: {
  1560. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1561. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1562. << ext_inst_name() << ": "
  1563. << "expected Result Type to be a float scalar or vector type";
  1564. }
  1565. const uint32_t num_components = _.GetDimension(result_type);
  1566. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1567. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1568. << ext_inst_name() << ": "
  1569. << "expected Result Type to be a scalar or a vector with 2, "
  1570. "3, 4, 8 or 16 components";
  1571. }
  1572. const uint32_t nancode_type = _.GetOperandTypeId(inst, 4);
  1573. if (!_.IsIntScalarOrVectorType(nancode_type)) {
  1574. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1575. << ext_inst_name() << ": "
  1576. << "expected Nancode to be an int scalar or vector type";
  1577. }
  1578. if (_.GetDimension(nancode_type) != num_components) {
  1579. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1580. << ext_inst_name() << ": "
  1581. << "expected Nancode to have the same number of components as "
  1582. "Result Type";
  1583. }
  1584. if (_.GetBitWidth(result_type) != _.GetBitWidth(nancode_type)) {
  1585. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1586. << ext_inst_name() << ": "
  1587. << "expected Nancode to have the same bit width as Result "
  1588. "Type";
  1589. }
  1590. break;
  1591. }
  1592. case OpenCLLIB::SAbs:
  1593. case OpenCLLIB::SAbs_diff:
  1594. case OpenCLLIB::SAdd_sat:
  1595. case OpenCLLIB::UAdd_sat:
  1596. case OpenCLLIB::SHadd:
  1597. case OpenCLLIB::UHadd:
  1598. case OpenCLLIB::SRhadd:
  1599. case OpenCLLIB::URhadd:
  1600. case OpenCLLIB::SClamp:
  1601. case OpenCLLIB::UClamp:
  1602. case OpenCLLIB::Clz:
  1603. case OpenCLLIB::Ctz:
  1604. case OpenCLLIB::SMad_hi:
  1605. case OpenCLLIB::UMad_sat:
  1606. case OpenCLLIB::SMad_sat:
  1607. case OpenCLLIB::SMax:
  1608. case OpenCLLIB::UMax:
  1609. case OpenCLLIB::SMin:
  1610. case OpenCLLIB::UMin:
  1611. case OpenCLLIB::SMul_hi:
  1612. case OpenCLLIB::Rotate:
  1613. case OpenCLLIB::SSub_sat:
  1614. case OpenCLLIB::USub_sat:
  1615. case OpenCLLIB::Popcount:
  1616. case OpenCLLIB::UAbs:
  1617. case OpenCLLIB::UAbs_diff:
  1618. case OpenCLLIB::UMul_hi:
  1619. case OpenCLLIB::UMad_hi: {
  1620. if (!_.IsIntScalarOrVectorType(result_type)) {
  1621. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1622. << ext_inst_name() << ": "
  1623. << "expected Result Type to be an int scalar or vector type";
  1624. }
  1625. const uint32_t num_components = _.GetDimension(result_type);
  1626. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1627. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1628. << ext_inst_name() << ": "
  1629. << "expected Result Type to be a scalar or a vector with 2, "
  1630. "3, 4, 8 or 16 components";
  1631. }
  1632. for (uint32_t operand_index = 4; operand_index < num_operands;
  1633. ++operand_index) {
  1634. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1635. if (result_type != operand_type) {
  1636. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1637. << ext_inst_name() << ": "
  1638. << "expected types of all operands to be equal to Result "
  1639. "Type";
  1640. }
  1641. }
  1642. break;
  1643. }
  1644. case OpenCLLIB::U_Upsample:
  1645. case OpenCLLIB::S_Upsample: {
  1646. if (!_.IsIntScalarOrVectorType(result_type)) {
  1647. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1648. << ext_inst_name() << ": "
  1649. << "expected Result Type to be an int scalar or vector "
  1650. "type";
  1651. }
  1652. const uint32_t result_num_components = _.GetDimension(result_type);
  1653. if (result_num_components > 4 && result_num_components != 8 &&
  1654. result_num_components != 16) {
  1655. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1656. << ext_inst_name() << ": "
  1657. << "expected Result Type to be a scalar or a vector with 2, "
  1658. "3, 4, 8 or 16 components";
  1659. }
  1660. const uint32_t result_bit_width = _.GetBitWidth(result_type);
  1661. if (result_bit_width != 16 && result_bit_width != 32 &&
  1662. result_bit_width != 64) {
  1663. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1664. << ext_inst_name() << ": "
  1665. << "expected bit width of Result Type components to be 16, 32 "
  1666. "or 64";
  1667. }
  1668. const uint32_t hi_type = _.GetOperandTypeId(inst, 4);
  1669. const uint32_t lo_type = _.GetOperandTypeId(inst, 5);
  1670. if (hi_type != lo_type) {
  1671. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1672. << ext_inst_name() << ": "
  1673. << "expected Hi and Lo operands to have the same type";
  1674. }
  1675. if (result_num_components != _.GetDimension(hi_type)) {
  1676. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1677. << ext_inst_name() << ": "
  1678. << "expected Hi and Lo operands to have the same number of "
  1679. "components as Result Type";
  1680. }
  1681. if (result_bit_width != 2 * _.GetBitWidth(hi_type)) {
  1682. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1683. << ext_inst_name() << ": "
  1684. << "expected bit width of components of Hi and Lo operands to "
  1685. "be half of the bit width of components of Result Type";
  1686. }
  1687. break;
  1688. }
  1689. case OpenCLLIB::SMad24:
  1690. case OpenCLLIB::UMad24:
  1691. case OpenCLLIB::SMul24:
  1692. case OpenCLLIB::UMul24: {
  1693. if (!_.IsIntScalarOrVectorType(result_type) ||
  1694. _.GetBitWidth(result_type) != 32) {
  1695. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1696. << ext_inst_name() << ": "
  1697. << "expected Result Type to be a 32-bit int scalar or vector "
  1698. "type";
  1699. }
  1700. const uint32_t num_components = _.GetDimension(result_type);
  1701. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1702. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1703. << ext_inst_name() << ": "
  1704. << "expected Result Type to be a scalar or a vector with 2, "
  1705. "3, 4, 8 or 16 components";
  1706. }
  1707. for (uint32_t operand_index = 4; operand_index < num_operands;
  1708. ++operand_index) {
  1709. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1710. if (result_type != operand_type) {
  1711. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1712. << ext_inst_name() << ": "
  1713. << "expected types of all operands to be equal to Result "
  1714. "Type";
  1715. }
  1716. }
  1717. break;
  1718. }
  1719. case OpenCLLIB::Cross: {
  1720. if (!_.IsFloatVectorType(result_type)) {
  1721. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1722. << ext_inst_name() << ": "
  1723. << "expected Result Type to be a float vector type";
  1724. }
  1725. const uint32_t num_components = _.GetDimension(result_type);
  1726. if (num_components != 3 && num_components != 4) {
  1727. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1728. << ext_inst_name() << ": "
  1729. << "expected Result Type to have 3 or 4 components";
  1730. }
  1731. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1732. const uint32_t y_type = _.GetOperandTypeId(inst, 5);
  1733. if (x_type != result_type) {
  1734. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1735. << ext_inst_name() << ": "
  1736. << "expected operand X type to be equal to Result Type";
  1737. }
  1738. if (y_type != result_type) {
  1739. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1740. << ext_inst_name() << ": "
  1741. << "expected operand Y type to be equal to Result Type";
  1742. }
  1743. break;
  1744. }
  1745. case OpenCLLIB::Distance:
  1746. case OpenCLLIB::Fast_distance: {
  1747. if (!_.IsFloatScalarType(result_type)) {
  1748. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1749. << ext_inst_name() << ": "
  1750. << "expected Result Type to be a float scalar type";
  1751. }
  1752. const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
  1753. if (!_.IsFloatScalarOrVectorType(p0_type)) {
  1754. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1755. << ext_inst_name() << ": "
  1756. << "expected operand P0 to be of float scalar or vector type";
  1757. }
  1758. const uint32_t num_components = _.GetDimension(p0_type);
  1759. if (num_components > 4) {
  1760. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1761. << ext_inst_name() << ": "
  1762. << "expected operand P0 to have no more than 4 components";
  1763. }
  1764. if (result_type != _.GetComponentType(p0_type)) {
  1765. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1766. << ext_inst_name() << ": "
  1767. << "expected operand P0 component type to be equal to "
  1768. << "Result Type";
  1769. }
  1770. const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
  1771. if (p0_type != p1_type) {
  1772. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1773. << ext_inst_name() << ": "
  1774. << "expected operands P0 and P1 to be of the same type";
  1775. }
  1776. break;
  1777. }
  1778. case OpenCLLIB::Length:
  1779. case OpenCLLIB::Fast_length: {
  1780. if (!_.IsFloatScalarType(result_type)) {
  1781. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1782. << ext_inst_name() << ": "
  1783. << "expected Result Type to be a float scalar type";
  1784. }
  1785. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  1786. if (!_.IsFloatScalarOrVectorType(p_type)) {
  1787. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1788. << ext_inst_name() << ": "
  1789. << "expected operand P to be a float scalar or vector";
  1790. }
  1791. const uint32_t num_components = _.GetDimension(p_type);
  1792. if (num_components > 4) {
  1793. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1794. << ext_inst_name() << ": "
  1795. << "expected operand P to have no more than 4 components";
  1796. }
  1797. if (result_type != _.GetComponentType(p_type)) {
  1798. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1799. << ext_inst_name() << ": "
  1800. << "expected operand P component type to be equal to Result "
  1801. "Type";
  1802. }
  1803. break;
  1804. }
  1805. case OpenCLLIB::Normalize:
  1806. case OpenCLLIB::Fast_normalize: {
  1807. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1808. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1809. << ext_inst_name() << ": "
  1810. << "expected Result Type to be a float scalar or vector type";
  1811. }
  1812. const uint32_t num_components = _.GetDimension(result_type);
  1813. if (num_components > 4) {
  1814. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1815. << ext_inst_name() << ": "
  1816. << "expected Result Type to have no more than 4 components";
  1817. }
  1818. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  1819. if (p_type != result_type) {
  1820. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1821. << ext_inst_name() << ": "
  1822. << "expected operand P type to be equal to Result Type";
  1823. }
  1824. break;
  1825. }
  1826. case OpenCLLIB::Bitselect: {
  1827. if (!_.IsFloatScalarOrVectorType(result_type) &&
  1828. !_.IsIntScalarOrVectorType(result_type)) {
  1829. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1830. << ext_inst_name() << ": "
  1831. << "expected Result Type to be an int or float scalar or "
  1832. "vector type";
  1833. }
  1834. const uint32_t num_components = _.GetDimension(result_type);
  1835. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1836. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1837. << ext_inst_name() << ": "
  1838. << "expected Result Type to be a scalar or a vector with 2, "
  1839. "3, 4, 8 or 16 components";
  1840. }
  1841. for (uint32_t operand_index = 4; operand_index < num_operands;
  1842. ++operand_index) {
  1843. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1844. if (result_type != operand_type) {
  1845. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1846. << ext_inst_name() << ": "
  1847. << "expected types of all operands to be equal to Result "
  1848. "Type";
  1849. }
  1850. }
  1851. break;
  1852. }
  1853. case OpenCLLIB::Select: {
  1854. if (!_.IsFloatScalarOrVectorType(result_type) &&
  1855. !_.IsIntScalarOrVectorType(result_type)) {
  1856. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1857. << ext_inst_name() << ": "
  1858. << "expected Result Type to be an int or float scalar or "
  1859. "vector type";
  1860. }
  1861. const uint32_t num_components = _.GetDimension(result_type);
  1862. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1863. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1864. << ext_inst_name() << ": "
  1865. << "expected Result Type to be a scalar or a vector with 2, "
  1866. "3, 4, 8 or 16 components";
  1867. }
  1868. const uint32_t a_type = _.GetOperandTypeId(inst, 4);
  1869. const uint32_t b_type = _.GetOperandTypeId(inst, 5);
  1870. const uint32_t c_type = _.GetOperandTypeId(inst, 6);
  1871. if (result_type != a_type) {
  1872. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1873. << ext_inst_name() << ": "
  1874. << "expected operand A type to be equal to Result Type";
  1875. }
  1876. if (result_type != b_type) {
  1877. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1878. << ext_inst_name() << ": "
  1879. << "expected operand B type to be equal to Result Type";
  1880. }
  1881. if (!_.IsIntScalarOrVectorType(c_type)) {
  1882. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1883. << ext_inst_name() << ": "
  1884. << "expected operand C to be an int scalar or vector";
  1885. }
  1886. if (num_components != _.GetDimension(c_type)) {
  1887. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1888. << ext_inst_name() << ": "
  1889. << "expected operand C to have the same number of components "
  1890. "as Result Type";
  1891. }
  1892. if (_.GetBitWidth(result_type) != _.GetBitWidth(c_type)) {
  1893. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1894. << ext_inst_name() << ": "
  1895. << "expected operand C to have the same bit width as Result "
  1896. "Type";
  1897. }
  1898. break;
  1899. }
  1900. case OpenCLLIB::Vloadn: {
  1901. if (!_.IsFloatVectorType(result_type) &&
  1902. !_.IsIntVectorType(result_type)) {
  1903. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1904. << ext_inst_name() << ": "
  1905. << "expected Result Type to be an int or float vector type";
  1906. }
  1907. const uint32_t num_components = _.GetDimension(result_type);
  1908. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1909. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1910. << ext_inst_name() << ": "
  1911. << "expected Result Type to have 2, 3, 4, 8 or 16 components";
  1912. }
  1913. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  1914. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  1915. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  1916. if (!size_t_bit_width) {
  1917. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1918. << ext_inst_name()
  1919. << " can only be used with physical addressing models";
  1920. }
  1921. if (!_.IsIntScalarType(offset_type) ||
  1922. _.GetBitWidth(offset_type) != size_t_bit_width) {
  1923. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1924. << ext_inst_name() << ": "
  1925. << "expected operand Offset to be of type size_t ("
  1926. << size_t_bit_width
  1927. << "-bit integer for the addressing model used in the module)";
  1928. }
  1929. uint32_t p_storage_class = 0;
  1930. uint32_t p_data_type = 0;
  1931. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1932. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1933. << ext_inst_name() << ": "
  1934. << "expected operand P to be a pointer";
  1935. }
  1936. if (p_storage_class != SpvStorageClassUniformConstant &&
  1937. p_storage_class != SpvStorageClassGeneric &&
  1938. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1939. p_storage_class != SpvStorageClassWorkgroup &&
  1940. p_storage_class != SpvStorageClassFunction) {
  1941. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1942. << ext_inst_name() << ": "
  1943. << "expected operand P storage class to be UniformConstant, "
  1944. "Generic, CrossWorkgroup, Workgroup or Function";
  1945. }
  1946. if (_.GetComponentType(result_type) != p_data_type) {
  1947. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1948. << ext_inst_name() << ": "
  1949. << "expected operand P data type to be equal to component "
  1950. "type of Result Type";
  1951. }
  1952. const uint32_t n_value = inst->word(7);
  1953. if (num_components != n_value) {
  1954. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1955. << ext_inst_name() << ": "
  1956. << "expected literal N to be equal to the number of "
  1957. "components of Result Type";
  1958. }
  1959. break;
  1960. }
  1961. case OpenCLLIB::Vstoren: {
  1962. if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) {
  1963. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1964. << ext_inst_name() << ": expected Result Type to be void";
  1965. }
  1966. const uint32_t data_type = _.GetOperandTypeId(inst, 4);
  1967. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  1968. const uint32_t p_type = _.GetOperandTypeId(inst, 6);
  1969. if (!_.IsFloatVectorType(data_type) && !_.IsIntVectorType(data_type)) {
  1970. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1971. << ext_inst_name() << ": "
  1972. << "expected Data to be an int or float vector";
  1973. }
  1974. const uint32_t num_components = _.GetDimension(data_type);
  1975. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1976. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1977. << ext_inst_name() << ": "
  1978. << "expected Data to have 2, 3, 4, 8 or 16 components";
  1979. }
  1980. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  1981. if (!size_t_bit_width) {
  1982. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1983. << ext_inst_name()
  1984. << " can only be used with physical addressing models";
  1985. }
  1986. if (!_.IsIntScalarType(offset_type) ||
  1987. _.GetBitWidth(offset_type) != size_t_bit_width) {
  1988. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1989. << ext_inst_name() << ": "
  1990. << "expected operand Offset to be of type size_t ("
  1991. << size_t_bit_width
  1992. << "-bit integer for the addressing model used in the module)";
  1993. }
  1994. uint32_t p_storage_class = 0;
  1995. uint32_t p_data_type = 0;
  1996. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1997. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1998. << ext_inst_name() << ": "
  1999. << "expected operand P to be a pointer";
  2000. }
  2001. if (p_storage_class != SpvStorageClassGeneric &&
  2002. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2003. p_storage_class != SpvStorageClassWorkgroup &&
  2004. p_storage_class != SpvStorageClassFunction) {
  2005. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2006. << ext_inst_name() << ": "
  2007. << "expected operand P storage class to be Generic, "
  2008. "CrossWorkgroup, Workgroup or Function";
  2009. }
  2010. if (_.GetComponentType(data_type) != p_data_type) {
  2011. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2012. << ext_inst_name() << ": "
  2013. << "expected operand P data type to be equal to the type of "
  2014. "operand Data components";
  2015. }
  2016. break;
  2017. }
  2018. case OpenCLLIB::Vload_half: {
  2019. if (!_.IsFloatScalarType(result_type)) {
  2020. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2021. << ext_inst_name() << ": "
  2022. << "expected Result Type to be a float scalar type";
  2023. }
  2024. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2025. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2026. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2027. if (!size_t_bit_width) {
  2028. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2029. << ext_inst_name()
  2030. << " can only be used with physical addressing models";
  2031. }
  2032. if (!_.IsIntScalarType(offset_type) ||
  2033. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2034. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2035. << ext_inst_name() << ": "
  2036. << "expected operand Offset to be of type size_t ("
  2037. << size_t_bit_width
  2038. << "-bit integer for the addressing model used in the module)";
  2039. }
  2040. uint32_t p_storage_class = 0;
  2041. uint32_t p_data_type = 0;
  2042. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2043. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2044. << ext_inst_name() << ": "
  2045. << "expected operand P to be a pointer";
  2046. }
  2047. if (p_storage_class != SpvStorageClassUniformConstant &&
  2048. p_storage_class != SpvStorageClassGeneric &&
  2049. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2050. p_storage_class != SpvStorageClassWorkgroup &&
  2051. p_storage_class != SpvStorageClassFunction) {
  2052. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2053. << ext_inst_name() << ": "
  2054. << "expected operand P storage class to be UniformConstant, "
  2055. "Generic, CrossWorkgroup, Workgroup or Function";
  2056. }
  2057. if (!_.IsFloatScalarType(p_data_type) ||
  2058. _.GetBitWidth(p_data_type) != 16) {
  2059. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2060. << ext_inst_name() << ": "
  2061. << "expected operand P data type to be 16-bit float scalar";
  2062. }
  2063. break;
  2064. }
  2065. case OpenCLLIB::Vload_halfn:
  2066. case OpenCLLIB::Vloada_halfn: {
  2067. if (!_.IsFloatVectorType(result_type)) {
  2068. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2069. << ext_inst_name() << ": "
  2070. << "expected Result Type to be a float vector type";
  2071. }
  2072. const uint32_t num_components = _.GetDimension(result_type);
  2073. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2074. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2075. << ext_inst_name() << ": "
  2076. << "expected Result Type to have 2, 3, 4, 8 or 16 components";
  2077. }
  2078. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2079. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2080. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2081. if (!size_t_bit_width) {
  2082. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2083. << ext_inst_name()
  2084. << " can only be used with physical addressing models";
  2085. }
  2086. if (!_.IsIntScalarType(offset_type) ||
  2087. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2088. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2089. << ext_inst_name() << ": "
  2090. << "expected operand Offset to be of type size_t ("
  2091. << size_t_bit_width
  2092. << "-bit integer for the addressing model used in the module)";
  2093. }
  2094. uint32_t p_storage_class = 0;
  2095. uint32_t p_data_type = 0;
  2096. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2097. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2098. << ext_inst_name() << ": "
  2099. << "expected operand P to be a pointer";
  2100. }
  2101. if (p_storage_class != SpvStorageClassUniformConstant &&
  2102. p_storage_class != SpvStorageClassGeneric &&
  2103. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2104. p_storage_class != SpvStorageClassWorkgroup &&
  2105. p_storage_class != SpvStorageClassFunction) {
  2106. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2107. << ext_inst_name() << ": "
  2108. << "expected operand P storage class to be UniformConstant, "
  2109. "Generic, CrossWorkgroup, Workgroup or Function";
  2110. }
  2111. if (!_.IsFloatScalarType(p_data_type) ||
  2112. _.GetBitWidth(p_data_type) != 16) {
  2113. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2114. << ext_inst_name() << ": "
  2115. << "expected operand P data type to be 16-bit float scalar";
  2116. }
  2117. const uint32_t n_value = inst->word(7);
  2118. if (num_components != n_value) {
  2119. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2120. << ext_inst_name() << ": "
  2121. << "expected literal N to be equal to the number of "
  2122. "components of Result Type";
  2123. }
  2124. break;
  2125. }
  2126. case OpenCLLIB::Vstore_half:
  2127. case OpenCLLIB::Vstore_half_r:
  2128. case OpenCLLIB::Vstore_halfn:
  2129. case OpenCLLIB::Vstore_halfn_r:
  2130. case OpenCLLIB::Vstorea_halfn:
  2131. case OpenCLLIB::Vstorea_halfn_r: {
  2132. if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) {
  2133. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2134. << ext_inst_name() << ": expected Result Type to be void";
  2135. }
  2136. const uint32_t data_type = _.GetOperandTypeId(inst, 4);
  2137. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  2138. const uint32_t p_type = _.GetOperandTypeId(inst, 6);
  2139. const uint32_t data_type_bit_width = _.GetBitWidth(data_type);
  2140. if (ext_inst_key == OpenCLLIB::Vstore_half ||
  2141. ext_inst_key == OpenCLLIB::Vstore_half_r) {
  2142. if (!_.IsFloatScalarType(data_type) ||
  2143. (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  2144. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2145. << ext_inst_name() << ": "
  2146. << "expected Data to be a 32 or 64-bit float scalar";
  2147. }
  2148. } else {
  2149. if (!_.IsFloatVectorType(data_type) ||
  2150. (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  2151. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2152. << ext_inst_name() << ": "
  2153. << "expected Data to be a 32 or 64-bit float vector";
  2154. }
  2155. const uint32_t num_components = _.GetDimension(data_type);
  2156. if (num_components > 4 && num_components != 8 &&
  2157. num_components != 16) {
  2158. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2159. << ext_inst_name() << ": "
  2160. << "expected Data to have 2, 3, 4, 8 or 16 components";
  2161. }
  2162. }
  2163. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2164. if (!size_t_bit_width) {
  2165. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2166. << ext_inst_name()
  2167. << " can only be used with physical addressing models";
  2168. }
  2169. if (!_.IsIntScalarType(offset_type) ||
  2170. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2171. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2172. << ext_inst_name() << ": "
  2173. << "expected operand Offset to be of type size_t ("
  2174. << size_t_bit_width
  2175. << "-bit integer for the addressing model used in the module)";
  2176. }
  2177. uint32_t p_storage_class = 0;
  2178. uint32_t p_data_type = 0;
  2179. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2180. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2181. << ext_inst_name() << ": "
  2182. << "expected operand P to be a pointer";
  2183. }
  2184. if (p_storage_class != SpvStorageClassGeneric &&
  2185. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2186. p_storage_class != SpvStorageClassWorkgroup &&
  2187. p_storage_class != SpvStorageClassFunction) {
  2188. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2189. << ext_inst_name() << ": "
  2190. << "expected operand P storage class to be Generic, "
  2191. "CrossWorkgroup, Workgroup or Function";
  2192. }
  2193. if (!_.IsFloatScalarType(p_data_type) ||
  2194. _.GetBitWidth(p_data_type) != 16) {
  2195. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2196. << ext_inst_name() << ": "
  2197. << "expected operand P data type to be 16-bit float scalar";
  2198. }
  2199. // Rounding mode enum is checked by assembler.
  2200. break;
  2201. }
  2202. case OpenCLLIB::Shuffle:
  2203. case OpenCLLIB::Shuffle2: {
  2204. if (!_.IsFloatVectorType(result_type) &&
  2205. !_.IsIntVectorType(result_type)) {
  2206. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2207. << ext_inst_name() << ": "
  2208. << "expected Result Type to be an int or float vector type";
  2209. }
  2210. const uint32_t result_num_components = _.GetDimension(result_type);
  2211. if (result_num_components != 2 && result_num_components != 4 &&
  2212. result_num_components != 8 && result_num_components != 16) {
  2213. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2214. << ext_inst_name() << ": "
  2215. << "expected Result Type to have 2, 4, 8 or 16 components";
  2216. }
  2217. uint32_t operand_index = 4;
  2218. const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
  2219. if (ext_inst_key == OpenCLLIB::Shuffle2) {
  2220. const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
  2221. if (x_type != y_type) {
  2222. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2223. << ext_inst_name() << ": "
  2224. << "expected operands X and Y to be of the same type";
  2225. }
  2226. }
  2227. const uint32_t shuffle_mask_type =
  2228. _.GetOperandTypeId(inst, operand_index++);
  2229. if (!_.IsFloatVectorType(x_type) && !_.IsIntVectorType(x_type)) {
  2230. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2231. << ext_inst_name() << ": "
  2232. << "expected operand X to be an int or float vector";
  2233. }
  2234. const uint32_t x_num_components = _.GetDimension(x_type);
  2235. if (x_num_components != 2 && x_num_components != 4 &&
  2236. x_num_components != 8 && x_num_components != 16) {
  2237. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2238. << ext_inst_name() << ": "
  2239. << "expected operand X to have 2, 4, 8 or 16 components";
  2240. }
  2241. const uint32_t result_component_type = _.GetComponentType(result_type);
  2242. if (result_component_type != _.GetComponentType(x_type)) {
  2243. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2244. << ext_inst_name() << ": "
  2245. << "expected operand X and Result Type to have equal "
  2246. "component types";
  2247. }
  2248. if (!_.IsIntVectorType(shuffle_mask_type)) {
  2249. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2250. << ext_inst_name() << ": "
  2251. << "expected operand Shuffle Mask to be an int vector";
  2252. }
  2253. if (result_num_components != _.GetDimension(shuffle_mask_type)) {
  2254. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2255. << ext_inst_name() << ": "
  2256. << "expected operand Shuffle Mask to have the same number of "
  2257. "components as Result Type";
  2258. }
  2259. if (_.GetBitWidth(result_component_type) !=
  2260. _.GetBitWidth(shuffle_mask_type)) {
  2261. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2262. << ext_inst_name() << ": "
  2263. << "expected operand Shuffle Mask components to have the same "
  2264. "bit width as Result Type components";
  2265. }
  2266. break;
  2267. }
  2268. case OpenCLLIB::Printf: {
  2269. if (!_.IsIntScalarType(result_type) ||
  2270. _.GetBitWidth(result_type) != 32) {
  2271. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2272. << ext_inst_name() << ": "
  2273. << "expected Result Type to be a 32-bit int type";
  2274. }
  2275. const uint32_t format_type = _.GetOperandTypeId(inst, 4);
  2276. uint32_t format_storage_class = 0;
  2277. uint32_t format_data_type = 0;
  2278. if (!_.GetPointerTypeInfo(format_type, &format_data_type,
  2279. &format_storage_class)) {
  2280. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2281. << ext_inst_name() << ": "
  2282. << "expected operand Format to be a pointer";
  2283. }
  2284. if (format_storage_class != SpvStorageClassUniformConstant) {
  2285. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2286. << ext_inst_name() << ": "
  2287. << "expected Format storage class to be UniformConstant";
  2288. }
  2289. if (!_.IsIntScalarType(format_data_type) ||
  2290. _.GetBitWidth(format_data_type) != 8) {
  2291. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2292. << ext_inst_name() << ": "
  2293. << "expected Format data type to be 8-bit int";
  2294. }
  2295. break;
  2296. }
  2297. case OpenCLLIB::Prefetch: {
  2298. if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) {
  2299. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2300. << ext_inst_name() << ": expected Result Type to be void";
  2301. }
  2302. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  2303. const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5);
  2304. uint32_t p_storage_class = 0;
  2305. uint32_t p_data_type = 0;
  2306. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2307. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2308. << ext_inst_name() << ": "
  2309. << "expected operand Ptr to be a pointer";
  2310. }
  2311. if (p_storage_class != SpvStorageClassCrossWorkgroup) {
  2312. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2313. << ext_inst_name() << ": "
  2314. << "expected operand Ptr storage class to be CrossWorkgroup";
  2315. }
  2316. if (!_.IsFloatScalarOrVectorType(p_data_type) &&
  2317. !_.IsIntScalarOrVectorType(p_data_type)) {
  2318. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2319. << ext_inst_name() << ": "
  2320. << "expected Ptr data type to be int or float scalar or "
  2321. "vector";
  2322. }
  2323. const uint32_t num_components = _.GetDimension(p_data_type);
  2324. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2325. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2326. << ext_inst_name() << ": "
  2327. << "expected Result Type to be a scalar or a vector with 2, "
  2328. "3, 4, 8 or 16 components";
  2329. }
  2330. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2331. if (!size_t_bit_width) {
  2332. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2333. << ext_inst_name()
  2334. << " can only be used with physical addressing models";
  2335. }
  2336. if (!_.IsIntScalarType(num_elements_type) ||
  2337. _.GetBitWidth(num_elements_type) != size_t_bit_width) {
  2338. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2339. << ext_inst_name() << ": "
  2340. << "expected operand Num Elements to be of type size_t ("
  2341. << size_t_bit_width
  2342. << "-bit integer for the addressing model used in the module)";
  2343. }
  2344. break;
  2345. }
  2346. }
  2347. } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  2348. if (!_.IsVoidType(result_type)) {
  2349. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2350. << ext_inst_name() << ": "
  2351. << "expected result type must be a result id of "
  2352. << "OpTypeVoid";
  2353. }
  2354. auto num_words = inst->words().size();
  2355. const OpenCLDebugInfo100Instructions ext_inst_key =
  2356. OpenCLDebugInfo100Instructions(ext_inst_index);
  2357. switch (ext_inst_key) {
  2358. case OpenCLDebugInfo100DebugInfoNone:
  2359. case OpenCLDebugInfo100DebugNoScope:
  2360. case OpenCLDebugInfo100DebugOperation:
  2361. // The binary parser validates the opcode for DebugInfoNone,
  2362. // DebugNoScope, DebugOperation, and the literal values don't need
  2363. // further checks.
  2364. break;
  2365. case OpenCLDebugInfo100DebugCompilationUnit: {
  2366. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2367. break;
  2368. }
  2369. case OpenCLDebugInfo100DebugSource: {
  2370. CHECK_OPERAND("File", SpvOpString, 5);
  2371. if (num_words == 7) CHECK_OPERAND("Text", SpvOpString, 6);
  2372. break;
  2373. }
  2374. case OpenCLDebugInfo100DebugTypeBasic: {
  2375. CHECK_OPERAND("Name", SpvOpString, 5);
  2376. CHECK_OPERAND("Size", SpvOpConstant, 6);
  2377. // "Encoding" param is already validated by the binary parsing stage.
  2378. break;
  2379. }
  2380. case OpenCLDebugInfo100DebugTypePointer:
  2381. case OpenCLDebugInfo100DebugTypeQualifier: {
  2382. auto validate_base_type =
  2383. ValidateOperandBaseType(_, inst, 5, ext_inst_name);
  2384. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2385. break;
  2386. }
  2387. case OpenCLDebugInfo100DebugTypeVector: {
  2388. auto validate_base_type =
  2389. ValidateOperandBaseType(_, inst, 5, ext_inst_name);
  2390. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2391. uint32_t component_count = inst->word(6);
  2392. if (!component_count || component_count > 4) {
  2393. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2394. << ext_inst_name() << ": Component Count must be positive "
  2395. << "integer less than or equal to 4";
  2396. }
  2397. break;
  2398. }
  2399. case OpenCLDebugInfo100DebugTypeArray: {
  2400. auto validate_base_type = ValidateOperandDebugType(
  2401. _, "Base Type", inst, 5, ext_inst_name, false);
  2402. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2403. for (uint32_t i = 6; i < num_words; ++i) {
  2404. bool invalid = false;
  2405. auto* component_count = _.FindDef(inst->word(i));
  2406. if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) {
  2407. // TODO: We need a spec discussion for the bindless array.
  2408. if (!component_count->word(3)) {
  2409. invalid = true;
  2410. }
  2411. } else if (component_count->words().size() > 6 &&
  2412. (OpenCLDebugInfo100Instructions(component_count->word(
  2413. 4)) == OpenCLDebugInfo100DebugLocalVariable ||
  2414. OpenCLDebugInfo100Instructions(component_count->word(
  2415. 4)) == OpenCLDebugInfo100DebugGlobalVariable)) {
  2416. auto* component_count_type = _.FindDef(component_count->word(6));
  2417. if (component_count_type->words().size() > 7) {
  2418. if (OpenCLDebugInfo100Instructions(component_count_type->word(
  2419. 4)) != OpenCLDebugInfo100DebugTypeBasic ||
  2420. OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
  2421. component_count_type->word(7)) !=
  2422. OpenCLDebugInfo100Unsigned) {
  2423. invalid = true;
  2424. } else {
  2425. // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable
  2426. // must have Unsigned encoding and 32 or 64 as its size in bits.
  2427. Instruction* size_in_bits =
  2428. _.FindDef(component_count_type->word(6));
  2429. if (!_.IsIntScalarType(size_in_bits->type_id()) ||
  2430. (size_in_bits->word(3) != 32 &&
  2431. size_in_bits->word(3) != 64)) {
  2432. invalid = true;
  2433. }
  2434. }
  2435. } else {
  2436. invalid = true;
  2437. }
  2438. } else {
  2439. invalid = true;
  2440. }
  2441. if (invalid) {
  2442. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2443. << ext_inst_name() << ": Component Count must be "
  2444. << "OpConstant with a 32- or 64-bits integer scalar type or "
  2445. << "DebugGlobalVariable or DebugLocalVariable with a 32- or "
  2446. << "64-bits unsigned integer scalar type";
  2447. }
  2448. }
  2449. break;
  2450. }
  2451. case OpenCLDebugInfo100DebugTypedef: {
  2452. CHECK_OPERAND("Name", SpvOpString, 5);
  2453. auto validate_base_type =
  2454. ValidateOperandBaseType(_, inst, 6, ext_inst_name);
  2455. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2456. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2457. auto validate_parent =
  2458. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2459. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2460. break;
  2461. }
  2462. case OpenCLDebugInfo100DebugTypeFunction: {
  2463. auto* return_type = _.FindDef(inst->word(6));
  2464. // TODO: We need a spec discussion that we have to allow return and
  2465. // parameter types of a DebugTypeFunction to have template parameter.
  2466. if (return_type->opcode() != SpvOpTypeVoid) {
  2467. auto validate_return = ValidateOperandDebugType(
  2468. _, "Return Type", inst, 6, ext_inst_name, true);
  2469. if (validate_return != SPV_SUCCESS) return validate_return;
  2470. }
  2471. for (uint32_t word_index = 7; word_index < num_words; ++word_index) {
  2472. auto validate_param = ValidateOperandDebugType(
  2473. _, "Parameter Types", inst, word_index, ext_inst_name, true);
  2474. if (validate_param != SPV_SUCCESS) return validate_param;
  2475. }
  2476. break;
  2477. }
  2478. case OpenCLDebugInfo100DebugTypeEnum: {
  2479. CHECK_OPERAND("Name", SpvOpString, 5);
  2480. if (!DoesDebugInfoOperandMatchExpectation(
  2481. _,
  2482. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2483. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2484. },
  2485. inst, 6)) {
  2486. auto validate_underlying_type = ValidateOperandDebugType(
  2487. _, "Underlying Types", inst, 6, ext_inst_name, false);
  2488. if (validate_underlying_type != SPV_SUCCESS)
  2489. return validate_underlying_type;
  2490. }
  2491. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2492. auto validate_parent =
  2493. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2494. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2495. CHECK_OPERAND("Size", SpvOpConstant, 11);
  2496. auto* size = _.FindDef(inst->word(11));
  2497. if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) {
  2498. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2499. << ext_inst_name() << ": expected operand Size is a "
  2500. << "positive integer";
  2501. }
  2502. for (uint32_t word_index = 13; word_index + 1 < num_words;
  2503. word_index += 2) {
  2504. CHECK_OPERAND("Value", SpvOpConstant, word_index);
  2505. CHECK_OPERAND("Name", SpvOpString, word_index + 1);
  2506. }
  2507. break;
  2508. }
  2509. case OpenCLDebugInfo100DebugTypeComposite: {
  2510. CHECK_OPERAND("Name", SpvOpString, 5);
  2511. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2512. auto validate_parent =
  2513. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2514. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2515. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2516. if (!DoesDebugInfoOperandMatchExpectation(
  2517. _,
  2518. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2519. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2520. },
  2521. inst, 12)) {
  2522. CHECK_OPERAND("Size", SpvOpConstant, 12);
  2523. }
  2524. for (uint32_t word_index = 14; word_index < num_words; ++word_index) {
  2525. if (!DoesDebugInfoOperandMatchExpectation(
  2526. _,
  2527. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2528. return dbg_inst == OpenCLDebugInfo100DebugTypeMember ||
  2529. dbg_inst == OpenCLDebugInfo100DebugFunction ||
  2530. dbg_inst == OpenCLDebugInfo100DebugTypeInheritance;
  2531. },
  2532. inst, word_index)) {
  2533. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2534. << ext_inst_name() << ": "
  2535. << "expected operand Members "
  2536. << "must be DebugTypeMember, DebugFunction, or "
  2537. "DebugTypeInheritance";
  2538. }
  2539. }
  2540. break;
  2541. }
  2542. case OpenCLDebugInfo100DebugTypeMember: {
  2543. CHECK_OPERAND("Name", SpvOpString, 5);
  2544. // TODO: We need a spec discussion that we have to allow member types
  2545. // to have template parameter.
  2546. auto validate_type =
  2547. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
  2548. if (validate_type != SPV_SUCCESS) return validate_type;
  2549. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2550. CHECK_DEBUG_OPERAND("Parent", OpenCLDebugInfo100DebugTypeComposite, 10);
  2551. CHECK_OPERAND("Offset", SpvOpConstant, 11);
  2552. CHECK_OPERAND("Size", SpvOpConstant, 12);
  2553. if (num_words == 15) CHECK_OPERAND("Value", SpvOpConstant, 14);
  2554. break;
  2555. }
  2556. case OpenCLDebugInfo100DebugTypeInheritance: {
  2557. CHECK_DEBUG_OPERAND("Child", OpenCLDebugInfo100DebugTypeComposite, 5);
  2558. auto* debug_inst = _.FindDef(inst->word(5));
  2559. auto composite_type =
  2560. OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
  2561. if (composite_type != OpenCLDebugInfo100Class &&
  2562. composite_type != OpenCLDebugInfo100Structure) {
  2563. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2564. << ext_inst_name() << ": "
  2565. << "expected operand Child must be class or struct debug type";
  2566. }
  2567. CHECK_DEBUG_OPERAND("Parent", OpenCLDebugInfo100DebugTypeComposite, 6);
  2568. debug_inst = _.FindDef(inst->word(6));
  2569. composite_type =
  2570. OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
  2571. if (composite_type != OpenCLDebugInfo100Class &&
  2572. composite_type != OpenCLDebugInfo100Structure) {
  2573. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2574. << ext_inst_name() << ": "
  2575. << "expected operand Parent must be class or struct debug "
  2576. "type";
  2577. }
  2578. CHECK_OPERAND("Offset", SpvOpConstant, 7);
  2579. CHECK_OPERAND("Size", SpvOpConstant, 8);
  2580. break;
  2581. }
  2582. case OpenCLDebugInfo100DebugFunction: {
  2583. CHECK_OPERAND("Name", SpvOpString, 5);
  2584. auto validate_type =
  2585. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
  2586. if (validate_type != SPV_SUCCESS) return validate_type;
  2587. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2588. auto validate_parent =
  2589. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2590. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2591. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2592. if (!DoesDebugInfoOperandMatchExpectation(
  2593. _,
  2594. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2595. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2596. },
  2597. inst, 14)) {
  2598. CHECK_OPERAND("Function", SpvOpFunction, 14);
  2599. }
  2600. if (num_words == 16) {
  2601. CHECK_DEBUG_OPERAND("Declaration",
  2602. OpenCLDebugInfo100DebugFunctionDeclaration, 15);
  2603. }
  2604. break;
  2605. }
  2606. case OpenCLDebugInfo100DebugFunctionDeclaration: {
  2607. CHECK_OPERAND("Name", SpvOpString, 5);
  2608. auto validate_type =
  2609. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
  2610. if (validate_type != SPV_SUCCESS) return validate_type;
  2611. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2612. auto validate_parent =
  2613. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2614. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2615. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2616. break;
  2617. }
  2618. case OpenCLDebugInfo100DebugLexicalBlock: {
  2619. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 5);
  2620. auto validate_parent =
  2621. ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name);
  2622. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2623. if (num_words == 10) CHECK_OPERAND("Name", SpvOpString, 9);
  2624. break;
  2625. }
  2626. case OpenCLDebugInfo100DebugScope: {
  2627. auto validate_scope =
  2628. ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name);
  2629. if (validate_scope != SPV_SUCCESS) return validate_scope;
  2630. if (num_words == 7) {
  2631. CHECK_DEBUG_OPERAND("Inlined At", OpenCLDebugInfo100DebugInlinedAt,
  2632. 6);
  2633. }
  2634. break;
  2635. }
  2636. case OpenCLDebugInfo100DebugLocalVariable: {
  2637. CHECK_OPERAND("Name", SpvOpString, 5);
  2638. // TODO: We need a spec discussion that we have to allow local variable
  2639. // types to have template parameter.
  2640. auto validate_type =
  2641. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
  2642. if (validate_type != SPV_SUCCESS) return validate_type;
  2643. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2644. auto validate_parent =
  2645. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2646. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2647. break;
  2648. }
  2649. case OpenCLDebugInfo100DebugDeclare: {
  2650. CHECK_DEBUG_OPERAND("Local Variable",
  2651. OpenCLDebugInfo100DebugLocalVariable, 5);
  2652. auto* operand = _.FindDef(inst->word(6));
  2653. if (operand->opcode() != SpvOpVariable &&
  2654. operand->opcode() != SpvOpFunctionParameter) {
  2655. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2656. << ext_inst_name() << ": "
  2657. << "expected operand Variable must be a result id of "
  2658. "OpVariable or OpFunctionParameter";
  2659. }
  2660. CHECK_DEBUG_OPERAND("Expression", OpenCLDebugInfo100DebugExpression, 7);
  2661. break;
  2662. }
  2663. case OpenCLDebugInfo100DebugExpression: {
  2664. for (uint32_t word_index = 5; word_index < num_words; ++word_index) {
  2665. CHECK_DEBUG_OPERAND("Operation", OpenCLDebugInfo100DebugOperation,
  2666. word_index);
  2667. }
  2668. break;
  2669. }
  2670. case OpenCLDebugInfo100DebugTypeTemplate: {
  2671. if (!DoesDebugInfoOperandMatchExpectation(
  2672. _,
  2673. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2674. return dbg_inst == OpenCLDebugInfo100DebugTypeComposite ||
  2675. dbg_inst == OpenCLDebugInfo100DebugFunction;
  2676. },
  2677. inst, 5)) {
  2678. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2679. << ext_inst_name() << ": "
  2680. << "expected operand Target must be DebugTypeComposite "
  2681. << "or DebugFunction";
  2682. }
  2683. for (uint32_t word_index = 6; word_index < num_words; ++word_index) {
  2684. if (!DoesDebugInfoOperandMatchExpectation(
  2685. _,
  2686. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2687. return dbg_inst ==
  2688. OpenCLDebugInfo100DebugTypeTemplateParameter ||
  2689. dbg_inst ==
  2690. OpenCLDebugInfo100DebugTypeTemplateTemplateParameter;
  2691. },
  2692. inst, word_index)) {
  2693. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2694. << ext_inst_name() << ": "
  2695. << "expected operand Parameters must be "
  2696. << "DebugTypeTemplateParameter or "
  2697. << "DebugTypeTemplateTemplateParameter";
  2698. }
  2699. }
  2700. break;
  2701. }
  2702. case OpenCLDebugInfo100DebugTypeTemplateParameter: {
  2703. CHECK_OPERAND("Name", SpvOpString, 5);
  2704. auto validate_actual_type = ValidateOperandDebugType(
  2705. _, "Actual Type", inst, 6, ext_inst_name, false);
  2706. if (validate_actual_type != SPV_SUCCESS) return validate_actual_type;
  2707. if (!DoesDebugInfoOperandMatchExpectation(
  2708. _,
  2709. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2710. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2711. },
  2712. inst, 7)) {
  2713. CHECK_OPERAND("Value", SpvOpConstant, 7);
  2714. }
  2715. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 8);
  2716. break;
  2717. }
  2718. case OpenCLDebugInfo100DebugGlobalVariable: {
  2719. CHECK_OPERAND("Name", SpvOpString, 5);
  2720. auto validate_type =
  2721. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
  2722. if (validate_type != SPV_SUCCESS) return validate_type;
  2723. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2724. auto validate_scope =
  2725. ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name);
  2726. if (validate_scope != SPV_SUCCESS) return validate_scope;
  2727. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2728. if (!DoesDebugInfoOperandMatchExpectation(
  2729. _,
  2730. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2731. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2732. },
  2733. inst, 12)) {
  2734. auto* operand = _.FindDef(inst->word(12));
  2735. if (operand->opcode() != SpvOpVariable &&
  2736. operand->opcode() != SpvOpConstant) {
  2737. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2738. << ext_inst_name() << ": "
  2739. << "expected operand Variable must be a result id of "
  2740. "OpVariable or OpConstant or DebugInfoNone";
  2741. }
  2742. }
  2743. if (num_words == 15) {
  2744. CHECK_DEBUG_OPERAND("Static Member Declaration",
  2745. OpenCLDebugInfo100DebugTypeMember, 14);
  2746. }
  2747. break;
  2748. }
  2749. case OpenCLDebugInfo100DebugInlinedAt: {
  2750. auto validate_scope =
  2751. ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name);
  2752. if (validate_scope != SPV_SUCCESS) return validate_scope;
  2753. if (num_words == 8) {
  2754. CHECK_DEBUG_OPERAND("Inlined", OpenCLDebugInfo100DebugInlinedAt, 7);
  2755. }
  2756. break;
  2757. }
  2758. case OpenCLDebugInfo100DebugValue: {
  2759. CHECK_DEBUG_OPERAND("Local Variable",
  2760. OpenCLDebugInfo100DebugLocalVariable, 5);
  2761. CHECK_DEBUG_OPERAND("Expression", OpenCLDebugInfo100DebugExpression, 7);
  2762. for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
  2763. // TODO: The following code simply checks if it is a const int scalar
  2764. // or a DebugLocalVariable or DebugGlobalVariable, but we have to
  2765. // check it using the same validation for Indexes of OpAccessChain.
  2766. if (!IsConstWithIntScalarType(_, inst, word_index) &&
  2767. !IsDebugVariableWithIntScalarType(_, inst, word_index)) {
  2768. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2769. << ext_inst_name() << ": expected operand Indexes is "
  2770. << "OpConstant, DebugGlobalVariable, or "
  2771. << "type is OpConstant with an integer scalar type";
  2772. }
  2773. }
  2774. break;
  2775. }
  2776. // TODO: Add validation rules for remaining cases as well.
  2777. case OpenCLDebugInfo100DebugTypePtrToMember:
  2778. case OpenCLDebugInfo100DebugTypeTemplateTemplateParameter:
  2779. case OpenCLDebugInfo100DebugTypeTemplateParameterPack:
  2780. case OpenCLDebugInfo100DebugLexicalBlockDiscriminator:
  2781. case OpenCLDebugInfo100DebugInlinedVariable:
  2782. case OpenCLDebugInfo100DebugMacroDef:
  2783. case OpenCLDebugInfo100DebugMacroUndef:
  2784. case OpenCLDebugInfo100DebugImportedEntity:
  2785. case OpenCLDebugInfo100DebugModuleINTEL:
  2786. break;
  2787. case OpenCLDebugInfo100InstructionsMax:
  2788. assert(0);
  2789. break;
  2790. }
  2791. } else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
  2792. auto import_inst = _.FindDef(inst->GetOperandAs<uint32_t>(2));
  2793. const std::string name(reinterpret_cast<const char*>(
  2794. import_inst->words().data() + import_inst->operands()[1].offset));
  2795. const std::string reflection = "NonSemantic.ClspvReflection.";
  2796. char* end_ptr;
  2797. auto version_string = name.substr(reflection.size());
  2798. if (version_string.empty()) {
  2799. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  2800. << "Missing NonSemantic.ClspvReflection import version";
  2801. }
  2802. uint32_t version = static_cast<uint32_t>(
  2803. std::strtoul(version_string.c_str(), &end_ptr, 10));
  2804. if (end_ptr && *end_ptr != '\0') {
  2805. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  2806. << "NonSemantic.ClspvReflection import does not encode the "
  2807. "version correctly";
  2808. }
  2809. if (version == 0 || version > NonSemanticClspvReflectionRevision) {
  2810. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  2811. << "Unknown NonSemantic.ClspvReflection import version";
  2812. }
  2813. return ValidateClspvReflectionInstruction(_, inst, version);
  2814. }
  2815. return SPV_SUCCESS;
  2816. }
  2817. spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) {
  2818. const SpvOp opcode = inst->opcode();
  2819. if (opcode == SpvOpExtension) return ValidateExtension(_, inst);
  2820. if (opcode == SpvOpExtInstImport) return ValidateExtInstImport(_, inst);
  2821. if (opcode == SpvOpExtInst) return ValidateExtInst(_, inst);
  2822. return SPV_SUCCESS;
  2823. }
  2824. } // namespace val
  2825. } // namespace spvtools