validate_extensions.cpp 122 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150
  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. const uint32_t interpolant_type = _.GetOperandTypeId(inst, 4);
  1200. uint32_t interpolant_storage_class = 0;
  1201. uint32_t interpolant_data_type = 0;
  1202. if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type,
  1203. &interpolant_storage_class)) {
  1204. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1205. << ext_inst_name() << ": "
  1206. << "expected Interpolant to be a pointer";
  1207. }
  1208. if (result_type != interpolant_data_type) {
  1209. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1210. << ext_inst_name() << ": "
  1211. << "expected Interpolant data type to be equal to Result Type";
  1212. }
  1213. if (interpolant_storage_class != SpvStorageClassInput) {
  1214. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1215. << ext_inst_name() << ": "
  1216. << "expected Interpolant storage class to be Input";
  1217. }
  1218. if (ext_inst_key == GLSLstd450InterpolateAtSample) {
  1219. const uint32_t sample_type = _.GetOperandTypeId(inst, 5);
  1220. if (!_.IsIntScalarType(sample_type) ||
  1221. _.GetBitWidth(sample_type) != 32) {
  1222. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1223. << ext_inst_name() << ": "
  1224. << "expected Sample to be 32-bit integer";
  1225. }
  1226. }
  1227. if (ext_inst_key == GLSLstd450InterpolateAtOffset) {
  1228. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  1229. if (!_.IsFloatVectorType(offset_type) ||
  1230. _.GetDimension(offset_type) != 2 ||
  1231. _.GetBitWidth(offset_type) != 32) {
  1232. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1233. << ext_inst_name() << ": "
  1234. << "expected Offset to be a vector of 2 32-bit floats";
  1235. }
  1236. }
  1237. _.function(inst->function()->id())
  1238. ->RegisterExecutionModelLimitation(
  1239. SpvExecutionModelFragment,
  1240. ext_inst_name() +
  1241. std::string(" requires Fragment execution model"));
  1242. break;
  1243. }
  1244. case GLSLstd450IMix: {
  1245. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1246. << "Extended instruction GLSLstd450IMix is not supported";
  1247. }
  1248. case GLSLstd450Bad: {
  1249. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1250. << "Encountered extended instruction GLSLstd450Bad";
  1251. }
  1252. case GLSLstd450Count: {
  1253. assert(0);
  1254. break;
  1255. }
  1256. }
  1257. } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_STD) {
  1258. const OpenCLLIB::Entrypoints ext_inst_key =
  1259. OpenCLLIB::Entrypoints(ext_inst_index);
  1260. switch (ext_inst_key) {
  1261. case OpenCLLIB::Acos:
  1262. case OpenCLLIB::Acosh:
  1263. case OpenCLLIB::Acospi:
  1264. case OpenCLLIB::Asin:
  1265. case OpenCLLIB::Asinh:
  1266. case OpenCLLIB::Asinpi:
  1267. case OpenCLLIB::Atan:
  1268. case OpenCLLIB::Atan2:
  1269. case OpenCLLIB::Atanh:
  1270. case OpenCLLIB::Atanpi:
  1271. case OpenCLLIB::Atan2pi:
  1272. case OpenCLLIB::Cbrt:
  1273. case OpenCLLIB::Ceil:
  1274. case OpenCLLIB::Copysign:
  1275. case OpenCLLIB::Cos:
  1276. case OpenCLLIB::Cosh:
  1277. case OpenCLLIB::Cospi:
  1278. case OpenCLLIB::Erfc:
  1279. case OpenCLLIB::Erf:
  1280. case OpenCLLIB::Exp:
  1281. case OpenCLLIB::Exp2:
  1282. case OpenCLLIB::Exp10:
  1283. case OpenCLLIB::Expm1:
  1284. case OpenCLLIB::Fabs:
  1285. case OpenCLLIB::Fdim:
  1286. case OpenCLLIB::Floor:
  1287. case OpenCLLIB::Fma:
  1288. case OpenCLLIB::Fmax:
  1289. case OpenCLLIB::Fmin:
  1290. case OpenCLLIB::Fmod:
  1291. case OpenCLLIB::Hypot:
  1292. case OpenCLLIB::Lgamma:
  1293. case OpenCLLIB::Log:
  1294. case OpenCLLIB::Log2:
  1295. case OpenCLLIB::Log10:
  1296. case OpenCLLIB::Log1p:
  1297. case OpenCLLIB::Logb:
  1298. case OpenCLLIB::Mad:
  1299. case OpenCLLIB::Maxmag:
  1300. case OpenCLLIB::Minmag:
  1301. case OpenCLLIB::Nextafter:
  1302. case OpenCLLIB::Pow:
  1303. case OpenCLLIB::Powr:
  1304. case OpenCLLIB::Remainder:
  1305. case OpenCLLIB::Rint:
  1306. case OpenCLLIB::Round:
  1307. case OpenCLLIB::Rsqrt:
  1308. case OpenCLLIB::Sin:
  1309. case OpenCLLIB::Sinh:
  1310. case OpenCLLIB::Sinpi:
  1311. case OpenCLLIB::Sqrt:
  1312. case OpenCLLIB::Tan:
  1313. case OpenCLLIB::Tanh:
  1314. case OpenCLLIB::Tanpi:
  1315. case OpenCLLIB::Tgamma:
  1316. case OpenCLLIB::Trunc:
  1317. case OpenCLLIB::Half_cos:
  1318. case OpenCLLIB::Half_divide:
  1319. case OpenCLLIB::Half_exp:
  1320. case OpenCLLIB::Half_exp2:
  1321. case OpenCLLIB::Half_exp10:
  1322. case OpenCLLIB::Half_log:
  1323. case OpenCLLIB::Half_log2:
  1324. case OpenCLLIB::Half_log10:
  1325. case OpenCLLIB::Half_powr:
  1326. case OpenCLLIB::Half_recip:
  1327. case OpenCLLIB::Half_rsqrt:
  1328. case OpenCLLIB::Half_sin:
  1329. case OpenCLLIB::Half_sqrt:
  1330. case OpenCLLIB::Half_tan:
  1331. case OpenCLLIB::Native_cos:
  1332. case OpenCLLIB::Native_divide:
  1333. case OpenCLLIB::Native_exp:
  1334. case OpenCLLIB::Native_exp2:
  1335. case OpenCLLIB::Native_exp10:
  1336. case OpenCLLIB::Native_log:
  1337. case OpenCLLIB::Native_log2:
  1338. case OpenCLLIB::Native_log10:
  1339. case OpenCLLIB::Native_powr:
  1340. case OpenCLLIB::Native_recip:
  1341. case OpenCLLIB::Native_rsqrt:
  1342. case OpenCLLIB::Native_sin:
  1343. case OpenCLLIB::Native_sqrt:
  1344. case OpenCLLIB::Native_tan:
  1345. case OpenCLLIB::FClamp:
  1346. case OpenCLLIB::Degrees:
  1347. case OpenCLLIB::FMax_common:
  1348. case OpenCLLIB::FMin_common:
  1349. case OpenCLLIB::Mix:
  1350. case OpenCLLIB::Radians:
  1351. case OpenCLLIB::Step:
  1352. case OpenCLLIB::Smoothstep:
  1353. case OpenCLLIB::Sign: {
  1354. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1355. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1356. << ext_inst_name() << ": "
  1357. << "expected Result Type to be a float scalar or vector type";
  1358. }
  1359. const uint32_t num_components = _.GetDimension(result_type);
  1360. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1361. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1362. << ext_inst_name() << ": "
  1363. << "expected Result Type to be a scalar or a vector with 2, "
  1364. "3, 4, 8 or 16 components";
  1365. }
  1366. for (uint32_t operand_index = 4; operand_index < num_operands;
  1367. ++operand_index) {
  1368. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1369. if (result_type != operand_type) {
  1370. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1371. << ext_inst_name() << ": "
  1372. << "expected types of all operands to be equal to Result "
  1373. "Type";
  1374. }
  1375. }
  1376. break;
  1377. }
  1378. case OpenCLLIB::Fract:
  1379. case OpenCLLIB::Modf:
  1380. case OpenCLLIB::Sincos: {
  1381. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1382. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1383. << ext_inst_name() << ": "
  1384. << "expected Result Type to be a float scalar or vector type";
  1385. }
  1386. const uint32_t num_components = _.GetDimension(result_type);
  1387. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1388. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1389. << ext_inst_name() << ": "
  1390. << "expected Result Type to be a scalar or a vector with 2, "
  1391. "3, 4, 8 or 16 components";
  1392. }
  1393. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1394. if (result_type != x_type) {
  1395. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1396. << ext_inst_name() << ": "
  1397. << "expected type of operand X to be equal to Result Type";
  1398. }
  1399. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  1400. uint32_t p_storage_class = 0;
  1401. uint32_t p_data_type = 0;
  1402. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1403. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1404. << ext_inst_name() << ": "
  1405. << "expected the last operand to be a pointer";
  1406. }
  1407. if (p_storage_class != SpvStorageClassGeneric &&
  1408. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1409. p_storage_class != SpvStorageClassWorkgroup &&
  1410. p_storage_class != SpvStorageClassFunction) {
  1411. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1412. << ext_inst_name() << ": "
  1413. << "expected storage class of the pointer to be Generic, "
  1414. "CrossWorkgroup, Workgroup or Function";
  1415. }
  1416. if (result_type != p_data_type) {
  1417. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1418. << ext_inst_name() << ": "
  1419. << "expected data type of the pointer to be equal to Result "
  1420. "Type";
  1421. }
  1422. break;
  1423. }
  1424. case OpenCLLIB::Frexp:
  1425. case OpenCLLIB::Lgamma_r:
  1426. case OpenCLLIB::Remquo: {
  1427. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1428. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1429. << ext_inst_name() << ": "
  1430. << "expected Result Type to be a float scalar or vector type";
  1431. }
  1432. const uint32_t num_components = _.GetDimension(result_type);
  1433. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1434. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1435. << ext_inst_name() << ": "
  1436. << "expected Result Type to be a scalar or a vector with 2, "
  1437. "3, 4, 8 or 16 components";
  1438. }
  1439. uint32_t operand_index = 4;
  1440. const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
  1441. if (result_type != x_type) {
  1442. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1443. << ext_inst_name() << ": "
  1444. << "expected type of operand X to be equal to Result Type";
  1445. }
  1446. if (ext_inst_key == OpenCLLIB::Remquo) {
  1447. const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
  1448. if (result_type != y_type) {
  1449. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1450. << ext_inst_name() << ": "
  1451. << "expected type of operand Y to be equal to Result Type";
  1452. }
  1453. }
  1454. const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++);
  1455. uint32_t p_storage_class = 0;
  1456. uint32_t p_data_type = 0;
  1457. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1458. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1459. << ext_inst_name() << ": "
  1460. << "expected the last operand to be a pointer";
  1461. }
  1462. if (p_storage_class != SpvStorageClassGeneric &&
  1463. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1464. p_storage_class != SpvStorageClassWorkgroup &&
  1465. p_storage_class != SpvStorageClassFunction) {
  1466. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1467. << ext_inst_name() << ": "
  1468. << "expected storage class of the pointer to be Generic, "
  1469. "CrossWorkgroup, Workgroup or Function";
  1470. }
  1471. if (!_.IsIntScalarOrVectorType(p_data_type) ||
  1472. _.GetBitWidth(p_data_type) != 32) {
  1473. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1474. << ext_inst_name() << ": "
  1475. << "expected data type of the pointer to be a 32-bit int "
  1476. "scalar or vector type";
  1477. }
  1478. if (_.GetDimension(p_data_type) != num_components) {
  1479. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1480. << ext_inst_name() << ": "
  1481. << "expected data type of the pointer to have the same number "
  1482. "of components as Result Type";
  1483. }
  1484. break;
  1485. }
  1486. case OpenCLLIB::Ilogb: {
  1487. if (!_.IsIntScalarOrVectorType(result_type) ||
  1488. _.GetBitWidth(result_type) != 32) {
  1489. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1490. << ext_inst_name() << ": "
  1491. << "expected Result Type to be a 32-bit int scalar or vector "
  1492. "type";
  1493. }
  1494. const uint32_t num_components = _.GetDimension(result_type);
  1495. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1496. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1497. << ext_inst_name() << ": "
  1498. << "expected Result Type to be a scalar or a vector with 2, "
  1499. "3, 4, 8 or 16 components";
  1500. }
  1501. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1502. if (!_.IsFloatScalarOrVectorType(x_type)) {
  1503. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1504. << ext_inst_name() << ": "
  1505. << "expected operand X to be a float scalar or vector";
  1506. }
  1507. if (_.GetDimension(x_type) != num_components) {
  1508. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1509. << ext_inst_name() << ": "
  1510. << "expected operand X to have the same number of components "
  1511. "as Result Type";
  1512. }
  1513. break;
  1514. }
  1515. case OpenCLLIB::Ldexp:
  1516. case OpenCLLIB::Pown:
  1517. case OpenCLLIB::Rootn: {
  1518. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1519. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1520. << ext_inst_name() << ": "
  1521. << "expected Result Type to be a float scalar or vector type";
  1522. }
  1523. const uint32_t num_components = _.GetDimension(result_type);
  1524. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1525. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1526. << ext_inst_name() << ": "
  1527. << "expected Result Type to be a scalar or a vector with 2, "
  1528. "3, 4, 8 or 16 components";
  1529. }
  1530. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1531. if (result_type != x_type) {
  1532. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1533. << ext_inst_name() << ": "
  1534. << "expected type of operand X to be equal to Result Type";
  1535. }
  1536. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  1537. if (!_.IsIntScalarOrVectorType(exp_type) ||
  1538. _.GetBitWidth(exp_type) != 32) {
  1539. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1540. << ext_inst_name() << ": "
  1541. << "expected the exponent to be a 32-bit int scalar or vector";
  1542. }
  1543. if (_.GetDimension(exp_type) != num_components) {
  1544. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1545. << ext_inst_name() << ": "
  1546. << "expected the exponent to have the same number of "
  1547. "components as Result Type";
  1548. }
  1549. break;
  1550. }
  1551. case OpenCLLIB::Nan: {
  1552. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1553. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1554. << ext_inst_name() << ": "
  1555. << "expected Result Type to be a float scalar or vector type";
  1556. }
  1557. const uint32_t num_components = _.GetDimension(result_type);
  1558. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1559. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1560. << ext_inst_name() << ": "
  1561. << "expected Result Type to be a scalar or a vector with 2, "
  1562. "3, 4, 8 or 16 components";
  1563. }
  1564. const uint32_t nancode_type = _.GetOperandTypeId(inst, 4);
  1565. if (!_.IsIntScalarOrVectorType(nancode_type)) {
  1566. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1567. << ext_inst_name() << ": "
  1568. << "expected Nancode to be an int scalar or vector type";
  1569. }
  1570. if (_.GetDimension(nancode_type) != num_components) {
  1571. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1572. << ext_inst_name() << ": "
  1573. << "expected Nancode to have the same number of components as "
  1574. "Result Type";
  1575. }
  1576. if (_.GetBitWidth(result_type) != _.GetBitWidth(nancode_type)) {
  1577. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1578. << ext_inst_name() << ": "
  1579. << "expected Nancode to have the same bit width as Result "
  1580. "Type";
  1581. }
  1582. break;
  1583. }
  1584. case OpenCLLIB::SAbs:
  1585. case OpenCLLIB::SAbs_diff:
  1586. case OpenCLLIB::SAdd_sat:
  1587. case OpenCLLIB::UAdd_sat:
  1588. case OpenCLLIB::SHadd:
  1589. case OpenCLLIB::UHadd:
  1590. case OpenCLLIB::SRhadd:
  1591. case OpenCLLIB::URhadd:
  1592. case OpenCLLIB::SClamp:
  1593. case OpenCLLIB::UClamp:
  1594. case OpenCLLIB::Clz:
  1595. case OpenCLLIB::Ctz:
  1596. case OpenCLLIB::SMad_hi:
  1597. case OpenCLLIB::UMad_sat:
  1598. case OpenCLLIB::SMad_sat:
  1599. case OpenCLLIB::SMax:
  1600. case OpenCLLIB::UMax:
  1601. case OpenCLLIB::SMin:
  1602. case OpenCLLIB::UMin:
  1603. case OpenCLLIB::SMul_hi:
  1604. case OpenCLLIB::Rotate:
  1605. case OpenCLLIB::SSub_sat:
  1606. case OpenCLLIB::USub_sat:
  1607. case OpenCLLIB::Popcount:
  1608. case OpenCLLIB::UAbs:
  1609. case OpenCLLIB::UAbs_diff:
  1610. case OpenCLLIB::UMul_hi:
  1611. case OpenCLLIB::UMad_hi: {
  1612. if (!_.IsIntScalarOrVectorType(result_type)) {
  1613. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1614. << ext_inst_name() << ": "
  1615. << "expected Result Type to be an int scalar or vector type";
  1616. }
  1617. const uint32_t num_components = _.GetDimension(result_type);
  1618. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1619. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1620. << ext_inst_name() << ": "
  1621. << "expected Result Type to be a scalar or a vector with 2, "
  1622. "3, 4, 8 or 16 components";
  1623. }
  1624. for (uint32_t operand_index = 4; operand_index < num_operands;
  1625. ++operand_index) {
  1626. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1627. if (result_type != operand_type) {
  1628. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1629. << ext_inst_name() << ": "
  1630. << "expected types of all operands to be equal to Result "
  1631. "Type";
  1632. }
  1633. }
  1634. break;
  1635. }
  1636. case OpenCLLIB::U_Upsample:
  1637. case OpenCLLIB::S_Upsample: {
  1638. if (!_.IsIntScalarOrVectorType(result_type)) {
  1639. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1640. << ext_inst_name() << ": "
  1641. << "expected Result Type to be an int scalar or vector "
  1642. "type";
  1643. }
  1644. const uint32_t result_num_components = _.GetDimension(result_type);
  1645. if (result_num_components > 4 && result_num_components != 8 &&
  1646. result_num_components != 16) {
  1647. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1648. << ext_inst_name() << ": "
  1649. << "expected Result Type to be a scalar or a vector with 2, "
  1650. "3, 4, 8 or 16 components";
  1651. }
  1652. const uint32_t result_bit_width = _.GetBitWidth(result_type);
  1653. if (result_bit_width != 16 && result_bit_width != 32 &&
  1654. result_bit_width != 64) {
  1655. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1656. << ext_inst_name() << ": "
  1657. << "expected bit width of Result Type components to be 16, 32 "
  1658. "or 64";
  1659. }
  1660. const uint32_t hi_type = _.GetOperandTypeId(inst, 4);
  1661. const uint32_t lo_type = _.GetOperandTypeId(inst, 5);
  1662. if (hi_type != lo_type) {
  1663. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1664. << ext_inst_name() << ": "
  1665. << "expected Hi and Lo operands to have the same type";
  1666. }
  1667. if (result_num_components != _.GetDimension(hi_type)) {
  1668. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1669. << ext_inst_name() << ": "
  1670. << "expected Hi and Lo operands to have the same number of "
  1671. "components as Result Type";
  1672. }
  1673. if (result_bit_width != 2 * _.GetBitWidth(hi_type)) {
  1674. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1675. << ext_inst_name() << ": "
  1676. << "expected bit width of components of Hi and Lo operands to "
  1677. "be half of the bit width of components of Result Type";
  1678. }
  1679. break;
  1680. }
  1681. case OpenCLLIB::SMad24:
  1682. case OpenCLLIB::UMad24:
  1683. case OpenCLLIB::SMul24:
  1684. case OpenCLLIB::UMul24: {
  1685. if (!_.IsIntScalarOrVectorType(result_type) ||
  1686. _.GetBitWidth(result_type) != 32) {
  1687. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1688. << ext_inst_name() << ": "
  1689. << "expected Result Type to be a 32-bit int scalar or vector "
  1690. "type";
  1691. }
  1692. const uint32_t num_components = _.GetDimension(result_type);
  1693. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1694. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1695. << ext_inst_name() << ": "
  1696. << "expected Result Type to be a scalar or a vector with 2, "
  1697. "3, 4, 8 or 16 components";
  1698. }
  1699. for (uint32_t operand_index = 4; operand_index < num_operands;
  1700. ++operand_index) {
  1701. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1702. if (result_type != operand_type) {
  1703. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1704. << ext_inst_name() << ": "
  1705. << "expected types of all operands to be equal to Result "
  1706. "Type";
  1707. }
  1708. }
  1709. break;
  1710. }
  1711. case OpenCLLIB::Cross: {
  1712. if (!_.IsFloatVectorType(result_type)) {
  1713. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1714. << ext_inst_name() << ": "
  1715. << "expected Result Type to be a float vector type";
  1716. }
  1717. const uint32_t num_components = _.GetDimension(result_type);
  1718. if (num_components != 3 && num_components != 4) {
  1719. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1720. << ext_inst_name() << ": "
  1721. << "expected Result Type to have 3 or 4 components";
  1722. }
  1723. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1724. const uint32_t y_type = _.GetOperandTypeId(inst, 5);
  1725. if (x_type != result_type) {
  1726. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1727. << ext_inst_name() << ": "
  1728. << "expected operand X type to be equal to Result Type";
  1729. }
  1730. if (y_type != result_type) {
  1731. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1732. << ext_inst_name() << ": "
  1733. << "expected operand Y type to be equal to Result Type";
  1734. }
  1735. break;
  1736. }
  1737. case OpenCLLIB::Distance:
  1738. case OpenCLLIB::Fast_distance: {
  1739. if (!_.IsFloatScalarType(result_type)) {
  1740. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1741. << ext_inst_name() << ": "
  1742. << "expected Result Type to be a float scalar type";
  1743. }
  1744. const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
  1745. if (!_.IsFloatScalarOrVectorType(p0_type)) {
  1746. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1747. << ext_inst_name() << ": "
  1748. << "expected operand P0 to be of float scalar or vector type";
  1749. }
  1750. const uint32_t num_components = _.GetDimension(p0_type);
  1751. if (num_components > 4) {
  1752. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1753. << ext_inst_name() << ": "
  1754. << "expected operand P0 to have no more than 4 components";
  1755. }
  1756. if (result_type != _.GetComponentType(p0_type)) {
  1757. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1758. << ext_inst_name() << ": "
  1759. << "expected operand P0 component type to be equal to "
  1760. << "Result Type";
  1761. }
  1762. const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
  1763. if (p0_type != p1_type) {
  1764. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1765. << ext_inst_name() << ": "
  1766. << "expected operands P0 and P1 to be of the same type";
  1767. }
  1768. break;
  1769. }
  1770. case OpenCLLIB::Length:
  1771. case OpenCLLIB::Fast_length: {
  1772. if (!_.IsFloatScalarType(result_type)) {
  1773. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1774. << ext_inst_name() << ": "
  1775. << "expected Result Type to be a float scalar type";
  1776. }
  1777. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  1778. if (!_.IsFloatScalarOrVectorType(p_type)) {
  1779. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1780. << ext_inst_name() << ": "
  1781. << "expected operand P to be a float scalar or vector";
  1782. }
  1783. const uint32_t num_components = _.GetDimension(p_type);
  1784. if (num_components > 4) {
  1785. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1786. << ext_inst_name() << ": "
  1787. << "expected operand P to have no more than 4 components";
  1788. }
  1789. if (result_type != _.GetComponentType(p_type)) {
  1790. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1791. << ext_inst_name() << ": "
  1792. << "expected operand P component type to be equal to Result "
  1793. "Type";
  1794. }
  1795. break;
  1796. }
  1797. case OpenCLLIB::Normalize:
  1798. case OpenCLLIB::Fast_normalize: {
  1799. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1800. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1801. << ext_inst_name() << ": "
  1802. << "expected Result Type to be a float scalar or vector type";
  1803. }
  1804. const uint32_t num_components = _.GetDimension(result_type);
  1805. if (num_components > 4) {
  1806. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1807. << ext_inst_name() << ": "
  1808. << "expected Result Type to have no more than 4 components";
  1809. }
  1810. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  1811. if (p_type != result_type) {
  1812. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1813. << ext_inst_name() << ": "
  1814. << "expected operand P type to be equal to Result Type";
  1815. }
  1816. break;
  1817. }
  1818. case OpenCLLIB::Bitselect: {
  1819. if (!_.IsFloatScalarOrVectorType(result_type) &&
  1820. !_.IsIntScalarOrVectorType(result_type)) {
  1821. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1822. << ext_inst_name() << ": "
  1823. << "expected Result Type to be an int or float scalar or "
  1824. "vector type";
  1825. }
  1826. const uint32_t num_components = _.GetDimension(result_type);
  1827. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1828. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1829. << ext_inst_name() << ": "
  1830. << "expected Result Type to be a scalar or a vector with 2, "
  1831. "3, 4, 8 or 16 components";
  1832. }
  1833. for (uint32_t operand_index = 4; operand_index < num_operands;
  1834. ++operand_index) {
  1835. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1836. if (result_type != operand_type) {
  1837. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1838. << ext_inst_name() << ": "
  1839. << "expected types of all operands to be equal to Result "
  1840. "Type";
  1841. }
  1842. }
  1843. break;
  1844. }
  1845. case OpenCLLIB::Select: {
  1846. if (!_.IsFloatScalarOrVectorType(result_type) &&
  1847. !_.IsIntScalarOrVectorType(result_type)) {
  1848. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1849. << ext_inst_name() << ": "
  1850. << "expected Result Type to be an int or float scalar or "
  1851. "vector type";
  1852. }
  1853. const uint32_t num_components = _.GetDimension(result_type);
  1854. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1855. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1856. << ext_inst_name() << ": "
  1857. << "expected Result Type to be a scalar or a vector with 2, "
  1858. "3, 4, 8 or 16 components";
  1859. }
  1860. const uint32_t a_type = _.GetOperandTypeId(inst, 4);
  1861. const uint32_t b_type = _.GetOperandTypeId(inst, 5);
  1862. const uint32_t c_type = _.GetOperandTypeId(inst, 6);
  1863. if (result_type != a_type) {
  1864. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1865. << ext_inst_name() << ": "
  1866. << "expected operand A type to be equal to Result Type";
  1867. }
  1868. if (result_type != b_type) {
  1869. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1870. << ext_inst_name() << ": "
  1871. << "expected operand B type to be equal to Result Type";
  1872. }
  1873. if (!_.IsIntScalarOrVectorType(c_type)) {
  1874. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1875. << ext_inst_name() << ": "
  1876. << "expected operand C to be an int scalar or vector";
  1877. }
  1878. if (num_components != _.GetDimension(c_type)) {
  1879. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1880. << ext_inst_name() << ": "
  1881. << "expected operand C to have the same number of components "
  1882. "as Result Type";
  1883. }
  1884. if (_.GetBitWidth(result_type) != _.GetBitWidth(c_type)) {
  1885. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1886. << ext_inst_name() << ": "
  1887. << "expected operand C to have the same bit width as Result "
  1888. "Type";
  1889. }
  1890. break;
  1891. }
  1892. case OpenCLLIB::Vloadn: {
  1893. if (!_.IsFloatVectorType(result_type) &&
  1894. !_.IsIntVectorType(result_type)) {
  1895. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1896. << ext_inst_name() << ": "
  1897. << "expected Result Type to be an int or float vector type";
  1898. }
  1899. const uint32_t num_components = _.GetDimension(result_type);
  1900. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1901. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1902. << ext_inst_name() << ": "
  1903. << "expected Result Type to have 2, 3, 4, 8 or 16 components";
  1904. }
  1905. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  1906. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  1907. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  1908. if (!size_t_bit_width) {
  1909. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1910. << ext_inst_name()
  1911. << " can only be used with physical addressing models";
  1912. }
  1913. if (!_.IsIntScalarType(offset_type) ||
  1914. _.GetBitWidth(offset_type) != size_t_bit_width) {
  1915. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1916. << ext_inst_name() << ": "
  1917. << "expected operand Offset to be of type size_t ("
  1918. << size_t_bit_width
  1919. << "-bit integer for the addressing model used in the module)";
  1920. }
  1921. uint32_t p_storage_class = 0;
  1922. uint32_t p_data_type = 0;
  1923. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1924. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1925. << ext_inst_name() << ": "
  1926. << "expected operand P to be a pointer";
  1927. }
  1928. if (p_storage_class != SpvStorageClassUniformConstant &&
  1929. p_storage_class != SpvStorageClassGeneric &&
  1930. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1931. p_storage_class != SpvStorageClassWorkgroup &&
  1932. p_storage_class != SpvStorageClassFunction) {
  1933. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1934. << ext_inst_name() << ": "
  1935. << "expected operand P storage class to be UniformConstant, "
  1936. "Generic, CrossWorkgroup, Workgroup or Function";
  1937. }
  1938. if (_.GetComponentType(result_type) != p_data_type) {
  1939. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1940. << ext_inst_name() << ": "
  1941. << "expected operand P data type to be equal to component "
  1942. "type of Result Type";
  1943. }
  1944. const uint32_t n_value = inst->word(7);
  1945. if (num_components != n_value) {
  1946. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1947. << ext_inst_name() << ": "
  1948. << "expected literal N to be equal to the number of "
  1949. "components of Result Type";
  1950. }
  1951. break;
  1952. }
  1953. case OpenCLLIB::Vstoren: {
  1954. if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) {
  1955. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1956. << ext_inst_name() << ": expected Result Type to be void";
  1957. }
  1958. const uint32_t data_type = _.GetOperandTypeId(inst, 4);
  1959. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  1960. const uint32_t p_type = _.GetOperandTypeId(inst, 6);
  1961. if (!_.IsFloatVectorType(data_type) && !_.IsIntVectorType(data_type)) {
  1962. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1963. << ext_inst_name() << ": "
  1964. << "expected Data to be an int or float vector";
  1965. }
  1966. const uint32_t num_components = _.GetDimension(data_type);
  1967. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1968. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1969. << ext_inst_name() << ": "
  1970. << "expected Data to have 2, 3, 4, 8 or 16 components";
  1971. }
  1972. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  1973. if (!size_t_bit_width) {
  1974. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1975. << ext_inst_name()
  1976. << " can only be used with physical addressing models";
  1977. }
  1978. if (!_.IsIntScalarType(offset_type) ||
  1979. _.GetBitWidth(offset_type) != size_t_bit_width) {
  1980. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1981. << ext_inst_name() << ": "
  1982. << "expected operand Offset to be of type size_t ("
  1983. << size_t_bit_width
  1984. << "-bit integer for the addressing model used in the module)";
  1985. }
  1986. uint32_t p_storage_class = 0;
  1987. uint32_t p_data_type = 0;
  1988. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1989. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1990. << ext_inst_name() << ": "
  1991. << "expected operand P to be a pointer";
  1992. }
  1993. if (p_storage_class != SpvStorageClassGeneric &&
  1994. p_storage_class != SpvStorageClassCrossWorkgroup &&
  1995. p_storage_class != SpvStorageClassWorkgroup &&
  1996. p_storage_class != SpvStorageClassFunction) {
  1997. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1998. << ext_inst_name() << ": "
  1999. << "expected operand P storage class to be Generic, "
  2000. "CrossWorkgroup, Workgroup or Function";
  2001. }
  2002. if (_.GetComponentType(data_type) != p_data_type) {
  2003. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2004. << ext_inst_name() << ": "
  2005. << "expected operand P data type to be equal to the type of "
  2006. "operand Data components";
  2007. }
  2008. break;
  2009. }
  2010. case OpenCLLIB::Vload_half: {
  2011. if (!_.IsFloatScalarType(result_type)) {
  2012. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2013. << ext_inst_name() << ": "
  2014. << "expected Result Type to be a float scalar type";
  2015. }
  2016. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2017. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2018. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2019. if (!size_t_bit_width) {
  2020. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2021. << ext_inst_name()
  2022. << " can only be used with physical addressing models";
  2023. }
  2024. if (!_.IsIntScalarType(offset_type) ||
  2025. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2026. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2027. << ext_inst_name() << ": "
  2028. << "expected operand Offset to be of type size_t ("
  2029. << size_t_bit_width
  2030. << "-bit integer for the addressing model used in the module)";
  2031. }
  2032. uint32_t p_storage_class = 0;
  2033. uint32_t p_data_type = 0;
  2034. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2035. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2036. << ext_inst_name() << ": "
  2037. << "expected operand P to be a pointer";
  2038. }
  2039. if (p_storage_class != SpvStorageClassUniformConstant &&
  2040. p_storage_class != SpvStorageClassGeneric &&
  2041. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2042. p_storage_class != SpvStorageClassWorkgroup &&
  2043. p_storage_class != SpvStorageClassFunction) {
  2044. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2045. << ext_inst_name() << ": "
  2046. << "expected operand P storage class to be UniformConstant, "
  2047. "Generic, CrossWorkgroup, Workgroup or Function";
  2048. }
  2049. if (!_.IsFloatScalarType(p_data_type) ||
  2050. _.GetBitWidth(p_data_type) != 16) {
  2051. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2052. << ext_inst_name() << ": "
  2053. << "expected operand P data type to be 16-bit float scalar";
  2054. }
  2055. break;
  2056. }
  2057. case OpenCLLIB::Vload_halfn:
  2058. case OpenCLLIB::Vloada_halfn: {
  2059. if (!_.IsFloatVectorType(result_type)) {
  2060. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2061. << ext_inst_name() << ": "
  2062. << "expected Result Type to be a float vector type";
  2063. }
  2064. const uint32_t num_components = _.GetDimension(result_type);
  2065. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2066. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2067. << ext_inst_name() << ": "
  2068. << "expected Result Type to have 2, 3, 4, 8 or 16 components";
  2069. }
  2070. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2071. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2072. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2073. if (!size_t_bit_width) {
  2074. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2075. << ext_inst_name()
  2076. << " can only be used with physical addressing models";
  2077. }
  2078. if (!_.IsIntScalarType(offset_type) ||
  2079. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2080. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2081. << ext_inst_name() << ": "
  2082. << "expected operand Offset to be of type size_t ("
  2083. << size_t_bit_width
  2084. << "-bit integer for the addressing model used in the module)";
  2085. }
  2086. uint32_t p_storage_class = 0;
  2087. uint32_t p_data_type = 0;
  2088. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2089. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2090. << ext_inst_name() << ": "
  2091. << "expected operand P to be a pointer";
  2092. }
  2093. if (p_storage_class != SpvStorageClassUniformConstant &&
  2094. p_storage_class != SpvStorageClassGeneric &&
  2095. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2096. p_storage_class != SpvStorageClassWorkgroup &&
  2097. p_storage_class != SpvStorageClassFunction) {
  2098. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2099. << ext_inst_name() << ": "
  2100. << "expected operand P storage class to be UniformConstant, "
  2101. "Generic, CrossWorkgroup, Workgroup or Function";
  2102. }
  2103. if (!_.IsFloatScalarType(p_data_type) ||
  2104. _.GetBitWidth(p_data_type) != 16) {
  2105. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2106. << ext_inst_name() << ": "
  2107. << "expected operand P data type to be 16-bit float scalar";
  2108. }
  2109. const uint32_t n_value = inst->word(7);
  2110. if (num_components != n_value) {
  2111. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2112. << ext_inst_name() << ": "
  2113. << "expected literal N to be equal to the number of "
  2114. "components of Result Type";
  2115. }
  2116. break;
  2117. }
  2118. case OpenCLLIB::Vstore_half:
  2119. case OpenCLLIB::Vstore_half_r:
  2120. case OpenCLLIB::Vstore_halfn:
  2121. case OpenCLLIB::Vstore_halfn_r:
  2122. case OpenCLLIB::Vstorea_halfn:
  2123. case OpenCLLIB::Vstorea_halfn_r: {
  2124. if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) {
  2125. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2126. << ext_inst_name() << ": expected Result Type to be void";
  2127. }
  2128. const uint32_t data_type = _.GetOperandTypeId(inst, 4);
  2129. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  2130. const uint32_t p_type = _.GetOperandTypeId(inst, 6);
  2131. const uint32_t data_type_bit_width = _.GetBitWidth(data_type);
  2132. if (ext_inst_key == OpenCLLIB::Vstore_half ||
  2133. ext_inst_key == OpenCLLIB::Vstore_half_r) {
  2134. if (!_.IsFloatScalarType(data_type) ||
  2135. (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  2136. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2137. << ext_inst_name() << ": "
  2138. << "expected Data to be a 32 or 64-bit float scalar";
  2139. }
  2140. } else {
  2141. if (!_.IsFloatVectorType(data_type) ||
  2142. (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  2143. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2144. << ext_inst_name() << ": "
  2145. << "expected Data to be a 32 or 64-bit float vector";
  2146. }
  2147. const uint32_t num_components = _.GetDimension(data_type);
  2148. if (num_components > 4 && num_components != 8 &&
  2149. num_components != 16) {
  2150. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2151. << ext_inst_name() << ": "
  2152. << "expected Data to have 2, 3, 4, 8 or 16 components";
  2153. }
  2154. }
  2155. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2156. if (!size_t_bit_width) {
  2157. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2158. << ext_inst_name()
  2159. << " can only be used with physical addressing models";
  2160. }
  2161. if (!_.IsIntScalarType(offset_type) ||
  2162. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2163. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2164. << ext_inst_name() << ": "
  2165. << "expected operand Offset to be of type size_t ("
  2166. << size_t_bit_width
  2167. << "-bit integer for the addressing model used in the module)";
  2168. }
  2169. uint32_t p_storage_class = 0;
  2170. uint32_t p_data_type = 0;
  2171. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2172. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2173. << ext_inst_name() << ": "
  2174. << "expected operand P to be a pointer";
  2175. }
  2176. if (p_storage_class != SpvStorageClassGeneric &&
  2177. p_storage_class != SpvStorageClassCrossWorkgroup &&
  2178. p_storage_class != SpvStorageClassWorkgroup &&
  2179. p_storage_class != SpvStorageClassFunction) {
  2180. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2181. << ext_inst_name() << ": "
  2182. << "expected operand P storage class to be Generic, "
  2183. "CrossWorkgroup, Workgroup or Function";
  2184. }
  2185. if (!_.IsFloatScalarType(p_data_type) ||
  2186. _.GetBitWidth(p_data_type) != 16) {
  2187. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2188. << ext_inst_name() << ": "
  2189. << "expected operand P data type to be 16-bit float scalar";
  2190. }
  2191. // Rounding mode enum is checked by assembler.
  2192. break;
  2193. }
  2194. case OpenCLLIB::Shuffle:
  2195. case OpenCLLIB::Shuffle2: {
  2196. if (!_.IsFloatVectorType(result_type) &&
  2197. !_.IsIntVectorType(result_type)) {
  2198. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2199. << ext_inst_name() << ": "
  2200. << "expected Result Type to be an int or float vector type";
  2201. }
  2202. const uint32_t result_num_components = _.GetDimension(result_type);
  2203. if (result_num_components != 2 && result_num_components != 4 &&
  2204. result_num_components != 8 && result_num_components != 16) {
  2205. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2206. << ext_inst_name() << ": "
  2207. << "expected Result Type to have 2, 4, 8 or 16 components";
  2208. }
  2209. uint32_t operand_index = 4;
  2210. const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
  2211. if (ext_inst_key == OpenCLLIB::Shuffle2) {
  2212. const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
  2213. if (x_type != y_type) {
  2214. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2215. << ext_inst_name() << ": "
  2216. << "expected operands X and Y to be of the same type";
  2217. }
  2218. }
  2219. const uint32_t shuffle_mask_type =
  2220. _.GetOperandTypeId(inst, operand_index++);
  2221. if (!_.IsFloatVectorType(x_type) && !_.IsIntVectorType(x_type)) {
  2222. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2223. << ext_inst_name() << ": "
  2224. << "expected operand X to be an int or float vector";
  2225. }
  2226. const uint32_t x_num_components = _.GetDimension(x_type);
  2227. if (x_num_components != 2 && x_num_components != 4 &&
  2228. x_num_components != 8 && x_num_components != 16) {
  2229. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2230. << ext_inst_name() << ": "
  2231. << "expected operand X to have 2, 4, 8 or 16 components";
  2232. }
  2233. const uint32_t result_component_type = _.GetComponentType(result_type);
  2234. if (result_component_type != _.GetComponentType(x_type)) {
  2235. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2236. << ext_inst_name() << ": "
  2237. << "expected operand X and Result Type to have equal "
  2238. "component types";
  2239. }
  2240. if (!_.IsIntVectorType(shuffle_mask_type)) {
  2241. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2242. << ext_inst_name() << ": "
  2243. << "expected operand Shuffle Mask to be an int vector";
  2244. }
  2245. if (result_num_components != _.GetDimension(shuffle_mask_type)) {
  2246. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2247. << ext_inst_name() << ": "
  2248. << "expected operand Shuffle Mask to have the same number of "
  2249. "components as Result Type";
  2250. }
  2251. if (_.GetBitWidth(result_component_type) !=
  2252. _.GetBitWidth(shuffle_mask_type)) {
  2253. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2254. << ext_inst_name() << ": "
  2255. << "expected operand Shuffle Mask components to have the same "
  2256. "bit width as Result Type components";
  2257. }
  2258. break;
  2259. }
  2260. case OpenCLLIB::Printf: {
  2261. if (!_.IsIntScalarType(result_type) ||
  2262. _.GetBitWidth(result_type) != 32) {
  2263. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2264. << ext_inst_name() << ": "
  2265. << "expected Result Type to be a 32-bit int type";
  2266. }
  2267. const uint32_t format_type = _.GetOperandTypeId(inst, 4);
  2268. uint32_t format_storage_class = 0;
  2269. uint32_t format_data_type = 0;
  2270. if (!_.GetPointerTypeInfo(format_type, &format_data_type,
  2271. &format_storage_class)) {
  2272. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2273. << ext_inst_name() << ": "
  2274. << "expected operand Format to be a pointer";
  2275. }
  2276. if (format_storage_class != SpvStorageClassUniformConstant) {
  2277. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2278. << ext_inst_name() << ": "
  2279. << "expected Format storage class to be UniformConstant";
  2280. }
  2281. if (!_.IsIntScalarType(format_data_type) ||
  2282. _.GetBitWidth(format_data_type) != 8) {
  2283. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2284. << ext_inst_name() << ": "
  2285. << "expected Format data type to be 8-bit int";
  2286. }
  2287. break;
  2288. }
  2289. case OpenCLLIB::Prefetch: {
  2290. if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) {
  2291. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2292. << ext_inst_name() << ": expected Result Type to be void";
  2293. }
  2294. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  2295. const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5);
  2296. uint32_t p_storage_class = 0;
  2297. uint32_t p_data_type = 0;
  2298. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2299. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2300. << ext_inst_name() << ": "
  2301. << "expected operand Ptr to be a pointer";
  2302. }
  2303. if (p_storage_class != SpvStorageClassCrossWorkgroup) {
  2304. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2305. << ext_inst_name() << ": "
  2306. << "expected operand Ptr storage class to be CrossWorkgroup";
  2307. }
  2308. if (!_.IsFloatScalarOrVectorType(p_data_type) &&
  2309. !_.IsIntScalarOrVectorType(p_data_type)) {
  2310. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2311. << ext_inst_name() << ": "
  2312. << "expected Ptr data type to be int or float scalar or "
  2313. "vector";
  2314. }
  2315. const uint32_t num_components = _.GetDimension(p_data_type);
  2316. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2317. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2318. << ext_inst_name() << ": "
  2319. << "expected Result Type to be a scalar or a vector with 2, "
  2320. "3, 4, 8 or 16 components";
  2321. }
  2322. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2323. if (!size_t_bit_width) {
  2324. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2325. << ext_inst_name()
  2326. << " can only be used with physical addressing models";
  2327. }
  2328. if (!_.IsIntScalarType(num_elements_type) ||
  2329. _.GetBitWidth(num_elements_type) != size_t_bit_width) {
  2330. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2331. << ext_inst_name() << ": "
  2332. << "expected operand Num Elements to be of type size_t ("
  2333. << size_t_bit_width
  2334. << "-bit integer for the addressing model used in the module)";
  2335. }
  2336. break;
  2337. }
  2338. }
  2339. } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  2340. if (!_.IsVoidType(result_type)) {
  2341. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2342. << ext_inst_name() << ": "
  2343. << "expected result type must be a result id of "
  2344. << "OpTypeVoid";
  2345. }
  2346. auto num_words = inst->words().size();
  2347. const OpenCLDebugInfo100Instructions ext_inst_key =
  2348. OpenCLDebugInfo100Instructions(ext_inst_index);
  2349. switch (ext_inst_key) {
  2350. case OpenCLDebugInfo100DebugInfoNone:
  2351. case OpenCLDebugInfo100DebugNoScope:
  2352. case OpenCLDebugInfo100DebugOperation:
  2353. // The binary parser validates the opcode for DebugInfoNone,
  2354. // DebugNoScope, DebugOperation, and the literal values don't need
  2355. // further checks.
  2356. break;
  2357. case OpenCLDebugInfo100DebugCompilationUnit: {
  2358. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2359. break;
  2360. }
  2361. case OpenCLDebugInfo100DebugSource: {
  2362. CHECK_OPERAND("File", SpvOpString, 5);
  2363. if (num_words == 7) CHECK_OPERAND("Text", SpvOpString, 6);
  2364. break;
  2365. }
  2366. case OpenCLDebugInfo100DebugTypeBasic: {
  2367. CHECK_OPERAND("Name", SpvOpString, 5);
  2368. CHECK_OPERAND("Size", SpvOpConstant, 6);
  2369. // "Encoding" param is already validated by the binary parsing stage.
  2370. break;
  2371. }
  2372. case OpenCLDebugInfo100DebugTypePointer:
  2373. case OpenCLDebugInfo100DebugTypeQualifier: {
  2374. auto validate_base_type =
  2375. ValidateOperandBaseType(_, inst, 5, ext_inst_name);
  2376. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2377. break;
  2378. }
  2379. case OpenCLDebugInfo100DebugTypeVector: {
  2380. auto validate_base_type =
  2381. ValidateOperandBaseType(_, inst, 5, ext_inst_name);
  2382. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2383. uint32_t component_count = inst->word(6);
  2384. if (!component_count || component_count > 4) {
  2385. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2386. << ext_inst_name() << ": Component Count must be positive "
  2387. << "integer less than or equal to 4";
  2388. }
  2389. break;
  2390. }
  2391. case OpenCLDebugInfo100DebugTypeArray: {
  2392. auto validate_base_type = ValidateOperandDebugType(
  2393. _, "Base Type", inst, 5, ext_inst_name, false);
  2394. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2395. for (uint32_t i = 6; i < num_words; ++i) {
  2396. bool invalid = false;
  2397. auto* component_count = _.FindDef(inst->word(i));
  2398. if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) {
  2399. // TODO: We need a spec discussion for the bindless array.
  2400. if (!component_count->word(3)) {
  2401. invalid = true;
  2402. }
  2403. } else if (component_count->words().size() > 6 &&
  2404. (OpenCLDebugInfo100Instructions(component_count->word(
  2405. 4)) == OpenCLDebugInfo100DebugLocalVariable ||
  2406. OpenCLDebugInfo100Instructions(component_count->word(
  2407. 4)) == OpenCLDebugInfo100DebugGlobalVariable)) {
  2408. auto* component_count_type = _.FindDef(component_count->word(6));
  2409. if (component_count_type->words().size() > 7) {
  2410. if (OpenCLDebugInfo100Instructions(component_count_type->word(
  2411. 4)) != OpenCLDebugInfo100DebugTypeBasic ||
  2412. OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
  2413. component_count_type->word(7)) !=
  2414. OpenCLDebugInfo100Unsigned) {
  2415. invalid = true;
  2416. } else {
  2417. // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable
  2418. // must have Unsigned encoding and 32 or 64 as its size in bits.
  2419. Instruction* size_in_bits =
  2420. _.FindDef(component_count_type->word(6));
  2421. if (!_.IsIntScalarType(size_in_bits->type_id()) ||
  2422. (size_in_bits->word(3) != 32 &&
  2423. size_in_bits->word(3) != 64)) {
  2424. invalid = true;
  2425. }
  2426. }
  2427. } else {
  2428. invalid = true;
  2429. }
  2430. } else {
  2431. invalid = true;
  2432. }
  2433. if (invalid) {
  2434. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2435. << ext_inst_name() << ": Component Count must be "
  2436. << "OpConstant with a 32- or 64-bits integer scalar type or "
  2437. << "DebugGlobalVariable or DebugLocalVariable with a 32- or "
  2438. << "64-bits unsigned integer scalar type";
  2439. }
  2440. }
  2441. break;
  2442. }
  2443. case OpenCLDebugInfo100DebugTypedef: {
  2444. CHECK_OPERAND("Name", SpvOpString, 5);
  2445. auto validate_base_type =
  2446. ValidateOperandBaseType(_, inst, 6, ext_inst_name);
  2447. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2448. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2449. auto validate_parent =
  2450. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2451. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2452. break;
  2453. }
  2454. case OpenCLDebugInfo100DebugTypeFunction: {
  2455. auto* return_type = _.FindDef(inst->word(6));
  2456. // TODO: We need a spec discussion that we have to allow return and
  2457. // parameter types of a DebugTypeFunction to have template parameter.
  2458. if (return_type->opcode() != SpvOpTypeVoid) {
  2459. auto validate_return = ValidateOperandDebugType(
  2460. _, "Return Type", inst, 6, ext_inst_name, true);
  2461. if (validate_return != SPV_SUCCESS) return validate_return;
  2462. }
  2463. for (uint32_t word_index = 7; word_index < num_words; ++word_index) {
  2464. auto validate_param = ValidateOperandDebugType(
  2465. _, "Parameter Types", inst, word_index, ext_inst_name, true);
  2466. if (validate_param != SPV_SUCCESS) return validate_param;
  2467. }
  2468. break;
  2469. }
  2470. case OpenCLDebugInfo100DebugTypeEnum: {
  2471. CHECK_OPERAND("Name", SpvOpString, 5);
  2472. if (!DoesDebugInfoOperandMatchExpectation(
  2473. _,
  2474. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2475. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2476. },
  2477. inst, 6)) {
  2478. auto validate_underlying_type = ValidateOperandDebugType(
  2479. _, "Underlying Types", inst, 6, ext_inst_name, false);
  2480. if (validate_underlying_type != SPV_SUCCESS)
  2481. return validate_underlying_type;
  2482. }
  2483. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2484. auto validate_parent =
  2485. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2486. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2487. CHECK_OPERAND("Size", SpvOpConstant, 11);
  2488. auto* size = _.FindDef(inst->word(11));
  2489. if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) {
  2490. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2491. << ext_inst_name() << ": expected operand Size is a "
  2492. << "positive integer";
  2493. }
  2494. for (uint32_t word_index = 13; word_index + 1 < num_words;
  2495. word_index += 2) {
  2496. CHECK_OPERAND("Value", SpvOpConstant, word_index);
  2497. CHECK_OPERAND("Name", SpvOpString, word_index + 1);
  2498. }
  2499. break;
  2500. }
  2501. case OpenCLDebugInfo100DebugTypeComposite: {
  2502. CHECK_OPERAND("Name", SpvOpString, 5);
  2503. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2504. auto validate_parent =
  2505. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2506. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2507. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2508. if (!DoesDebugInfoOperandMatchExpectation(
  2509. _,
  2510. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2511. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2512. },
  2513. inst, 12)) {
  2514. CHECK_OPERAND("Size", SpvOpConstant, 12);
  2515. }
  2516. for (uint32_t word_index = 14; word_index < num_words; ++word_index) {
  2517. if (!DoesDebugInfoOperandMatchExpectation(
  2518. _,
  2519. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2520. return dbg_inst == OpenCLDebugInfo100DebugTypeMember ||
  2521. dbg_inst == OpenCLDebugInfo100DebugFunction ||
  2522. dbg_inst == OpenCLDebugInfo100DebugTypeInheritance;
  2523. },
  2524. inst, word_index)) {
  2525. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2526. << ext_inst_name() << ": "
  2527. << "expected operand Members "
  2528. << "must be DebugTypeMember, DebugFunction, or "
  2529. "DebugTypeInheritance";
  2530. }
  2531. }
  2532. break;
  2533. }
  2534. case OpenCLDebugInfo100DebugTypeMember: {
  2535. CHECK_OPERAND("Name", SpvOpString, 5);
  2536. // TODO: We need a spec discussion that we have to allow member types
  2537. // to have template parameter.
  2538. auto validate_type =
  2539. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
  2540. if (validate_type != SPV_SUCCESS) return validate_type;
  2541. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2542. CHECK_DEBUG_OPERAND("Parent", OpenCLDebugInfo100DebugTypeComposite, 10);
  2543. CHECK_OPERAND("Offset", SpvOpConstant, 11);
  2544. CHECK_OPERAND("Size", SpvOpConstant, 12);
  2545. if (num_words == 15) CHECK_OPERAND("Value", SpvOpConstant, 14);
  2546. break;
  2547. }
  2548. case OpenCLDebugInfo100DebugTypeInheritance: {
  2549. CHECK_DEBUG_OPERAND("Child", OpenCLDebugInfo100DebugTypeComposite, 5);
  2550. auto* debug_inst = _.FindDef(inst->word(5));
  2551. auto composite_type =
  2552. OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
  2553. if (composite_type != OpenCLDebugInfo100Class &&
  2554. composite_type != OpenCLDebugInfo100Structure) {
  2555. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2556. << ext_inst_name() << ": "
  2557. << "expected operand Child must be class or struct debug type";
  2558. }
  2559. CHECK_DEBUG_OPERAND("Parent", OpenCLDebugInfo100DebugTypeComposite, 6);
  2560. debug_inst = _.FindDef(inst->word(6));
  2561. composite_type =
  2562. OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
  2563. if (composite_type != OpenCLDebugInfo100Class &&
  2564. composite_type != OpenCLDebugInfo100Structure) {
  2565. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2566. << ext_inst_name() << ": "
  2567. << "expected operand Parent must be class or struct debug "
  2568. "type";
  2569. }
  2570. CHECK_OPERAND("Offset", SpvOpConstant, 7);
  2571. CHECK_OPERAND("Size", SpvOpConstant, 8);
  2572. break;
  2573. }
  2574. case OpenCLDebugInfo100DebugFunction: {
  2575. CHECK_OPERAND("Name", SpvOpString, 5);
  2576. auto validate_type =
  2577. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
  2578. if (validate_type != SPV_SUCCESS) return validate_type;
  2579. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2580. auto validate_parent =
  2581. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2582. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2583. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2584. if (!DoesDebugInfoOperandMatchExpectation(
  2585. _,
  2586. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2587. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2588. },
  2589. inst, 14)) {
  2590. CHECK_OPERAND("Function", SpvOpFunction, 14);
  2591. }
  2592. if (num_words == 16) {
  2593. CHECK_DEBUG_OPERAND("Declaration",
  2594. OpenCLDebugInfo100DebugFunctionDeclaration, 15);
  2595. }
  2596. break;
  2597. }
  2598. case OpenCLDebugInfo100DebugFunctionDeclaration: {
  2599. CHECK_OPERAND("Name", SpvOpString, 5);
  2600. auto validate_type =
  2601. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
  2602. if (validate_type != SPV_SUCCESS) return validate_type;
  2603. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2604. auto validate_parent =
  2605. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2606. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2607. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2608. break;
  2609. }
  2610. case OpenCLDebugInfo100DebugLexicalBlock: {
  2611. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 5);
  2612. auto validate_parent =
  2613. ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name);
  2614. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2615. if (num_words == 10) CHECK_OPERAND("Name", SpvOpString, 9);
  2616. break;
  2617. }
  2618. case OpenCLDebugInfo100DebugScope: {
  2619. auto validate_scope =
  2620. ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name);
  2621. if (validate_scope != SPV_SUCCESS) return validate_scope;
  2622. if (num_words == 7) {
  2623. CHECK_DEBUG_OPERAND("Inlined At", OpenCLDebugInfo100DebugInlinedAt,
  2624. 6);
  2625. }
  2626. break;
  2627. }
  2628. case OpenCLDebugInfo100DebugLocalVariable: {
  2629. CHECK_OPERAND("Name", SpvOpString, 5);
  2630. // TODO: We need a spec discussion that we have to allow local variable
  2631. // types to have template parameter.
  2632. auto validate_type =
  2633. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
  2634. if (validate_type != SPV_SUCCESS) return validate_type;
  2635. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2636. auto validate_parent =
  2637. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  2638. if (validate_parent != SPV_SUCCESS) return validate_parent;
  2639. break;
  2640. }
  2641. case OpenCLDebugInfo100DebugDeclare: {
  2642. CHECK_DEBUG_OPERAND("Local Variable",
  2643. OpenCLDebugInfo100DebugLocalVariable, 5);
  2644. auto* operand = _.FindDef(inst->word(6));
  2645. if (operand->opcode() != SpvOpVariable &&
  2646. operand->opcode() != SpvOpFunctionParameter) {
  2647. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2648. << ext_inst_name() << ": "
  2649. << "expected operand Variable must be a result id of "
  2650. "OpVariable or OpFunctionParameter";
  2651. }
  2652. CHECK_DEBUG_OPERAND("Expression", OpenCLDebugInfo100DebugExpression, 7);
  2653. break;
  2654. }
  2655. case OpenCLDebugInfo100DebugExpression: {
  2656. for (uint32_t word_index = 5; word_index < num_words; ++word_index) {
  2657. CHECK_DEBUG_OPERAND("Operation", OpenCLDebugInfo100DebugOperation,
  2658. word_index);
  2659. }
  2660. break;
  2661. }
  2662. case OpenCLDebugInfo100DebugTypeTemplate: {
  2663. if (!DoesDebugInfoOperandMatchExpectation(
  2664. _,
  2665. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2666. return dbg_inst == OpenCLDebugInfo100DebugTypeComposite ||
  2667. dbg_inst == OpenCLDebugInfo100DebugFunction;
  2668. },
  2669. inst, 5)) {
  2670. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2671. << ext_inst_name() << ": "
  2672. << "expected operand Target must be DebugTypeComposite "
  2673. << "or DebugFunction";
  2674. }
  2675. for (uint32_t word_index = 6; word_index < num_words; ++word_index) {
  2676. if (!DoesDebugInfoOperandMatchExpectation(
  2677. _,
  2678. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2679. return dbg_inst ==
  2680. OpenCLDebugInfo100DebugTypeTemplateParameter ||
  2681. dbg_inst ==
  2682. OpenCLDebugInfo100DebugTypeTemplateTemplateParameter;
  2683. },
  2684. inst, word_index)) {
  2685. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2686. << ext_inst_name() << ": "
  2687. << "expected operand Parameters must be "
  2688. << "DebugTypeTemplateParameter or "
  2689. << "DebugTypeTemplateTemplateParameter";
  2690. }
  2691. }
  2692. break;
  2693. }
  2694. case OpenCLDebugInfo100DebugTypeTemplateParameter: {
  2695. CHECK_OPERAND("Name", SpvOpString, 5);
  2696. auto validate_actual_type = ValidateOperandDebugType(
  2697. _, "Actual Type", inst, 6, ext_inst_name, false);
  2698. if (validate_actual_type != SPV_SUCCESS) return validate_actual_type;
  2699. if (!DoesDebugInfoOperandMatchExpectation(
  2700. _,
  2701. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2702. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2703. },
  2704. inst, 7)) {
  2705. CHECK_OPERAND("Value", SpvOpConstant, 7);
  2706. }
  2707. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 8);
  2708. break;
  2709. }
  2710. case OpenCLDebugInfo100DebugGlobalVariable: {
  2711. CHECK_OPERAND("Name", SpvOpString, 5);
  2712. auto validate_type =
  2713. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
  2714. if (validate_type != SPV_SUCCESS) return validate_type;
  2715. CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
  2716. auto validate_scope =
  2717. ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name);
  2718. if (validate_scope != SPV_SUCCESS) return validate_scope;
  2719. CHECK_OPERAND("Linkage Name", SpvOpString, 11);
  2720. if (!DoesDebugInfoOperandMatchExpectation(
  2721. _,
  2722. [](OpenCLDebugInfo100Instructions dbg_inst) {
  2723. return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
  2724. },
  2725. inst, 12)) {
  2726. auto* operand = _.FindDef(inst->word(12));
  2727. if (operand->opcode() != SpvOpVariable &&
  2728. operand->opcode() != SpvOpConstant) {
  2729. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2730. << ext_inst_name() << ": "
  2731. << "expected operand Variable must be a result id of "
  2732. "OpVariable or OpConstant or DebugInfoNone";
  2733. }
  2734. }
  2735. if (num_words == 15) {
  2736. CHECK_DEBUG_OPERAND("Static Member Declaration",
  2737. OpenCLDebugInfo100DebugTypeMember, 14);
  2738. }
  2739. break;
  2740. }
  2741. case OpenCLDebugInfo100DebugInlinedAt: {
  2742. auto validate_scope =
  2743. ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name);
  2744. if (validate_scope != SPV_SUCCESS) return validate_scope;
  2745. if (num_words == 8) {
  2746. CHECK_DEBUG_OPERAND("Inlined", OpenCLDebugInfo100DebugInlinedAt, 7);
  2747. }
  2748. break;
  2749. }
  2750. case OpenCLDebugInfo100DebugValue: {
  2751. CHECK_DEBUG_OPERAND("Local Variable",
  2752. OpenCLDebugInfo100DebugLocalVariable, 5);
  2753. CHECK_DEBUG_OPERAND("Expression", OpenCLDebugInfo100DebugExpression, 7);
  2754. for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
  2755. // TODO: The following code simply checks if it is a const int scalar
  2756. // or a DebugLocalVariable or DebugGlobalVariable, but we have to
  2757. // check it using the same validation for Indexes of OpAccessChain.
  2758. if (!IsConstWithIntScalarType(_, inst, word_index) &&
  2759. !IsDebugVariableWithIntScalarType(_, inst, word_index)) {
  2760. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2761. << ext_inst_name() << ": expected operand Indexes is "
  2762. << "OpConstant, DebugGlobalVariable, or "
  2763. << "type is OpConstant with an integer scalar type";
  2764. }
  2765. }
  2766. break;
  2767. }
  2768. // TODO: Add validation rules for remaining cases as well.
  2769. case OpenCLDebugInfo100DebugTypePtrToMember:
  2770. case OpenCLDebugInfo100DebugTypeTemplateTemplateParameter:
  2771. case OpenCLDebugInfo100DebugTypeTemplateParameterPack:
  2772. case OpenCLDebugInfo100DebugLexicalBlockDiscriminator:
  2773. case OpenCLDebugInfo100DebugInlinedVariable:
  2774. case OpenCLDebugInfo100DebugMacroDef:
  2775. case OpenCLDebugInfo100DebugMacroUndef:
  2776. case OpenCLDebugInfo100DebugImportedEntity:
  2777. break;
  2778. case OpenCLDebugInfo100InstructionsMax:
  2779. assert(0);
  2780. break;
  2781. }
  2782. } else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
  2783. auto import_inst = _.FindDef(inst->GetOperandAs<uint32_t>(2));
  2784. const std::string name(reinterpret_cast<const char*>(
  2785. import_inst->words().data() + import_inst->operands()[1].offset));
  2786. const std::string reflection = "NonSemantic.ClspvReflection.";
  2787. char* end_ptr;
  2788. auto version_string = name.substr(reflection.size());
  2789. if (version_string.empty()) {
  2790. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  2791. << "Missing NonSemantic.ClspvReflection import version";
  2792. }
  2793. uint32_t version = static_cast<uint32_t>(
  2794. std::strtoul(version_string.c_str(), &end_ptr, 10));
  2795. if (end_ptr && *end_ptr != '\0') {
  2796. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  2797. << "NonSemantic.ClspvReflection import does not encode the "
  2798. "version correctly";
  2799. }
  2800. if (version == 0 || version > NonSemanticClspvReflectionRevision) {
  2801. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  2802. << "Unknown NonSemantic.ClspvReflection import version";
  2803. }
  2804. return ValidateClspvReflectionInstruction(_, inst, version);
  2805. }
  2806. return SPV_SUCCESS;
  2807. }
  2808. spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) {
  2809. const SpvOp opcode = inst->opcode();
  2810. if (opcode == SpvOpExtension) return ValidateExtension(_, inst);
  2811. if (opcode == SpvOpExtInstImport) return ValidateExtInstImport(_, inst);
  2812. if (opcode == SpvOpExtInst) return ValidateExtInst(_, inst);
  2813. return SPV_SUCCESS;
  2814. }
  2815. } // namespace val
  2816. } // namespace spvtools