validate_extensions.cpp 122 KB

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