validate_extensions.cpp 153 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845
  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 "NonSemanticShaderDebugInfo100.h"
  20. #include "OpenCLDebugInfo100.h"
  21. #include "source/common_debug_info.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/spirv_constant.h"
  27. #include "source/val/instruction.h"
  28. #include "source/val/validate.h"
  29. #include "source/val/validation_state.h"
  30. #include "spirv/unified1/NonSemanticClspvReflection.h"
  31. namespace spvtools {
  32. namespace val {
  33. namespace {
  34. std::string ReflectionInstructionName(ValidationState_t& _,
  35. const Instruction* inst) {
  36. spv_ext_inst_desc desc = nullptr;
  37. if (_.grammar().lookupExtInst(SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
  38. inst->word(4), &desc) != SPV_SUCCESS ||
  39. !desc) {
  40. return std::string("Unknown ExtInst");
  41. }
  42. std::ostringstream ss;
  43. ss << desc->name;
  44. return ss.str();
  45. }
  46. uint32_t GetSizeTBitWidth(const ValidationState_t& _) {
  47. if (_.addressing_model() == spv::AddressingModel::Physical32) return 32;
  48. if (_.addressing_model() == spv::AddressingModel::Physical64) return 64;
  49. return 0;
  50. }
  51. bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32,
  52. bool must_unsigned) {
  53. auto type = _.FindDef(id);
  54. if (!type || type->opcode() != spv::Op::OpTypeInt) {
  55. return false;
  56. }
  57. if (must_len32 && type->GetOperandAs<uint32_t>(1) != 32) {
  58. return false;
  59. }
  60. return !must_unsigned || type->GetOperandAs<uint32_t>(2) == 0;
  61. }
  62. bool IsUint32Constant(ValidationState_t& _, uint32_t id) {
  63. auto inst = _.FindDef(id);
  64. if (!inst || inst->opcode() != spv::Op::OpConstant) {
  65. return false;
  66. }
  67. return IsIntScalar(_, inst->type_id(), true, true);
  68. }
  69. uint32_t GetUint32Constant(ValidationState_t& _, uint32_t id) {
  70. auto inst = _.FindDef(id);
  71. return inst->word(3);
  72. }
  73. // Check that the operand of a debug info instruction |inst| at |word_index|
  74. // is a result id of an instruction with |expected_opcode|.
  75. spv_result_t ValidateOperandForDebugInfo(
  76. ValidationState_t& _, const std::string& operand_name,
  77. spv::Op expected_opcode, const Instruction* inst, uint32_t word_index,
  78. const std::function<std::string()>& ext_inst_name) {
  79. auto* operand = _.FindDef(inst->word(word_index));
  80. if (operand->opcode() != expected_opcode) {
  81. spv_opcode_desc desc = nullptr;
  82. if (_.grammar().lookupOpcode(expected_opcode, &desc) != SPV_SUCCESS ||
  83. !desc) {
  84. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  85. << ext_inst_name() << ": "
  86. << "expected operand " << operand_name << " is invalid";
  87. }
  88. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  89. << ext_inst_name() << ": "
  90. << "expected operand " << operand_name << " must be a result id of "
  91. << "Op" << desc->name;
  92. }
  93. return SPV_SUCCESS;
  94. }
  95. // For NonSemantic.Shader.DebugInfo.100 check that the operand of a debug info
  96. // instruction |inst| at |word_index| is a result id of a 32-bit integer
  97. // OpConstant instruction. For OpenCL.DebugInfo.100 the parameter is a literal
  98. // word so cannot be validated.
  99. spv_result_t ValidateUint32ConstantOperandForDebugInfo(
  100. ValidationState_t& _, const std::string& operand_name,
  101. const Instruction* inst, uint32_t word_index,
  102. const std::function<std::string()>& ext_inst_name) {
  103. if (!IsUint32Constant(_, inst->word(word_index))) {
  104. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  105. << ext_inst_name() << ": expected operand " << operand_name
  106. << " must be a result id of 32-bit unsigned OpConstant";
  107. }
  108. return SPV_SUCCESS;
  109. }
  110. #define CHECK_OPERAND(NAME, opcode, index) \
  111. do { \
  112. auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  113. ext_inst_name); \
  114. if (result != SPV_SUCCESS) return result; \
  115. } while (0)
  116. #define CHECK_CONST_UINT_OPERAND(NAME, index) \
  117. if (vulkanDebugInfo) { \
  118. auto result = ValidateUint32ConstantOperandForDebugInfo( \
  119. _, NAME, inst, index, ext_inst_name); \
  120. if (result != SPV_SUCCESS) return result; \
  121. }
  122. // True if the operand of a debug info instruction |inst| at |word_index|
  123. // satisfies |expectation| that is given as a function. Otherwise,
  124. // returns false.
  125. bool DoesDebugInfoOperandMatchExpectation(
  126. const ValidationState_t& _,
  127. const std::function<bool(CommonDebugInfoInstructions)>& expectation,
  128. const Instruction* inst, uint32_t word_index) {
  129. if (inst->words().size() <= word_index) return false;
  130. auto* debug_inst = _.FindDef(inst->word(word_index));
  131. if (!spvIsExtendedInstruction(debug_inst->opcode()) ||
  132. (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 &&
  133. debug_inst->ext_inst_type() !=
  134. SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
  135. !expectation(CommonDebugInfoInstructions(debug_inst->word(4)))) {
  136. return false;
  137. }
  138. return true;
  139. }
  140. // Overload for NonSemanticShaderDebugInfo100Instructions.
  141. bool DoesDebugInfoOperandMatchExpectation(
  142. const ValidationState_t& _,
  143. const std::function<bool(NonSemanticShaderDebugInfo100Instructions)>&
  144. expectation,
  145. const Instruction* inst, uint32_t word_index) {
  146. if (inst->words().size() <= word_index) return false;
  147. auto* debug_inst = _.FindDef(inst->word(word_index));
  148. if (!spvIsExtendedInstruction(debug_inst->opcode()) ||
  149. (debug_inst->ext_inst_type() !=
  150. SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
  151. !expectation(
  152. NonSemanticShaderDebugInfo100Instructions(debug_inst->word(4)))) {
  153. return false;
  154. }
  155. return true;
  156. }
  157. // Check that the operand of a debug info instruction |inst| at |word_index|
  158. // is a result id of an debug info instruction whose debug instruction type
  159. // is |expected_debug_inst|.
  160. spv_result_t ValidateDebugInfoOperand(
  161. ValidationState_t& _, const std::string& debug_inst_name,
  162. CommonDebugInfoInstructions expected_debug_inst, const Instruction* inst,
  163. uint32_t word_index, const std::function<std::string()>& ext_inst_name) {
  164. std::function<bool(CommonDebugInfoInstructions)> expectation =
  165. [expected_debug_inst](CommonDebugInfoInstructions dbg_inst) {
  166. return dbg_inst == expected_debug_inst;
  167. };
  168. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  169. return SPV_SUCCESS;
  170. spv_ext_inst_desc desc = nullptr;
  171. if (_.grammar().lookupExtInst(inst->ext_inst_type(), expected_debug_inst,
  172. &desc) != SPV_SUCCESS ||
  173. !desc) {
  174. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  175. << ext_inst_name() << ": "
  176. << "expected operand " << debug_inst_name << " is invalid";
  177. }
  178. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  179. << ext_inst_name() << ": "
  180. << "expected operand " << debug_inst_name << " must be a result id of "
  181. << desc->name;
  182. }
  183. #define CHECK_DEBUG_OPERAND(NAME, debug_opcode, index) \
  184. do { \
  185. auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  186. ext_inst_name); \
  187. if (result != SPV_SUCCESS) return result; \
  188. } while (0)
  189. // Check that the operand of a debug info instruction |inst| at |word_index|
  190. // is a result id of an debug info instruction with DebugTypeBasic.
  191. spv_result_t ValidateOperandBaseType(
  192. ValidationState_t& _, const Instruction* inst, uint32_t word_index,
  193. const std::function<std::string()>& ext_inst_name) {
  194. return ValidateDebugInfoOperand(_, "Base Type", CommonDebugInfoDebugTypeBasic,
  195. inst, word_index, ext_inst_name);
  196. }
  197. // Check that the operand of a debug info instruction |inst| at |word_index|
  198. // is a result id of a debug lexical scope instruction which is one of
  199. // DebugCompilationUnit, DebugFunction, DebugLexicalBlock, or
  200. // DebugTypeComposite.
  201. spv_result_t ValidateOperandLexicalScope(
  202. ValidationState_t& _, const std::string& debug_inst_name,
  203. const Instruction* inst, uint32_t word_index,
  204. const std::function<std::string()>& ext_inst_name) {
  205. std::function<bool(CommonDebugInfoInstructions)> expectation =
  206. [](CommonDebugInfoInstructions dbg_inst) {
  207. return dbg_inst == CommonDebugInfoDebugCompilationUnit ||
  208. dbg_inst == CommonDebugInfoDebugFunction ||
  209. dbg_inst == CommonDebugInfoDebugLexicalBlock ||
  210. dbg_inst == CommonDebugInfoDebugTypeComposite;
  211. };
  212. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  213. return SPV_SUCCESS;
  214. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  215. << ext_inst_name() << ": "
  216. << "expected operand " << debug_inst_name
  217. << " must be a result id of a lexical scope";
  218. }
  219. // Check that the operand of a debug info instruction |inst| at |word_index|
  220. // is a result id of a debug type instruction (See DebugTypeXXX in
  221. // "4.3. Type instructions" section of OpenCL.DebugInfo.100 spec.
  222. spv_result_t ValidateOperandDebugType(
  223. ValidationState_t& _, const std::string& debug_inst_name,
  224. const Instruction* inst, uint32_t word_index,
  225. const std::function<std::string()>& ext_inst_name,
  226. bool allow_template_param) {
  227. // Check for NonSemanticShaderDebugInfo100 specific types.
  228. if (inst->ext_inst_type() ==
  229. SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
  230. std::function<bool(NonSemanticShaderDebugInfo100Instructions)> expectation =
  231. [](NonSemanticShaderDebugInfo100Instructions dbg_inst) {
  232. return dbg_inst == NonSemanticShaderDebugInfo100DebugTypeMatrix;
  233. };
  234. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  235. return SPV_SUCCESS;
  236. }
  237. // Check for common types.
  238. std::function<bool(CommonDebugInfoInstructions)> expectation =
  239. [&allow_template_param](CommonDebugInfoInstructions dbg_inst) {
  240. if (allow_template_param &&
  241. (dbg_inst == CommonDebugInfoDebugTypeTemplateParameter ||
  242. dbg_inst == CommonDebugInfoDebugTypeTemplateTemplateParameter)) {
  243. return true;
  244. }
  245. return CommonDebugInfoDebugTypeBasic <= dbg_inst &&
  246. dbg_inst <= CommonDebugInfoDebugTypeTemplate;
  247. };
  248. if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
  249. return SPV_SUCCESS;
  250. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  251. << ext_inst_name() << ": "
  252. << "expected operand " << debug_inst_name
  253. << " is not a valid debug type";
  254. }
  255. spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _,
  256. const Instruction* inst,
  257. uint32_t version) {
  258. const auto inst_name = ReflectionInstructionName(_, inst);
  259. const auto kernel_id = inst->GetOperandAs<uint32_t>(4);
  260. const auto kernel = _.FindDef(kernel_id);
  261. if (kernel->opcode() != spv::Op::OpFunction) {
  262. return _.diag(SPV_ERROR_INVALID_ID, inst)
  263. << inst_name << " does not reference a function";
  264. }
  265. bool found_kernel = false;
  266. for (auto entry_point : _.entry_points()) {
  267. if (entry_point == kernel_id) {
  268. found_kernel = true;
  269. break;
  270. }
  271. }
  272. if (!found_kernel) {
  273. return _.diag(SPV_ERROR_INVALID_ID, inst)
  274. << inst_name << " does not reference an entry-point";
  275. }
  276. const auto* exec_models = _.GetExecutionModels(kernel_id);
  277. if (!exec_models || exec_models->empty()) {
  278. return _.diag(SPV_ERROR_INVALID_ID, inst)
  279. << inst_name << " does not reference an entry-point";
  280. }
  281. for (auto exec_model : *exec_models) {
  282. if (exec_model != spv::ExecutionModel::GLCompute) {
  283. return _.diag(SPV_ERROR_INVALID_ID, inst)
  284. << inst_name << " must refer only to GLCompute entry-points";
  285. }
  286. }
  287. auto name = _.FindDef(inst->GetOperandAs<uint32_t>(5));
  288. if (!name || name->opcode() != spv::Op::OpString) {
  289. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString";
  290. }
  291. const std::string name_str = name->GetOperandAs<std::string>(1);
  292. bool found = false;
  293. for (auto& desc : _.entry_point_descriptions(kernel_id)) {
  294. if (name_str == desc.name) {
  295. found = true;
  296. break;
  297. }
  298. }
  299. if (!found) {
  300. return _.diag(SPV_ERROR_INVALID_ID, inst)
  301. << "Name must match an entry-point for Kernel";
  302. }
  303. const auto num_operands = inst->operands().size();
  304. if (version < 5 && num_operands > 6) {
  305. return _.diag(SPV_ERROR_INVALID_ID, inst)
  306. << "Version " << version << " of the " << inst_name
  307. << " instruction can only have 2 additional operands";
  308. }
  309. if (num_operands > 6) {
  310. const auto num_args_id = inst->GetOperandAs<uint32_t>(6);
  311. if (!IsUint32Constant(_, num_args_id)) {
  312. return _.diag(SPV_ERROR_INVALID_ID, inst)
  313. << "NumArguments must be a 32-bit unsigned integer OpConstant";
  314. }
  315. }
  316. if (num_operands > 7) {
  317. const auto flags_id = inst->GetOperandAs<uint32_t>(7);
  318. if (!IsUint32Constant(_, flags_id)) {
  319. return _.diag(SPV_ERROR_INVALID_ID, inst)
  320. << "Flags must be a 32-bit unsigned integer OpConstant";
  321. }
  322. }
  323. if (num_operands > 8) {
  324. const auto atts_id = inst->GetOperandAs<uint32_t>(8);
  325. if (_.GetIdOpcode(atts_id) != spv::Op::OpString) {
  326. return _.diag(SPV_ERROR_INVALID_ID, inst)
  327. << "Attributes must be an OpString";
  328. }
  329. }
  330. return SPV_SUCCESS;
  331. }
  332. spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _,
  333. const Instruction* inst) {
  334. const auto num_operands = inst->operands().size();
  335. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(4)) != spv::Op::OpString) {
  336. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString";
  337. }
  338. if (num_operands > 5) {
  339. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(5)) != spv::Op::OpString) {
  340. return _.diag(SPV_ERROR_INVALID_ID, inst)
  341. << "TypeName must be an OpString";
  342. }
  343. }
  344. if (num_operands > 6) {
  345. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  346. return _.diag(SPV_ERROR_INVALID_ID, inst)
  347. << "AddressQualifier must be a 32-bit unsigned integer "
  348. "OpConstant";
  349. }
  350. }
  351. if (num_operands > 7) {
  352. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  353. return _.diag(SPV_ERROR_INVALID_ID, inst)
  354. << "AccessQualifier must be a 32-bit unsigned integer "
  355. "OpConstant";
  356. }
  357. }
  358. if (num_operands > 8) {
  359. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(8))) {
  360. return _.diag(SPV_ERROR_INVALID_ID, inst)
  361. << "TypeQualifier must be a 32-bit unsigned integer "
  362. "OpConstant";
  363. }
  364. }
  365. return SPV_SUCCESS;
  366. }
  367. spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) {
  368. const auto decl_id = inst->GetOperandAs<uint32_t>(4);
  369. const auto decl = _.FindDef(decl_id);
  370. if (!decl || !spvIsExtendedInstruction(decl->opcode())) {
  371. return _.diag(SPV_ERROR_INVALID_ID, inst)
  372. << "Kernel must be a Kernel extended instruction";
  373. }
  374. if (decl->GetOperandAs<uint32_t>(2) != inst->GetOperandAs<uint32_t>(2)) {
  375. return _.diag(SPV_ERROR_INVALID_ID, inst)
  376. << "Kernel must be from the same extended instruction import";
  377. }
  378. const auto ext_inst =
  379. decl->GetOperandAs<NonSemanticClspvReflectionInstructions>(3);
  380. if (ext_inst != NonSemanticClspvReflectionKernel) {
  381. return _.diag(SPV_ERROR_INVALID_ID, inst)
  382. << "Kernel must be a Kernel extended instruction";
  383. }
  384. return SPV_SUCCESS;
  385. }
  386. spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst,
  387. uint32_t info_index) {
  388. auto info = _.FindDef(inst->GetOperandAs<uint32_t>(info_index));
  389. if (!info || !spvIsExtendedInstruction(info->opcode())) {
  390. return _.diag(SPV_ERROR_INVALID_ID, inst)
  391. << "ArgInfo must be an ArgumentInfo extended instruction";
  392. }
  393. if (info->GetOperandAs<uint32_t>(2) != inst->GetOperandAs<uint32_t>(2)) {
  394. return _.diag(SPV_ERROR_INVALID_ID, inst)
  395. << "ArgInfo must be from the same extended instruction import";
  396. }
  397. auto ext_inst = info->GetOperandAs<NonSemanticClspvReflectionInstructions>(3);
  398. if (ext_inst != NonSemanticClspvReflectionArgumentInfo) {
  399. return _.diag(SPV_ERROR_INVALID_ID, inst)
  400. << "ArgInfo must be an ArgumentInfo extended instruction";
  401. }
  402. return SPV_SUCCESS;
  403. }
  404. spv_result_t ValidateClspvReflectionArgumentBuffer(ValidationState_t& _,
  405. const Instruction* inst) {
  406. const auto num_operands = inst->operands().size();
  407. if (auto error = ValidateKernelDecl(_, inst)) {
  408. return error;
  409. }
  410. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  411. return _.diag(SPV_ERROR_INVALID_ID, inst)
  412. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  413. }
  414. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  415. return _.diag(SPV_ERROR_INVALID_ID, inst)
  416. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  417. }
  418. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  419. return _.diag(SPV_ERROR_INVALID_ID, inst)
  420. << "Binding must be a 32-bit unsigned integer OpConstant";
  421. }
  422. if (num_operands == 9) {
  423. if (auto error = ValidateArgInfo(_, inst, 8)) {
  424. return error;
  425. }
  426. }
  427. return SPV_SUCCESS;
  428. }
  429. spv_result_t ValidateClspvReflectionArgumentOffsetBuffer(
  430. ValidationState_t& _, const Instruction* inst) {
  431. const auto num_operands = inst->operands().size();
  432. if (auto error = ValidateKernelDecl(_, inst)) {
  433. return error;
  434. }
  435. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  436. return _.diag(SPV_ERROR_INVALID_ID, inst)
  437. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  438. }
  439. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  440. return _.diag(SPV_ERROR_INVALID_ID, inst)
  441. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  442. }
  443. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  444. return _.diag(SPV_ERROR_INVALID_ID, inst)
  445. << "Binding must be a 32-bit unsigned integer OpConstant";
  446. }
  447. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(8))) {
  448. return _.diag(SPV_ERROR_INVALID_ID, inst)
  449. << "Offset must be a 32-bit unsigned integer OpConstant";
  450. }
  451. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(9))) {
  452. return _.diag(SPV_ERROR_INVALID_ID, inst)
  453. << "Size must be a 32-bit unsigned integer OpConstant";
  454. }
  455. if (num_operands == 11) {
  456. if (auto error = ValidateArgInfo(_, inst, 10)) {
  457. return error;
  458. }
  459. }
  460. return SPV_SUCCESS;
  461. }
  462. spv_result_t ValidateClspvReflectionArgumentPushConstant(
  463. ValidationState_t& _, const Instruction* inst) {
  464. const auto num_operands = inst->operands().size();
  465. if (auto error = ValidateKernelDecl(_, inst)) {
  466. return error;
  467. }
  468. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  469. return _.diag(SPV_ERROR_INVALID_ID, inst)
  470. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  471. }
  472. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  473. return _.diag(SPV_ERROR_INVALID_ID, inst)
  474. << "Offset must be a 32-bit unsigned integer OpConstant";
  475. }
  476. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  477. return _.diag(SPV_ERROR_INVALID_ID, inst)
  478. << "Size must be a 32-bit unsigned integer OpConstant";
  479. }
  480. if (num_operands == 9) {
  481. if (auto error = ValidateArgInfo(_, inst, 8)) {
  482. return error;
  483. }
  484. }
  485. return SPV_SUCCESS;
  486. }
  487. spv_result_t ValidateClspvReflectionArgumentWorkgroup(ValidationState_t& _,
  488. const Instruction* inst) {
  489. const auto num_operands = inst->operands().size();
  490. if (auto error = ValidateKernelDecl(_, inst)) {
  491. return error;
  492. }
  493. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  494. return _.diag(SPV_ERROR_INVALID_ID, inst)
  495. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  496. }
  497. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  498. return _.diag(SPV_ERROR_INVALID_ID, inst)
  499. << "SpecId must be a 32-bit unsigned integer OpConstant";
  500. }
  501. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  502. return _.diag(SPV_ERROR_INVALID_ID, inst)
  503. << "ElemSize must be a 32-bit unsigned integer OpConstant";
  504. }
  505. if (num_operands == 9) {
  506. if (auto error = ValidateArgInfo(_, inst, 8)) {
  507. return error;
  508. }
  509. }
  510. return SPV_SUCCESS;
  511. }
  512. spv_result_t ValidateClspvReflectionSpecConstantTriple(
  513. ValidationState_t& _, const Instruction* inst) {
  514. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  515. return _.diag(SPV_ERROR_INVALID_ID, inst)
  516. << "X must be a 32-bit unsigned integer OpConstant";
  517. }
  518. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  519. return _.diag(SPV_ERROR_INVALID_ID, inst)
  520. << "Y must be a 32-bit unsigned integer OpConstant";
  521. }
  522. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  523. return _.diag(SPV_ERROR_INVALID_ID, inst)
  524. << "Z must be a 32-bit unsigned integer OpConstant";
  525. }
  526. return SPV_SUCCESS;
  527. }
  528. spv_result_t ValidateClspvReflectionSpecConstantWorkDim(
  529. ValidationState_t& _, const Instruction* inst) {
  530. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  531. return _.diag(SPV_ERROR_INVALID_ID, inst)
  532. << "Dim must be a 32-bit unsigned integer OpConstant";
  533. }
  534. return SPV_SUCCESS;
  535. }
  536. spv_result_t ValidateClspvReflectionPushConstant(ValidationState_t& _,
  537. const Instruction* inst) {
  538. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  539. return _.diag(SPV_ERROR_INVALID_ID, inst)
  540. << "Offset must be a 32-bit unsigned integer OpConstant";
  541. }
  542. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  543. return _.diag(SPV_ERROR_INVALID_ID, inst)
  544. << "Size must be a 32-bit unsigned integer OpConstant";
  545. }
  546. return SPV_SUCCESS;
  547. }
  548. spv_result_t ValidateClspvReflectionInitializedData(ValidationState_t& _,
  549. const Instruction* inst) {
  550. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  551. return _.diag(SPV_ERROR_INVALID_ID, inst)
  552. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  553. }
  554. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  555. return _.diag(SPV_ERROR_INVALID_ID, inst)
  556. << "Binding must be a 32-bit unsigned integer OpConstant";
  557. }
  558. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(6)) != spv::Op::OpString) {
  559. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString";
  560. }
  561. return SPV_SUCCESS;
  562. }
  563. spv_result_t ValidateClspvReflectionSampler(ValidationState_t& _,
  564. const Instruction* inst) {
  565. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  566. return _.diag(SPV_ERROR_INVALID_ID, inst)
  567. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  568. }
  569. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  570. return _.diag(SPV_ERROR_INVALID_ID, inst)
  571. << "Binding must be a 32-bit unsigned integer OpConstant";
  572. }
  573. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  574. return _.diag(SPV_ERROR_INVALID_ID, inst)
  575. << "Mask must be a 32-bit unsigned integer OpConstant";
  576. }
  577. return SPV_SUCCESS;
  578. }
  579. spv_result_t ValidateClspvReflectionPropertyRequiredWorkgroupSize(
  580. ValidationState_t& _, const Instruction* inst) {
  581. if (auto error = ValidateKernelDecl(_, inst)) {
  582. return error;
  583. }
  584. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  585. return _.diag(SPV_ERROR_INVALID_ID, inst)
  586. << "X must be a 32-bit unsigned integer OpConstant";
  587. }
  588. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  589. return _.diag(SPV_ERROR_INVALID_ID, inst)
  590. << "Y must be a 32-bit unsigned integer OpConstant";
  591. }
  592. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  593. return _.diag(SPV_ERROR_INVALID_ID, inst)
  594. << "Z must be a 32-bit unsigned integer OpConstant";
  595. }
  596. return SPV_SUCCESS;
  597. }
  598. spv_result_t ValidateClspvReflectionSubgroupMaxSize(ValidationState_t& _,
  599. const Instruction* inst) {
  600. const auto size_id = inst->GetOperandAs<uint32_t>(4);
  601. if (!IsUint32Constant(_, size_id)) {
  602. return _.diag(SPV_ERROR_INVALID_ID, inst)
  603. << "Size must be a 32-bit unsigned integer OpConstant";
  604. }
  605. return SPV_SUCCESS;
  606. }
  607. spv_result_t ValidateClspvReflectionPointerRelocation(ValidationState_t& _,
  608. const Instruction* inst) {
  609. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  610. return _.diag(SPV_ERROR_INVALID_ID, inst)
  611. << "ObjectOffset must be a 32-bit unsigned integer OpConstant";
  612. }
  613. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  614. return _.diag(SPV_ERROR_INVALID_ID, inst)
  615. << "PointerOffset must be a 32-bit unsigned integer OpConstant";
  616. }
  617. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  618. return _.diag(SPV_ERROR_INVALID_ID, inst)
  619. << "PointerSize must be a 32-bit unsigned integer OpConstant";
  620. }
  621. return SPV_SUCCESS;
  622. }
  623. spv_result_t ValidateClspvReflectionImageMetadataPushConstant(
  624. ValidationState_t& _, const Instruction* inst) {
  625. if (auto error = ValidateKernelDecl(_, inst)) {
  626. return error;
  627. }
  628. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  629. return _.diag(SPV_ERROR_INVALID_ID, inst)
  630. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  631. }
  632. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  633. return _.diag(SPV_ERROR_INVALID_ID, inst)
  634. << "Offset must be a 32-bit unsigned integer OpConstant";
  635. }
  636. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  637. return _.diag(SPV_ERROR_INVALID_ID, inst)
  638. << "Size must be a 32-bit unsigned integer OpConstant";
  639. }
  640. return SPV_SUCCESS;
  641. }
  642. spv_result_t ValidateClspvReflectionImageMetadataUniform(
  643. ValidationState_t& _, const Instruction* inst) {
  644. if (auto error = ValidateKernelDecl(_, inst)) {
  645. return error;
  646. }
  647. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  648. return _.diag(SPV_ERROR_INVALID_ID, inst)
  649. << "Ordinal must be a 32-bit unsigned integer OpConstant";
  650. }
  651. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  652. return _.diag(SPV_ERROR_INVALID_ID, inst)
  653. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  654. }
  655. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(7))) {
  656. return _.diag(SPV_ERROR_INVALID_ID, inst)
  657. << "Binding must be a 32-bit unsigned integer OpConstant";
  658. }
  659. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(8))) {
  660. return _.diag(SPV_ERROR_INVALID_ID, inst)
  661. << "Offset must be a 32-bit unsigned integer OpConstant";
  662. }
  663. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(9))) {
  664. return _.diag(SPV_ERROR_INVALID_ID, inst)
  665. << "Size must be a 32-bit unsigned integer OpConstant";
  666. }
  667. return SPV_SUCCESS;
  668. }
  669. spv_result_t ValidateClspvReflectionPushConstantData(ValidationState_t& _,
  670. const Instruction* inst) {
  671. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  672. return _.diag(SPV_ERROR_INVALID_ID, inst)
  673. << "Offset must be a 32-bit unsigned integer OpConstant";
  674. }
  675. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  676. return _.diag(SPV_ERROR_INVALID_ID, inst)
  677. << "Size must be a 32-bit unsigned integer OpConstant";
  678. }
  679. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(6)) != spv::Op::OpString) {
  680. return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString";
  681. }
  682. return SPV_SUCCESS;
  683. }
  684. spv_result_t ValidateClspvReflectionPrintfInfo(ValidationState_t& _,
  685. const Instruction* inst) {
  686. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  687. return _.diag(SPV_ERROR_INVALID_ID, inst)
  688. << "PrintfID must be a 32-bit unsigned integer OpConstant";
  689. }
  690. if (_.GetIdOpcode(inst->GetOperandAs<uint32_t>(5)) != spv::Op::OpString) {
  691. return _.diag(SPV_ERROR_INVALID_ID, inst)
  692. << "FormatString must be an OpString";
  693. }
  694. for (size_t i = 6; i < inst->operands().size(); ++i) {
  695. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(i))) {
  696. return _.diag(SPV_ERROR_INVALID_ID, inst)
  697. << "ArgumentSizes must be a 32-bit unsigned integer OpConstant";
  698. }
  699. }
  700. return SPV_SUCCESS;
  701. }
  702. spv_result_t ValidateClspvReflectionPrintfStorageBuffer(
  703. ValidationState_t& _, const Instruction* inst) {
  704. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  705. return _.diag(SPV_ERROR_INVALID_ID, inst)
  706. << "DescriptorSet must be a 32-bit unsigned integer OpConstant";
  707. }
  708. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  709. return _.diag(SPV_ERROR_INVALID_ID, inst)
  710. << "Binding must be a 32-bit unsigned integer OpConstant";
  711. }
  712. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  713. return _.diag(SPV_ERROR_INVALID_ID, inst)
  714. << "Size must be a 32-bit unsigned integer OpConstant";
  715. }
  716. return SPV_SUCCESS;
  717. }
  718. spv_result_t ValidateClspvReflectionPrintfPushConstant(
  719. ValidationState_t& _, const Instruction* inst) {
  720. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
  721. return _.diag(SPV_ERROR_INVALID_ID, inst)
  722. << "Offset must be a 32-bit unsigned integer OpConstant";
  723. }
  724. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(5))) {
  725. return _.diag(SPV_ERROR_INVALID_ID, inst)
  726. << "Size must be a 32-bit unsigned integer OpConstant";
  727. }
  728. if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(6))) {
  729. return _.diag(SPV_ERROR_INVALID_ID, inst)
  730. << "BufferSize must be a 32-bit unsigned integer OpConstant";
  731. }
  732. return SPV_SUCCESS;
  733. }
  734. spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _,
  735. const Instruction* inst,
  736. uint32_t version) {
  737. if (!_.IsVoidType(inst->type_id())) {
  738. return _.diag(SPV_ERROR_INVALID_ID, inst)
  739. << "Return Type must be OpTypeVoid";
  740. }
  741. uint32_t required_version = 0;
  742. const auto ext_inst =
  743. inst->GetOperandAs<NonSemanticClspvReflectionInstructions>(3);
  744. switch (ext_inst) {
  745. case NonSemanticClspvReflectionKernel:
  746. case NonSemanticClspvReflectionArgumentInfo:
  747. case NonSemanticClspvReflectionArgumentStorageBuffer:
  748. case NonSemanticClspvReflectionArgumentUniform:
  749. case NonSemanticClspvReflectionArgumentPodStorageBuffer:
  750. case NonSemanticClspvReflectionArgumentPodUniform:
  751. case NonSemanticClspvReflectionArgumentPodPushConstant:
  752. case NonSemanticClspvReflectionArgumentSampledImage:
  753. case NonSemanticClspvReflectionArgumentStorageImage:
  754. case NonSemanticClspvReflectionArgumentSampler:
  755. case NonSemanticClspvReflectionArgumentWorkgroup:
  756. case NonSemanticClspvReflectionSpecConstantWorkgroupSize:
  757. case NonSemanticClspvReflectionSpecConstantGlobalOffset:
  758. case NonSemanticClspvReflectionSpecConstantWorkDim:
  759. case NonSemanticClspvReflectionPushConstantGlobalOffset:
  760. case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize:
  761. case NonSemanticClspvReflectionPushConstantGlobalSize:
  762. case NonSemanticClspvReflectionPushConstantRegionOffset:
  763. case NonSemanticClspvReflectionPushConstantNumWorkgroups:
  764. case NonSemanticClspvReflectionPushConstantRegionGroupOffset:
  765. case NonSemanticClspvReflectionConstantDataStorageBuffer:
  766. case NonSemanticClspvReflectionConstantDataUniform:
  767. case NonSemanticClspvReflectionLiteralSampler:
  768. case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize:
  769. required_version = 1;
  770. break;
  771. case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize:
  772. required_version = 2;
  773. break;
  774. case NonSemanticClspvReflectionArgumentPointerPushConstant:
  775. case NonSemanticClspvReflectionArgumentPointerUniform:
  776. case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer:
  777. case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation:
  778. case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant:
  779. case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant:
  780. case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform:
  781. case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform:
  782. required_version = 3;
  783. break;
  784. case NonSemanticClspvReflectionArgumentStorageTexelBuffer:
  785. case NonSemanticClspvReflectionArgumentUniformTexelBuffer:
  786. required_version = 4;
  787. break;
  788. case NonSemanticClspvReflectionConstantDataPointerPushConstant:
  789. case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant:
  790. case NonSemanticClspvReflectionPrintfInfo:
  791. case NonSemanticClspvReflectionPrintfBufferStorageBuffer:
  792. case NonSemanticClspvReflectionPrintfBufferPointerPushConstant:
  793. required_version = 5;
  794. break;
  795. default:
  796. break;
  797. }
  798. if (version < required_version) {
  799. return _.diag(SPV_ERROR_INVALID_ID, inst)
  800. << ReflectionInstructionName(_, inst) << " requires version "
  801. << required_version << ", but parsed version is " << version;
  802. }
  803. switch (ext_inst) {
  804. case NonSemanticClspvReflectionKernel:
  805. return ValidateClspvReflectionKernel(_, inst, version);
  806. case NonSemanticClspvReflectionArgumentInfo:
  807. return ValidateClspvReflectionArgumentInfo(_, inst);
  808. case NonSemanticClspvReflectionArgumentStorageBuffer:
  809. case NonSemanticClspvReflectionArgumentUniform:
  810. case NonSemanticClspvReflectionArgumentSampledImage:
  811. case NonSemanticClspvReflectionArgumentStorageImage:
  812. case NonSemanticClspvReflectionArgumentSampler:
  813. case NonSemanticClspvReflectionArgumentStorageTexelBuffer:
  814. case NonSemanticClspvReflectionArgumentUniformTexelBuffer:
  815. return ValidateClspvReflectionArgumentBuffer(_, inst);
  816. case NonSemanticClspvReflectionArgumentPodStorageBuffer:
  817. case NonSemanticClspvReflectionArgumentPodUniform:
  818. case NonSemanticClspvReflectionArgumentPointerUniform:
  819. return ValidateClspvReflectionArgumentOffsetBuffer(_, inst);
  820. case NonSemanticClspvReflectionArgumentPodPushConstant:
  821. case NonSemanticClspvReflectionArgumentPointerPushConstant:
  822. return ValidateClspvReflectionArgumentPushConstant(_, inst);
  823. case NonSemanticClspvReflectionArgumentWorkgroup:
  824. return ValidateClspvReflectionArgumentWorkgroup(_, inst);
  825. case NonSemanticClspvReflectionSpecConstantWorkgroupSize:
  826. case NonSemanticClspvReflectionSpecConstantGlobalOffset:
  827. return ValidateClspvReflectionSpecConstantTriple(_, inst);
  828. case NonSemanticClspvReflectionSpecConstantWorkDim:
  829. return ValidateClspvReflectionSpecConstantWorkDim(_, inst);
  830. case NonSemanticClspvReflectionPushConstantGlobalOffset:
  831. case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize:
  832. case NonSemanticClspvReflectionPushConstantGlobalSize:
  833. case NonSemanticClspvReflectionPushConstantRegionOffset:
  834. case NonSemanticClspvReflectionPushConstantNumWorkgroups:
  835. case NonSemanticClspvReflectionPushConstantRegionGroupOffset:
  836. return ValidateClspvReflectionPushConstant(_, inst);
  837. case NonSemanticClspvReflectionConstantDataStorageBuffer:
  838. case NonSemanticClspvReflectionConstantDataUniform:
  839. case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer:
  840. return ValidateClspvReflectionInitializedData(_, inst);
  841. case NonSemanticClspvReflectionLiteralSampler:
  842. return ValidateClspvReflectionSampler(_, inst);
  843. case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize:
  844. return ValidateClspvReflectionPropertyRequiredWorkgroupSize(_, inst);
  845. case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize:
  846. return ValidateClspvReflectionSubgroupMaxSize(_, inst);
  847. case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation:
  848. return ValidateClspvReflectionPointerRelocation(_, inst);
  849. case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant:
  850. case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant:
  851. return ValidateClspvReflectionImageMetadataPushConstant(_, inst);
  852. case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform:
  853. case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform:
  854. return ValidateClspvReflectionImageMetadataUniform(_, inst);
  855. case NonSemanticClspvReflectionConstantDataPointerPushConstant:
  856. case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant:
  857. return ValidateClspvReflectionPushConstantData(_, inst);
  858. case NonSemanticClspvReflectionPrintfInfo:
  859. return ValidateClspvReflectionPrintfInfo(_, inst);
  860. case NonSemanticClspvReflectionPrintfBufferStorageBuffer:
  861. return ValidateClspvReflectionPrintfStorageBuffer(_, inst);
  862. case NonSemanticClspvReflectionPrintfBufferPointerPushConstant:
  863. return ValidateClspvReflectionPrintfPushConstant(_, inst);
  864. default:
  865. break;
  866. }
  867. return SPV_SUCCESS;
  868. }
  869. bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _,
  870. Instruction* instr) {
  871. if (instr->opcode() != spv::Op::OpConstant) return false;
  872. if (!_.IsIntScalarType(instr->type_id())) return false;
  873. uint32_t size_in_bits = _.GetBitWidth(instr->type_id());
  874. return size_in_bits == 32 || size_in_bits == 64;
  875. }
  876. bool IsConstWithIntScalarType(ValidationState_t& _, const Instruction* inst,
  877. uint32_t word_index) {
  878. auto* int_scalar_const = _.FindDef(inst->word(word_index));
  879. if (int_scalar_const->opcode() == spv::Op::OpConstant &&
  880. _.IsIntScalarType(int_scalar_const->type_id())) {
  881. return true;
  882. }
  883. return false;
  884. }
  885. bool IsDebugVariableWithIntScalarType(ValidationState_t& _,
  886. const Instruction* inst,
  887. uint32_t word_index) {
  888. auto* dbg_int_scalar_var = _.FindDef(inst->word(word_index));
  889. if (CommonDebugInfoInstructions(dbg_int_scalar_var->word(4)) ==
  890. CommonDebugInfoDebugLocalVariable ||
  891. CommonDebugInfoInstructions(dbg_int_scalar_var->word(4)) ==
  892. CommonDebugInfoDebugGlobalVariable) {
  893. auto* dbg_type = _.FindDef(dbg_int_scalar_var->word(6));
  894. if (CommonDebugInfoInstructions(dbg_type->word(4)) ==
  895. CommonDebugInfoDebugTypeBasic) {
  896. const spv_ext_inst_type_t ext_inst_type =
  897. spv_ext_inst_type_t(inst->ext_inst_type());
  898. const bool vulkanDebugInfo =
  899. ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
  900. uint32_t encoding = dbg_type->word(7);
  901. if (!vulkanDebugInfo || IsUint32Constant(_, encoding)) {
  902. auto ocl_encoding = OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
  903. vulkanDebugInfo ? GetUint32Constant(_, encoding) : encoding);
  904. if (ocl_encoding == OpenCLDebugInfo100Signed ||
  905. ocl_encoding == OpenCLDebugInfo100Unsigned) {
  906. return true;
  907. }
  908. }
  909. }
  910. }
  911. return false;
  912. }
  913. } // anonymous namespace
  914. spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) {
  915. if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) {
  916. std::string extension = GetExtensionString(&(inst->c_inst()));
  917. if (extension ==
  918. ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) ||
  919. extension == ExtensionToString(kSPV_EXT_mesh_shader) ||
  920. extension == ExtensionToString(kSPV_NV_shader_invocation_reorder) ||
  921. extension ==
  922. ExtensionToString(kSPV_NV_cluster_acceleration_structure) ||
  923. extension == ExtensionToString(kSPV_NV_linear_swept_spheres)) {
  924. return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  925. << extension << " extension requires SPIR-V version 1.4 or later.";
  926. }
  927. }
  928. return SPV_SUCCESS;
  929. }
  930. spv_result_t ValidateExtInstImport(ValidationState_t& _,
  931. const Instruction* inst) {
  932. const auto name_id = 1;
  933. if (_.version() <= SPV_SPIRV_VERSION_WORD(1, 5) &&
  934. !_.HasExtension(kSPV_KHR_non_semantic_info)) {
  935. const std::string name = inst->GetOperandAs<std::string>(name_id);
  936. if (name.find("NonSemantic.") == 0) {
  937. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  938. << "NonSemantic extended instruction sets cannot be declared "
  939. "without SPV_KHR_non_semantic_info.";
  940. }
  941. }
  942. return SPV_SUCCESS;
  943. }
  944. spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
  945. const uint32_t result_type = inst->type_id();
  946. const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size());
  947. const uint32_t ext_inst_set = inst->word(3);
  948. const uint32_t ext_inst_index = inst->word(4);
  949. const spv_ext_inst_type_t ext_inst_type =
  950. spv_ext_inst_type_t(inst->ext_inst_type());
  951. auto ext_inst_name = [&_, ext_inst_set, ext_inst_type, ext_inst_index]() {
  952. spv_ext_inst_desc desc = nullptr;
  953. if (_.grammar().lookupExtInst(ext_inst_type, ext_inst_index, &desc) !=
  954. SPV_SUCCESS ||
  955. !desc) {
  956. return std::string("Unknown ExtInst");
  957. }
  958. auto* import_inst = _.FindDef(ext_inst_set);
  959. assert(import_inst);
  960. std::ostringstream ss;
  961. ss << import_inst->GetOperandAs<std::string>(1);
  962. ss << " ";
  963. ss << desc->name;
  964. return ss.str();
  965. };
  966. if (ext_inst_type == SPV_EXT_INST_TYPE_GLSL_STD_450) {
  967. const GLSLstd450 ext_inst_key = GLSLstd450(ext_inst_index);
  968. switch (ext_inst_key) {
  969. case GLSLstd450Round:
  970. case GLSLstd450RoundEven:
  971. case GLSLstd450FAbs:
  972. case GLSLstd450Trunc:
  973. case GLSLstd450FSign:
  974. case GLSLstd450Floor:
  975. case GLSLstd450Ceil:
  976. case GLSLstd450Fract:
  977. case GLSLstd450Sqrt:
  978. case GLSLstd450InverseSqrt:
  979. case GLSLstd450FMin:
  980. case GLSLstd450FMax:
  981. case GLSLstd450FClamp:
  982. case GLSLstd450FMix:
  983. case GLSLstd450Step:
  984. case GLSLstd450SmoothStep:
  985. case GLSLstd450Fma:
  986. case GLSLstd450Normalize:
  987. case GLSLstd450FaceForward:
  988. case GLSLstd450Reflect:
  989. case GLSLstd450NMin:
  990. case GLSLstd450NMax:
  991. case GLSLstd450NClamp: {
  992. bool supportsCoopVec =
  993. (ext_inst_key == GLSLstd450FMin || ext_inst_key == GLSLstd450FMax ||
  994. ext_inst_key == GLSLstd450FClamp ||
  995. ext_inst_key == GLSLstd450NMin || ext_inst_key == GLSLstd450NMax ||
  996. ext_inst_key == GLSLstd450NClamp ||
  997. ext_inst_key == GLSLstd450Step || ext_inst_key == GLSLstd450Fma);
  998. if (!_.IsFloatScalarOrVectorType(result_type) &&
  999. !(supportsCoopVec &&
  1000. _.IsFloatCooperativeVectorNVType(result_type))) {
  1001. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1002. << ext_inst_name() << ": "
  1003. << "expected Result Type to be a float scalar or vector type";
  1004. }
  1005. for (uint32_t operand_index = 4; operand_index < num_operands;
  1006. ++operand_index) {
  1007. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1008. if (result_type != operand_type) {
  1009. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1010. << ext_inst_name() << ": "
  1011. << "expected types of all operands to be equal to Result "
  1012. "Type";
  1013. }
  1014. }
  1015. break;
  1016. }
  1017. case GLSLstd450SAbs:
  1018. case GLSLstd450SSign:
  1019. case GLSLstd450UMin:
  1020. case GLSLstd450SMin:
  1021. case GLSLstd450UMax:
  1022. case GLSLstd450SMax:
  1023. case GLSLstd450UClamp:
  1024. case GLSLstd450SClamp:
  1025. case GLSLstd450FindILsb:
  1026. case GLSLstd450FindUMsb:
  1027. case GLSLstd450FindSMsb: {
  1028. bool supportsCoopVec =
  1029. (ext_inst_key == GLSLstd450UMin || ext_inst_key == GLSLstd450UMax ||
  1030. ext_inst_key == GLSLstd450UClamp ||
  1031. ext_inst_key == GLSLstd450SMin || ext_inst_key == GLSLstd450SMax ||
  1032. ext_inst_key == GLSLstd450SClamp);
  1033. if (!_.IsIntScalarOrVectorType(result_type) &&
  1034. !(supportsCoopVec && _.IsIntCooperativeVectorNVType(result_type))) {
  1035. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1036. << ext_inst_name() << ": "
  1037. << "expected Result Type to be an int scalar or vector type";
  1038. }
  1039. const uint32_t result_type_bit_width = _.GetBitWidth(result_type);
  1040. const uint32_t result_type_dimension = _.GetDimension(result_type);
  1041. for (uint32_t operand_index = 4; operand_index < num_operands;
  1042. ++operand_index) {
  1043. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1044. if (!operand_type ||
  1045. (!_.IsIntScalarOrVectorType(operand_type) &&
  1046. !(supportsCoopVec &&
  1047. _.IsIntCooperativeVectorNVType(operand_type)))) {
  1048. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1049. << ext_inst_name() << ": "
  1050. << "expected all operands to be int scalars or vectors";
  1051. }
  1052. if (result_type_dimension != _.GetDimension(operand_type)) {
  1053. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1054. << ext_inst_name() << ": "
  1055. << "expected all operands to have the same dimension as "
  1056. << "Result Type";
  1057. }
  1058. if (result_type_bit_width != _.GetBitWidth(operand_type)) {
  1059. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1060. << ext_inst_name() << ": "
  1061. << "expected all operands to have the same bit width as "
  1062. << "Result Type";
  1063. }
  1064. if (ext_inst_key == GLSLstd450FindUMsb ||
  1065. ext_inst_key == GLSLstd450FindSMsb) {
  1066. if (result_type_bit_width != 32) {
  1067. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1068. << ext_inst_name() << ": "
  1069. << "this instruction is currently limited to 32-bit width "
  1070. << "components";
  1071. }
  1072. }
  1073. }
  1074. break;
  1075. }
  1076. case GLSLstd450Radians:
  1077. case GLSLstd450Degrees:
  1078. case GLSLstd450Sin:
  1079. case GLSLstd450Cos:
  1080. case GLSLstd450Tan:
  1081. case GLSLstd450Asin:
  1082. case GLSLstd450Acos:
  1083. case GLSLstd450Atan:
  1084. case GLSLstd450Sinh:
  1085. case GLSLstd450Cosh:
  1086. case GLSLstd450Tanh:
  1087. case GLSLstd450Asinh:
  1088. case GLSLstd450Acosh:
  1089. case GLSLstd450Atanh:
  1090. case GLSLstd450Exp:
  1091. case GLSLstd450Exp2:
  1092. case GLSLstd450Log:
  1093. case GLSLstd450Log2:
  1094. case GLSLstd450Atan2:
  1095. case GLSLstd450Pow: {
  1096. bool supportsCoopVec =
  1097. (ext_inst_key == GLSLstd450Atan || ext_inst_key == GLSLstd450Tanh ||
  1098. ext_inst_key == GLSLstd450Exp || ext_inst_key == GLSLstd450Log);
  1099. if (!_.IsFloatScalarOrVectorType(result_type) &&
  1100. !(supportsCoopVec &&
  1101. _.IsFloatCooperativeVectorNVType(result_type))) {
  1102. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1103. << ext_inst_name() << ": "
  1104. << "expected Result Type to be a 16 or 32-bit scalar or "
  1105. "vector float type";
  1106. }
  1107. const uint32_t result_type_bit_width = _.GetBitWidth(result_type);
  1108. if (result_type_bit_width != 16 && result_type_bit_width != 32) {
  1109. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1110. << ext_inst_name() << ": "
  1111. << "expected Result Type to be a 16 or 32-bit scalar or "
  1112. "vector float type";
  1113. }
  1114. for (uint32_t operand_index = 4; operand_index < num_operands;
  1115. ++operand_index) {
  1116. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1117. if (result_type != operand_type) {
  1118. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1119. << ext_inst_name() << ": "
  1120. << "expected types of all operands to be equal to Result "
  1121. "Type";
  1122. }
  1123. }
  1124. break;
  1125. }
  1126. case GLSLstd450Determinant: {
  1127. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1128. uint32_t num_rows = 0;
  1129. uint32_t num_cols = 0;
  1130. uint32_t col_type = 0;
  1131. uint32_t component_type = 0;
  1132. if (!_.GetMatrixTypeInfo(x_type, &num_rows, &num_cols, &col_type,
  1133. &component_type) ||
  1134. num_rows != num_cols) {
  1135. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1136. << ext_inst_name() << ": "
  1137. << "expected operand X to be a square matrix";
  1138. }
  1139. if (result_type != component_type) {
  1140. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1141. << ext_inst_name() << ": "
  1142. << "expected operand X component type to be equal to "
  1143. << "Result Type";
  1144. }
  1145. break;
  1146. }
  1147. case GLSLstd450MatrixInverse: {
  1148. uint32_t num_rows = 0;
  1149. uint32_t num_cols = 0;
  1150. uint32_t col_type = 0;
  1151. uint32_t component_type = 0;
  1152. if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type,
  1153. &component_type) ||
  1154. num_rows != num_cols) {
  1155. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1156. << ext_inst_name() << ": "
  1157. << "expected Result Type to be a square matrix";
  1158. }
  1159. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1160. if (result_type != x_type) {
  1161. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1162. << ext_inst_name() << ": "
  1163. << "expected operand X type to be equal to Result Type";
  1164. }
  1165. break;
  1166. }
  1167. case GLSLstd450Modf: {
  1168. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1169. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1170. << ext_inst_name() << ": "
  1171. << "expected Result Type to be a scalar or vector float type";
  1172. }
  1173. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1174. const uint32_t i_type = _.GetOperandTypeId(inst, 5);
  1175. if (x_type != result_type) {
  1176. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1177. << ext_inst_name() << ": "
  1178. << "expected operand X type to be equal to Result Type";
  1179. }
  1180. spv::StorageClass i_storage_class;
  1181. uint32_t i_data_type = 0;
  1182. if (!_.GetPointerTypeInfo(i_type, &i_data_type, &i_storage_class)) {
  1183. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1184. << ext_inst_name() << ": "
  1185. << "expected operand I to be a pointer";
  1186. }
  1187. if (i_data_type != result_type) {
  1188. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1189. << ext_inst_name() << ": "
  1190. << "expected operand I data type to be equal to Result Type";
  1191. }
  1192. break;
  1193. }
  1194. case GLSLstd450ModfStruct: {
  1195. std::vector<uint32_t> result_types;
  1196. if (!_.GetStructMemberTypes(result_type, &result_types) ||
  1197. result_types.size() != 2 ||
  1198. !_.IsFloatScalarOrVectorType(result_types[0]) ||
  1199. result_types[1] != result_types[0]) {
  1200. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1201. << ext_inst_name() << ": "
  1202. << "expected Result Type to be a struct with two identical "
  1203. << "scalar or vector float type members";
  1204. }
  1205. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1206. if (x_type != result_types[0]) {
  1207. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1208. << ext_inst_name() << ": "
  1209. << "expected operand X type to be equal to members of "
  1210. << "Result Type struct";
  1211. }
  1212. break;
  1213. }
  1214. case GLSLstd450Frexp: {
  1215. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1216. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1217. << ext_inst_name() << ": "
  1218. << "expected Result Type to be a scalar or vector float type";
  1219. }
  1220. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1221. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  1222. if (x_type != result_type) {
  1223. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1224. << ext_inst_name() << ": "
  1225. << "expected operand X type to be equal to Result Type";
  1226. }
  1227. spv::StorageClass exp_storage_class;
  1228. uint32_t exp_data_type = 0;
  1229. if (!_.GetPointerTypeInfo(exp_type, &exp_data_type,
  1230. &exp_storage_class)) {
  1231. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1232. << ext_inst_name() << ": "
  1233. << "expected operand Exp to be a pointer";
  1234. }
  1235. if (!_.IsIntScalarOrVectorType(exp_data_type) ||
  1236. (!_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  1237. _.GetBitWidth(exp_data_type) != 32) ||
  1238. (_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  1239. _.GetBitWidth(exp_data_type) != 16 &&
  1240. _.GetBitWidth(exp_data_type) != 32)) {
  1241. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1242. << ext_inst_name() << ": "
  1243. << "expected operand Exp data type to be a "
  1244. << (_.HasExtension(kSPV_AMD_gpu_shader_int16)
  1245. ? "16-bit or 32-bit "
  1246. : "32-bit ")
  1247. << "int scalar or vector type";
  1248. }
  1249. if (_.GetDimension(result_type) != _.GetDimension(exp_data_type)) {
  1250. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1251. << ext_inst_name() << ": "
  1252. << "expected operand Exp data type to have the same component "
  1253. << "number as Result Type";
  1254. }
  1255. break;
  1256. }
  1257. case GLSLstd450Ldexp: {
  1258. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1259. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1260. << ext_inst_name() << ": "
  1261. << "expected Result Type to be a scalar or vector float type";
  1262. }
  1263. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1264. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  1265. if (x_type != result_type) {
  1266. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1267. << ext_inst_name() << ": "
  1268. << "expected operand X type to be equal to Result Type";
  1269. }
  1270. if (!_.IsIntScalarOrVectorType(exp_type)) {
  1271. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1272. << ext_inst_name() << ": "
  1273. << "expected operand Exp to be a 32-bit int scalar "
  1274. << "or vector type";
  1275. }
  1276. if (_.GetDimension(result_type) != _.GetDimension(exp_type)) {
  1277. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1278. << ext_inst_name() << ": "
  1279. << "expected operand Exp to have the same component "
  1280. << "number as Result Type";
  1281. }
  1282. break;
  1283. }
  1284. case GLSLstd450FrexpStruct: {
  1285. std::vector<uint32_t> result_types;
  1286. if (!_.GetStructMemberTypes(result_type, &result_types) ||
  1287. result_types.size() != 2 ||
  1288. !_.IsFloatScalarOrVectorType(result_types[0]) ||
  1289. !_.IsIntScalarOrVectorType(result_types[1]) ||
  1290. (!_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  1291. _.GetBitWidth(result_types[1]) != 32) ||
  1292. (_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  1293. _.GetBitWidth(result_types[1]) != 16 &&
  1294. _.GetBitWidth(result_types[1]) != 32) ||
  1295. _.GetDimension(result_types[0]) !=
  1296. _.GetDimension(result_types[1])) {
  1297. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1298. << ext_inst_name() << ": "
  1299. << "expected Result Type to be a struct with two members, "
  1300. << "first member a float scalar or vector, second member a "
  1301. << (_.HasExtension(kSPV_AMD_gpu_shader_int16)
  1302. ? "16-bit or 32-bit "
  1303. : "32-bit ")
  1304. << "int scalar or vector with the same number of "
  1305. << "components as the first member";
  1306. }
  1307. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1308. if (x_type != result_types[0]) {
  1309. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1310. << ext_inst_name() << ": "
  1311. << "expected operand X type to be equal to the first member "
  1312. << "of Result Type struct";
  1313. }
  1314. break;
  1315. }
  1316. case GLSLstd450PackSnorm4x8:
  1317. case GLSLstd450PackUnorm4x8: {
  1318. if (!_.IsIntScalarType(result_type) ||
  1319. _.GetBitWidth(result_type) != 32) {
  1320. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1321. << ext_inst_name() << ": "
  1322. << "expected Result Type to be 32-bit int scalar type";
  1323. }
  1324. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1325. if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 4 ||
  1326. _.GetBitWidth(v_type) != 32) {
  1327. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1328. << ext_inst_name() << ": "
  1329. << "expected operand V to be a 32-bit float vector of size 4";
  1330. }
  1331. break;
  1332. }
  1333. case GLSLstd450PackSnorm2x16:
  1334. case GLSLstd450PackUnorm2x16:
  1335. case GLSLstd450PackHalf2x16: {
  1336. if (!_.IsIntScalarType(result_type) ||
  1337. _.GetBitWidth(result_type) != 32) {
  1338. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1339. << ext_inst_name() << ": "
  1340. << "expected Result Type to be 32-bit int scalar type";
  1341. }
  1342. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1343. if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 2 ||
  1344. _.GetBitWidth(v_type) != 32) {
  1345. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1346. << ext_inst_name() << ": "
  1347. << "expected operand V to be a 32-bit float vector of size 2";
  1348. }
  1349. break;
  1350. }
  1351. case GLSLstd450PackDouble2x32: {
  1352. if (!_.IsFloatScalarType(result_type) ||
  1353. _.GetBitWidth(result_type) != 64) {
  1354. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1355. << ext_inst_name() << ": "
  1356. << "expected Result Type to be 64-bit float scalar type";
  1357. }
  1358. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1359. if (!_.IsIntVectorType(v_type) || _.GetDimension(v_type) != 2 ||
  1360. _.GetBitWidth(v_type) != 32) {
  1361. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1362. << ext_inst_name() << ": "
  1363. << "expected operand V to be a 32-bit int vector of size 2";
  1364. }
  1365. break;
  1366. }
  1367. case GLSLstd450UnpackSnorm4x8:
  1368. case GLSLstd450UnpackUnorm4x8: {
  1369. if (!_.IsFloatVectorType(result_type) ||
  1370. _.GetDimension(result_type) != 4 ||
  1371. _.GetBitWidth(result_type) != 32) {
  1372. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1373. << ext_inst_name() << ": "
  1374. << "expected Result Type to be a 32-bit float vector of size "
  1375. "4";
  1376. }
  1377. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1378. if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) {
  1379. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1380. << ext_inst_name() << ": "
  1381. << "expected operand P to be a 32-bit int scalar";
  1382. }
  1383. break;
  1384. }
  1385. case GLSLstd450UnpackSnorm2x16:
  1386. case GLSLstd450UnpackUnorm2x16:
  1387. case GLSLstd450UnpackHalf2x16: {
  1388. if (!_.IsFloatVectorType(result_type) ||
  1389. _.GetDimension(result_type) != 2 ||
  1390. _.GetBitWidth(result_type) != 32) {
  1391. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1392. << ext_inst_name() << ": "
  1393. << "expected Result Type to be a 32-bit float vector of size "
  1394. "2";
  1395. }
  1396. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1397. if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) {
  1398. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1399. << ext_inst_name() << ": "
  1400. << "expected operand P to be a 32-bit int scalar";
  1401. }
  1402. break;
  1403. }
  1404. case GLSLstd450UnpackDouble2x32: {
  1405. if (!_.IsIntVectorType(result_type) ||
  1406. _.GetDimension(result_type) != 2 ||
  1407. _.GetBitWidth(result_type) != 32) {
  1408. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1409. << ext_inst_name() << ": "
  1410. << "expected Result Type to be a 32-bit int vector of size "
  1411. "2";
  1412. }
  1413. const uint32_t v_type = _.GetOperandTypeId(inst, 4);
  1414. if (!_.IsFloatScalarType(v_type) || _.GetBitWidth(v_type) != 64) {
  1415. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1416. << ext_inst_name() << ": "
  1417. << "expected operand V to be a 64-bit float scalar";
  1418. }
  1419. break;
  1420. }
  1421. case GLSLstd450Length: {
  1422. if (!_.IsFloatScalarType(result_type)) {
  1423. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1424. << ext_inst_name() << ": "
  1425. << "expected Result Type to be a float scalar type";
  1426. }
  1427. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1428. if (!_.IsFloatScalarOrVectorType(x_type)) {
  1429. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1430. << ext_inst_name() << ": "
  1431. << "expected operand X to be of float scalar or vector type";
  1432. }
  1433. if (result_type != _.GetComponentType(x_type)) {
  1434. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1435. << ext_inst_name() << ": "
  1436. << "expected operand X component type to be equal to Result "
  1437. "Type";
  1438. }
  1439. break;
  1440. }
  1441. case GLSLstd450Distance: {
  1442. if (!_.IsFloatScalarType(result_type)) {
  1443. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1444. << ext_inst_name() << ": "
  1445. << "expected Result Type to be a float scalar type";
  1446. }
  1447. const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
  1448. if (!_.IsFloatScalarOrVectorType(p0_type)) {
  1449. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1450. << ext_inst_name() << ": "
  1451. << "expected operand P0 to be of float scalar or vector type";
  1452. }
  1453. if (result_type != _.GetComponentType(p0_type)) {
  1454. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1455. << ext_inst_name() << ": "
  1456. << "expected operand P0 component type to be equal to "
  1457. << "Result Type";
  1458. }
  1459. const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
  1460. if (!_.IsFloatScalarOrVectorType(p1_type)) {
  1461. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1462. << ext_inst_name() << ": "
  1463. << "expected operand P1 to be of float scalar or vector type";
  1464. }
  1465. if (result_type != _.GetComponentType(p1_type)) {
  1466. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1467. << ext_inst_name() << ": "
  1468. << "expected operand P1 component type to be equal to "
  1469. << "Result Type";
  1470. }
  1471. if (_.GetDimension(p0_type) != _.GetDimension(p1_type)) {
  1472. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1473. << ext_inst_name() << ": "
  1474. << "expected operands P0 and P1 to have the same number of "
  1475. << "components";
  1476. }
  1477. break;
  1478. }
  1479. case GLSLstd450Cross: {
  1480. if (!_.IsFloatVectorType(result_type)) {
  1481. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1482. << ext_inst_name() << ": "
  1483. << "expected Result Type to be a float vector type";
  1484. }
  1485. if (_.GetDimension(result_type) != 3) {
  1486. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1487. << ext_inst_name() << ": "
  1488. << "expected Result Type to have 3 components";
  1489. }
  1490. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1491. const uint32_t y_type = _.GetOperandTypeId(inst, 5);
  1492. if (x_type != result_type) {
  1493. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1494. << ext_inst_name() << ": "
  1495. << "expected operand X type to be equal to Result Type";
  1496. }
  1497. if (y_type != result_type) {
  1498. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1499. << ext_inst_name() << ": "
  1500. << "expected operand Y type to be equal to Result Type";
  1501. }
  1502. break;
  1503. }
  1504. case GLSLstd450Refract: {
  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 i_type = _.GetOperandTypeId(inst, 4);
  1511. const uint32_t n_type = _.GetOperandTypeId(inst, 5);
  1512. const uint32_t eta_type = _.GetOperandTypeId(inst, 6);
  1513. if (result_type != i_type) {
  1514. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1515. << ext_inst_name() << ": "
  1516. << "expected operand I to be of type equal to Result Type";
  1517. }
  1518. if (result_type != n_type) {
  1519. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1520. << ext_inst_name() << ": "
  1521. << "expected operand N to be of type equal to Result Type";
  1522. }
  1523. if (!_.IsFloatScalarType(eta_type)) {
  1524. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1525. << ext_inst_name() << ": "
  1526. << "expected operand Eta to be a float scalar";
  1527. }
  1528. break;
  1529. }
  1530. case GLSLstd450InterpolateAtCentroid:
  1531. case GLSLstd450InterpolateAtSample:
  1532. case GLSLstd450InterpolateAtOffset: {
  1533. if (!_.HasCapability(spv::Capability::InterpolationFunction)) {
  1534. return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  1535. << ext_inst_name()
  1536. << " requires capability InterpolationFunction";
  1537. }
  1538. if (!_.IsFloatScalarOrVectorType(result_type) ||
  1539. _.GetBitWidth(result_type) != 32) {
  1540. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1541. << ext_inst_name() << ": "
  1542. << "expected Result Type to be a 32-bit float scalar "
  1543. << "or vector type";
  1544. }
  1545. // If HLSL legalization and first operand is an OpLoad, use load
  1546. // pointer as the interpolant lvalue. Else use interpolate first
  1547. // operand.
  1548. uint32_t interp_id = inst->GetOperandAs<uint32_t>(4);
  1549. auto* interp_inst = _.FindDef(interp_id);
  1550. uint32_t interpolant_type = (_.options()->before_hlsl_legalization &&
  1551. interp_inst->opcode() == spv::Op::OpLoad)
  1552. ? _.GetOperandTypeId(interp_inst, 2)
  1553. : _.GetOperandTypeId(inst, 4);
  1554. spv::StorageClass interpolant_storage_class;
  1555. uint32_t interpolant_data_type = 0;
  1556. if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type,
  1557. &interpolant_storage_class)) {
  1558. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1559. << ext_inst_name() << ": "
  1560. << "expected Interpolant to be a pointer";
  1561. }
  1562. if (result_type != interpolant_data_type) {
  1563. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1564. << ext_inst_name() << ": "
  1565. << "expected Interpolant data type to be equal to Result Type";
  1566. }
  1567. if (interpolant_storage_class != spv::StorageClass::Input) {
  1568. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1569. << ext_inst_name() << ": "
  1570. << "expected Interpolant storage class to be Input";
  1571. }
  1572. if (ext_inst_key == GLSLstd450InterpolateAtSample) {
  1573. const uint32_t sample_type = _.GetOperandTypeId(inst, 5);
  1574. if (!_.IsIntScalarType(sample_type) ||
  1575. _.GetBitWidth(sample_type) != 32) {
  1576. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1577. << ext_inst_name() << ": "
  1578. << "expected Sample to be 32-bit integer";
  1579. }
  1580. }
  1581. if (ext_inst_key == GLSLstd450InterpolateAtOffset) {
  1582. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  1583. if (!_.IsFloatVectorType(offset_type) ||
  1584. _.GetDimension(offset_type) != 2 ||
  1585. _.GetBitWidth(offset_type) != 32) {
  1586. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1587. << ext_inst_name() << ": "
  1588. << "expected Offset to be a vector of 2 32-bit floats";
  1589. }
  1590. }
  1591. _.function(inst->function()->id())
  1592. ->RegisterExecutionModelLimitation(
  1593. spv::ExecutionModel::Fragment,
  1594. ext_inst_name() +
  1595. std::string(" requires Fragment execution model"));
  1596. break;
  1597. }
  1598. case GLSLstd450IMix: {
  1599. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1600. << "Extended instruction GLSLstd450IMix is not supported";
  1601. }
  1602. case GLSLstd450Bad: {
  1603. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1604. << "Encountered extended instruction GLSLstd450Bad";
  1605. }
  1606. case GLSLstd450Count: {
  1607. assert(0);
  1608. break;
  1609. }
  1610. }
  1611. } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_STD) {
  1612. const OpenCLLIB::Entrypoints ext_inst_key =
  1613. OpenCLLIB::Entrypoints(ext_inst_index);
  1614. switch (ext_inst_key) {
  1615. case OpenCLLIB::Acos:
  1616. case OpenCLLIB::Acosh:
  1617. case OpenCLLIB::Acospi:
  1618. case OpenCLLIB::Asin:
  1619. case OpenCLLIB::Asinh:
  1620. case OpenCLLIB::Asinpi:
  1621. case OpenCLLIB::Atan:
  1622. case OpenCLLIB::Atan2:
  1623. case OpenCLLIB::Atanh:
  1624. case OpenCLLIB::Atanpi:
  1625. case OpenCLLIB::Atan2pi:
  1626. case OpenCLLIB::Cbrt:
  1627. case OpenCLLIB::Ceil:
  1628. case OpenCLLIB::Copysign:
  1629. case OpenCLLIB::Cos:
  1630. case OpenCLLIB::Cosh:
  1631. case OpenCLLIB::Cospi:
  1632. case OpenCLLIB::Erfc:
  1633. case OpenCLLIB::Erf:
  1634. case OpenCLLIB::Exp:
  1635. case OpenCLLIB::Exp2:
  1636. case OpenCLLIB::Exp10:
  1637. case OpenCLLIB::Expm1:
  1638. case OpenCLLIB::Fabs:
  1639. case OpenCLLIB::Fdim:
  1640. case OpenCLLIB::Floor:
  1641. case OpenCLLIB::Fma:
  1642. case OpenCLLIB::Fmax:
  1643. case OpenCLLIB::Fmin:
  1644. case OpenCLLIB::Fmod:
  1645. case OpenCLLIB::Hypot:
  1646. case OpenCLLIB::Lgamma:
  1647. case OpenCLLIB::Log:
  1648. case OpenCLLIB::Log2:
  1649. case OpenCLLIB::Log10:
  1650. case OpenCLLIB::Log1p:
  1651. case OpenCLLIB::Logb:
  1652. case OpenCLLIB::Mad:
  1653. case OpenCLLIB::Maxmag:
  1654. case OpenCLLIB::Minmag:
  1655. case OpenCLLIB::Nextafter:
  1656. case OpenCLLIB::Pow:
  1657. case OpenCLLIB::Powr:
  1658. case OpenCLLIB::Remainder:
  1659. case OpenCLLIB::Rint:
  1660. case OpenCLLIB::Round:
  1661. case OpenCLLIB::Rsqrt:
  1662. case OpenCLLIB::Sin:
  1663. case OpenCLLIB::Sinh:
  1664. case OpenCLLIB::Sinpi:
  1665. case OpenCLLIB::Sqrt:
  1666. case OpenCLLIB::Tan:
  1667. case OpenCLLIB::Tanh:
  1668. case OpenCLLIB::Tanpi:
  1669. case OpenCLLIB::Tgamma:
  1670. case OpenCLLIB::Trunc:
  1671. case OpenCLLIB::Half_cos:
  1672. case OpenCLLIB::Half_divide:
  1673. case OpenCLLIB::Half_exp:
  1674. case OpenCLLIB::Half_exp2:
  1675. case OpenCLLIB::Half_exp10:
  1676. case OpenCLLIB::Half_log:
  1677. case OpenCLLIB::Half_log2:
  1678. case OpenCLLIB::Half_log10:
  1679. case OpenCLLIB::Half_powr:
  1680. case OpenCLLIB::Half_recip:
  1681. case OpenCLLIB::Half_rsqrt:
  1682. case OpenCLLIB::Half_sin:
  1683. case OpenCLLIB::Half_sqrt:
  1684. case OpenCLLIB::Half_tan:
  1685. case OpenCLLIB::Native_cos:
  1686. case OpenCLLIB::Native_divide:
  1687. case OpenCLLIB::Native_exp:
  1688. case OpenCLLIB::Native_exp2:
  1689. case OpenCLLIB::Native_exp10:
  1690. case OpenCLLIB::Native_log:
  1691. case OpenCLLIB::Native_log2:
  1692. case OpenCLLIB::Native_log10:
  1693. case OpenCLLIB::Native_powr:
  1694. case OpenCLLIB::Native_recip:
  1695. case OpenCLLIB::Native_rsqrt:
  1696. case OpenCLLIB::Native_sin:
  1697. case OpenCLLIB::Native_sqrt:
  1698. case OpenCLLIB::Native_tan:
  1699. case OpenCLLIB::FClamp:
  1700. case OpenCLLIB::Degrees:
  1701. case OpenCLLIB::FMax_common:
  1702. case OpenCLLIB::FMin_common:
  1703. case OpenCLLIB::Mix:
  1704. case OpenCLLIB::Radians:
  1705. case OpenCLLIB::Step:
  1706. case OpenCLLIB::Smoothstep:
  1707. case OpenCLLIB::Sign: {
  1708. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1709. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1710. << ext_inst_name() << ": "
  1711. << "expected Result Type to be a float scalar or vector type";
  1712. }
  1713. const uint32_t num_components = _.GetDimension(result_type);
  1714. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1715. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1716. << ext_inst_name() << ": "
  1717. << "expected Result Type to be a scalar or a vector with 2, "
  1718. "3, 4, 8 or 16 components";
  1719. }
  1720. for (uint32_t operand_index = 4; operand_index < num_operands;
  1721. ++operand_index) {
  1722. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1723. if (result_type != operand_type) {
  1724. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1725. << ext_inst_name() << ": "
  1726. << "expected types of all operands to be equal to Result "
  1727. "Type";
  1728. }
  1729. }
  1730. break;
  1731. }
  1732. case OpenCLLIB::Fract:
  1733. case OpenCLLIB::Modf:
  1734. case OpenCLLIB::Sincos: {
  1735. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1736. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1737. << ext_inst_name() << ": "
  1738. << "expected Result Type to be a float scalar or vector type";
  1739. }
  1740. const uint32_t num_components = _.GetDimension(result_type);
  1741. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1742. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1743. << ext_inst_name() << ": "
  1744. << "expected Result Type to be a scalar or a vector with 2, "
  1745. "3, 4, 8 or 16 components";
  1746. }
  1747. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1748. if (result_type != x_type) {
  1749. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1750. << ext_inst_name() << ": "
  1751. << "expected type of operand X to be equal to Result Type";
  1752. }
  1753. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  1754. spv::StorageClass p_storage_class;
  1755. uint32_t p_data_type = 0;
  1756. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1757. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1758. << ext_inst_name() << ": "
  1759. << "expected the last operand to be a pointer";
  1760. }
  1761. if (p_storage_class != spv::StorageClass::Generic &&
  1762. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  1763. p_storage_class != spv::StorageClass::Workgroup &&
  1764. p_storage_class != spv::StorageClass::Function) {
  1765. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1766. << ext_inst_name() << ": "
  1767. << "expected storage class of the pointer to be Generic, "
  1768. "CrossWorkgroup, Workgroup or Function";
  1769. }
  1770. if (!_.ContainsUntypedPointer(p_type) && result_type != p_data_type) {
  1771. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1772. << ext_inst_name() << ": "
  1773. << "expected data type of the pointer to be equal to Result "
  1774. "Type";
  1775. }
  1776. break;
  1777. }
  1778. case OpenCLLIB::Frexp:
  1779. case OpenCLLIB::Lgamma_r:
  1780. case OpenCLLIB::Remquo: {
  1781. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1782. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1783. << ext_inst_name() << ": "
  1784. << "expected Result Type to be a float scalar or vector type";
  1785. }
  1786. const uint32_t num_components = _.GetDimension(result_type);
  1787. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1788. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1789. << ext_inst_name() << ": "
  1790. << "expected Result Type to be a scalar or a vector with 2, "
  1791. "3, 4, 8 or 16 components";
  1792. }
  1793. uint32_t operand_index = 4;
  1794. const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
  1795. if (result_type != x_type) {
  1796. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1797. << ext_inst_name() << ": "
  1798. << "expected type of operand X to be equal to Result Type";
  1799. }
  1800. if (ext_inst_key == OpenCLLIB::Remquo) {
  1801. const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
  1802. if (result_type != y_type) {
  1803. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1804. << ext_inst_name() << ": "
  1805. << "expected type of operand Y to be equal to Result Type";
  1806. }
  1807. }
  1808. const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++);
  1809. spv::StorageClass p_storage_class;
  1810. uint32_t p_data_type = 0;
  1811. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  1812. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1813. << ext_inst_name() << ": "
  1814. << "expected the last operand to be a pointer";
  1815. }
  1816. if (p_storage_class != spv::StorageClass::Generic &&
  1817. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  1818. p_storage_class != spv::StorageClass::Workgroup &&
  1819. p_storage_class != spv::StorageClass::Function) {
  1820. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1821. << ext_inst_name() << ": "
  1822. << "expected storage class of the pointer to be Generic, "
  1823. "CrossWorkgroup, Workgroup or Function";
  1824. }
  1825. if ((!_.IsIntScalarOrVectorType(p_data_type) ||
  1826. _.GetBitWidth(p_data_type) != 32) &&
  1827. !_.ContainsUntypedPointer(p_type)) {
  1828. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1829. << ext_inst_name() << ": "
  1830. << "expected data type of the pointer to be a 32-bit int "
  1831. "scalar or vector type";
  1832. }
  1833. if (!_.ContainsUntypedPointer(p_type) &&
  1834. _.GetDimension(p_data_type) != num_components) {
  1835. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1836. << ext_inst_name() << ": "
  1837. << "expected data type of the pointer to have the same number "
  1838. "of components as Result Type";
  1839. }
  1840. break;
  1841. }
  1842. case OpenCLLIB::Ilogb: {
  1843. if (!_.IsIntScalarOrVectorType(result_type) ||
  1844. _.GetBitWidth(result_type) != 32) {
  1845. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1846. << ext_inst_name() << ": "
  1847. << "expected Result Type to be a 32-bit int scalar or vector "
  1848. "type";
  1849. }
  1850. const uint32_t num_components = _.GetDimension(result_type);
  1851. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1852. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1853. << ext_inst_name() << ": "
  1854. << "expected Result Type to be a scalar or a vector with 2, "
  1855. "3, 4, 8 or 16 components";
  1856. }
  1857. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1858. if (!_.IsFloatScalarOrVectorType(x_type)) {
  1859. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1860. << ext_inst_name() << ": "
  1861. << "expected operand X to be a float scalar or vector";
  1862. }
  1863. if (_.GetDimension(x_type) != num_components) {
  1864. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1865. << ext_inst_name() << ": "
  1866. << "expected operand X to have the same number of components "
  1867. "as Result Type";
  1868. }
  1869. break;
  1870. }
  1871. case OpenCLLIB::Ldexp:
  1872. case OpenCLLIB::Pown:
  1873. case OpenCLLIB::Rootn: {
  1874. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1875. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1876. << ext_inst_name() << ": "
  1877. << "expected Result Type to be a float scalar or vector type";
  1878. }
  1879. const uint32_t num_components = _.GetDimension(result_type);
  1880. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1881. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1882. << ext_inst_name() << ": "
  1883. << "expected Result Type to be a scalar or a vector with 2, "
  1884. "3, 4, 8 or 16 components";
  1885. }
  1886. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  1887. if (result_type != x_type) {
  1888. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1889. << ext_inst_name() << ": "
  1890. << "expected type of operand X to be equal to Result Type";
  1891. }
  1892. const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
  1893. if (!_.IsIntScalarOrVectorType(exp_type) ||
  1894. _.GetBitWidth(exp_type) != 32) {
  1895. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1896. << ext_inst_name() << ": "
  1897. << "expected the exponent to be a 32-bit int scalar or vector";
  1898. }
  1899. if (_.GetDimension(exp_type) != num_components) {
  1900. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1901. << ext_inst_name() << ": "
  1902. << "expected the exponent to have the same number of "
  1903. "components as Result Type";
  1904. }
  1905. break;
  1906. }
  1907. case OpenCLLIB::Nan: {
  1908. if (!_.IsFloatScalarOrVectorType(result_type)) {
  1909. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1910. << ext_inst_name() << ": "
  1911. << "expected Result Type to be a float scalar or vector type";
  1912. }
  1913. const uint32_t num_components = _.GetDimension(result_type);
  1914. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1915. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1916. << ext_inst_name() << ": "
  1917. << "expected Result Type to be a scalar or a vector with 2, "
  1918. "3, 4, 8 or 16 components";
  1919. }
  1920. const uint32_t nancode_type = _.GetOperandTypeId(inst, 4);
  1921. if (!_.IsIntScalarOrVectorType(nancode_type)) {
  1922. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1923. << ext_inst_name() << ": "
  1924. << "expected Nancode to be an int scalar or vector type";
  1925. }
  1926. if (_.GetDimension(nancode_type) != num_components) {
  1927. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1928. << ext_inst_name() << ": "
  1929. << "expected Nancode to have the same number of components as "
  1930. "Result Type";
  1931. }
  1932. if (_.GetBitWidth(result_type) != _.GetBitWidth(nancode_type)) {
  1933. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1934. << ext_inst_name() << ": "
  1935. << "expected Nancode to have the same bit width as Result "
  1936. "Type";
  1937. }
  1938. break;
  1939. }
  1940. case OpenCLLIB::SAbs:
  1941. case OpenCLLIB::SAbs_diff:
  1942. case OpenCLLIB::SAdd_sat:
  1943. case OpenCLLIB::UAdd_sat:
  1944. case OpenCLLIB::SHadd:
  1945. case OpenCLLIB::UHadd:
  1946. case OpenCLLIB::SRhadd:
  1947. case OpenCLLIB::URhadd:
  1948. case OpenCLLIB::SClamp:
  1949. case OpenCLLIB::UClamp:
  1950. case OpenCLLIB::Clz:
  1951. case OpenCLLIB::Ctz:
  1952. case OpenCLLIB::SMad_hi:
  1953. case OpenCLLIB::UMad_sat:
  1954. case OpenCLLIB::SMad_sat:
  1955. case OpenCLLIB::SMax:
  1956. case OpenCLLIB::UMax:
  1957. case OpenCLLIB::SMin:
  1958. case OpenCLLIB::UMin:
  1959. case OpenCLLIB::SMul_hi:
  1960. case OpenCLLIB::Rotate:
  1961. case OpenCLLIB::SSub_sat:
  1962. case OpenCLLIB::USub_sat:
  1963. case OpenCLLIB::Popcount:
  1964. case OpenCLLIB::UAbs:
  1965. case OpenCLLIB::UAbs_diff:
  1966. case OpenCLLIB::UMul_hi:
  1967. case OpenCLLIB::UMad_hi: {
  1968. if (!_.IsIntScalarOrVectorType(result_type)) {
  1969. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1970. << ext_inst_name() << ": "
  1971. << "expected Result Type to be an int scalar or vector type";
  1972. }
  1973. const uint32_t num_components = _.GetDimension(result_type);
  1974. if (num_components > 4 && num_components != 8 && num_components != 16) {
  1975. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1976. << ext_inst_name() << ": "
  1977. << "expected Result Type to be a scalar or a vector with 2, "
  1978. "3, 4, 8 or 16 components";
  1979. }
  1980. for (uint32_t operand_index = 4; operand_index < num_operands;
  1981. ++operand_index) {
  1982. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  1983. if (result_type != operand_type) {
  1984. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1985. << ext_inst_name() << ": "
  1986. << "expected types of all operands to be equal to Result "
  1987. "Type";
  1988. }
  1989. }
  1990. break;
  1991. }
  1992. case OpenCLLIB::U_Upsample:
  1993. case OpenCLLIB::S_Upsample: {
  1994. if (!_.IsIntScalarOrVectorType(result_type)) {
  1995. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  1996. << ext_inst_name() << ": "
  1997. << "expected Result Type to be an int scalar or vector "
  1998. "type";
  1999. }
  2000. const uint32_t result_num_components = _.GetDimension(result_type);
  2001. if (result_num_components > 4 && result_num_components != 8 &&
  2002. result_num_components != 16) {
  2003. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2004. << ext_inst_name() << ": "
  2005. << "expected Result Type to be a scalar or a vector with 2, "
  2006. "3, 4, 8 or 16 components";
  2007. }
  2008. const uint32_t result_bit_width = _.GetBitWidth(result_type);
  2009. if (result_bit_width != 16 && result_bit_width != 32 &&
  2010. result_bit_width != 64) {
  2011. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2012. << ext_inst_name() << ": "
  2013. << "expected bit width of Result Type components to be 16, 32 "
  2014. "or 64";
  2015. }
  2016. const uint32_t hi_type = _.GetOperandTypeId(inst, 4);
  2017. const uint32_t lo_type = _.GetOperandTypeId(inst, 5);
  2018. if (hi_type != lo_type) {
  2019. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2020. << ext_inst_name() << ": "
  2021. << "expected Hi and Lo operands to have the same type";
  2022. }
  2023. if (result_num_components != _.GetDimension(hi_type)) {
  2024. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2025. << ext_inst_name() << ": "
  2026. << "expected Hi and Lo operands to have the same number of "
  2027. "components as Result Type";
  2028. }
  2029. if (result_bit_width != 2 * _.GetBitWidth(hi_type)) {
  2030. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2031. << ext_inst_name() << ": "
  2032. << "expected bit width of components of Hi and Lo operands to "
  2033. "be half of the bit width of components of Result Type";
  2034. }
  2035. break;
  2036. }
  2037. case OpenCLLIB::SMad24:
  2038. case OpenCLLIB::UMad24:
  2039. case OpenCLLIB::SMul24:
  2040. case OpenCLLIB::UMul24: {
  2041. if (!_.IsIntScalarOrVectorType(result_type) ||
  2042. _.GetBitWidth(result_type) != 32) {
  2043. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2044. << ext_inst_name() << ": "
  2045. << "expected Result Type to be a 32-bit int scalar or vector "
  2046. "type";
  2047. }
  2048. const uint32_t num_components = _.GetDimension(result_type);
  2049. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2050. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2051. << ext_inst_name() << ": "
  2052. << "expected Result Type to be a scalar or a vector with 2, "
  2053. "3, 4, 8 or 16 components";
  2054. }
  2055. for (uint32_t operand_index = 4; operand_index < num_operands;
  2056. ++operand_index) {
  2057. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  2058. if (result_type != operand_type) {
  2059. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2060. << ext_inst_name() << ": "
  2061. << "expected types of all operands to be equal to Result "
  2062. "Type";
  2063. }
  2064. }
  2065. break;
  2066. }
  2067. case OpenCLLIB::Cross: {
  2068. if (!_.IsFloatVectorType(result_type)) {
  2069. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2070. << ext_inst_name() << ": "
  2071. << "expected Result Type to be a float vector type";
  2072. }
  2073. const uint32_t num_components = _.GetDimension(result_type);
  2074. if (num_components != 3 && num_components != 4) {
  2075. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2076. << ext_inst_name() << ": "
  2077. << "expected Result Type to have 3 or 4 components";
  2078. }
  2079. const uint32_t x_type = _.GetOperandTypeId(inst, 4);
  2080. const uint32_t y_type = _.GetOperandTypeId(inst, 5);
  2081. if (x_type != result_type) {
  2082. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2083. << ext_inst_name() << ": "
  2084. << "expected operand X type to be equal to Result Type";
  2085. }
  2086. if (y_type != result_type) {
  2087. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2088. << ext_inst_name() << ": "
  2089. << "expected operand Y type to be equal to Result Type";
  2090. }
  2091. break;
  2092. }
  2093. case OpenCLLIB::Distance:
  2094. case OpenCLLIB::Fast_distance: {
  2095. if (!_.IsFloatScalarType(result_type)) {
  2096. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2097. << ext_inst_name() << ": "
  2098. << "expected Result Type to be a float scalar type";
  2099. }
  2100. const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
  2101. if (!_.IsFloatScalarOrVectorType(p0_type)) {
  2102. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2103. << ext_inst_name() << ": "
  2104. << "expected operand P0 to be of float scalar or vector type";
  2105. }
  2106. const uint32_t num_components = _.GetDimension(p0_type);
  2107. if (num_components > 4) {
  2108. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2109. << ext_inst_name() << ": "
  2110. << "expected operand P0 to have no more than 4 components";
  2111. }
  2112. if (result_type != _.GetComponentType(p0_type)) {
  2113. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2114. << ext_inst_name() << ": "
  2115. << "expected operand P0 component type to be equal to "
  2116. << "Result Type";
  2117. }
  2118. const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
  2119. if (p0_type != p1_type) {
  2120. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2121. << ext_inst_name() << ": "
  2122. << "expected operands P0 and P1 to be of the same type";
  2123. }
  2124. break;
  2125. }
  2126. case OpenCLLIB::Length:
  2127. case OpenCLLIB::Fast_length: {
  2128. if (!_.IsFloatScalarType(result_type)) {
  2129. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2130. << ext_inst_name() << ": "
  2131. << "expected Result Type to be a float scalar type";
  2132. }
  2133. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  2134. if (!_.IsFloatScalarOrVectorType(p_type)) {
  2135. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2136. << ext_inst_name() << ": "
  2137. << "expected operand P to be a float scalar or vector";
  2138. }
  2139. const uint32_t num_components = _.GetDimension(p_type);
  2140. if (num_components > 4) {
  2141. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2142. << ext_inst_name() << ": "
  2143. << "expected operand P to have no more than 4 components";
  2144. }
  2145. if (result_type != _.GetComponentType(p_type)) {
  2146. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2147. << ext_inst_name() << ": "
  2148. << "expected operand P component type to be equal to Result "
  2149. "Type";
  2150. }
  2151. break;
  2152. }
  2153. case OpenCLLIB::Normalize:
  2154. case OpenCLLIB::Fast_normalize: {
  2155. if (!_.IsFloatScalarOrVectorType(result_type)) {
  2156. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2157. << ext_inst_name() << ": "
  2158. << "expected Result Type to be a float scalar or vector type";
  2159. }
  2160. const uint32_t num_components = _.GetDimension(result_type);
  2161. if (num_components > 4) {
  2162. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2163. << ext_inst_name() << ": "
  2164. << "expected Result Type to have no more than 4 components";
  2165. }
  2166. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  2167. if (p_type != result_type) {
  2168. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2169. << ext_inst_name() << ": "
  2170. << "expected operand P type to be equal to Result Type";
  2171. }
  2172. break;
  2173. }
  2174. case OpenCLLIB::Bitselect: {
  2175. if (!_.IsFloatScalarOrVectorType(result_type) &&
  2176. !_.IsIntScalarOrVectorType(result_type)) {
  2177. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2178. << ext_inst_name() << ": "
  2179. << "expected Result Type to be an int or float scalar or "
  2180. "vector type";
  2181. }
  2182. const uint32_t num_components = _.GetDimension(result_type);
  2183. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2184. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2185. << ext_inst_name() << ": "
  2186. << "expected Result Type to be a scalar or a vector with 2, "
  2187. "3, 4, 8 or 16 components";
  2188. }
  2189. for (uint32_t operand_index = 4; operand_index < num_operands;
  2190. ++operand_index) {
  2191. const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  2192. if (result_type != operand_type) {
  2193. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2194. << ext_inst_name() << ": "
  2195. << "expected types of all operands to be equal to Result "
  2196. "Type";
  2197. }
  2198. }
  2199. break;
  2200. }
  2201. case OpenCLLIB::Select: {
  2202. if (!_.IsFloatScalarOrVectorType(result_type) &&
  2203. !_.IsIntScalarOrVectorType(result_type)) {
  2204. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2205. << ext_inst_name() << ": "
  2206. << "expected Result Type to be an int or float scalar or "
  2207. "vector type";
  2208. }
  2209. const uint32_t num_components = _.GetDimension(result_type);
  2210. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2211. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2212. << ext_inst_name() << ": "
  2213. << "expected Result Type to be a scalar or a vector with 2, "
  2214. "3, 4, 8 or 16 components";
  2215. }
  2216. const uint32_t a_type = _.GetOperandTypeId(inst, 4);
  2217. const uint32_t b_type = _.GetOperandTypeId(inst, 5);
  2218. const uint32_t c_type = _.GetOperandTypeId(inst, 6);
  2219. if (result_type != a_type) {
  2220. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2221. << ext_inst_name() << ": "
  2222. << "expected operand A type to be equal to Result Type";
  2223. }
  2224. if (result_type != b_type) {
  2225. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2226. << ext_inst_name() << ": "
  2227. << "expected operand B type to be equal to Result Type";
  2228. }
  2229. if (!_.IsIntScalarOrVectorType(c_type)) {
  2230. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2231. << ext_inst_name() << ": "
  2232. << "expected operand C to be an int scalar or vector";
  2233. }
  2234. if (num_components != _.GetDimension(c_type)) {
  2235. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2236. << ext_inst_name() << ": "
  2237. << "expected operand C to have the same number of components "
  2238. "as Result Type";
  2239. }
  2240. if (_.GetBitWidth(result_type) != _.GetBitWidth(c_type)) {
  2241. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2242. << ext_inst_name() << ": "
  2243. << "expected operand C to have the same bit width as Result "
  2244. "Type";
  2245. }
  2246. break;
  2247. }
  2248. case OpenCLLIB::Vloadn: {
  2249. if (!_.IsFloatVectorType(result_type) &&
  2250. !_.IsIntVectorType(result_type)) {
  2251. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2252. << ext_inst_name() << ": "
  2253. << "expected Result Type to be an int or float vector type";
  2254. }
  2255. const uint32_t num_components = _.GetDimension(result_type);
  2256. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2257. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2258. << ext_inst_name() << ": "
  2259. << "expected Result Type to have 2, 3, 4, 8 or 16 components";
  2260. }
  2261. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2262. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2263. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2264. if (!size_t_bit_width) {
  2265. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2266. << ext_inst_name()
  2267. << " can only be used with physical addressing models";
  2268. }
  2269. if (!_.IsIntScalarType(offset_type) ||
  2270. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2271. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2272. << ext_inst_name() << ": "
  2273. << "expected operand Offset to be of type size_t ("
  2274. << size_t_bit_width
  2275. << "-bit integer for the addressing model used in the module)";
  2276. }
  2277. spv::StorageClass p_storage_class;
  2278. uint32_t p_data_type = 0;
  2279. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2280. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2281. << ext_inst_name() << ": "
  2282. << "expected operand P to be a pointer";
  2283. }
  2284. if (p_storage_class != spv::StorageClass::UniformConstant &&
  2285. p_storage_class != spv::StorageClass::Generic &&
  2286. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  2287. p_storage_class != spv::StorageClass::Workgroup &&
  2288. p_storage_class != spv::StorageClass::Function) {
  2289. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2290. << ext_inst_name() << ": "
  2291. << "expected operand P storage class to be UniformConstant, "
  2292. "Generic, CrossWorkgroup, Workgroup or Function";
  2293. }
  2294. if (_.GetComponentType(result_type) != p_data_type) {
  2295. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2296. << ext_inst_name() << ": "
  2297. << "expected operand P data type to be equal to component "
  2298. "type of Result Type";
  2299. }
  2300. const uint32_t n_value = inst->word(7);
  2301. if (num_components != n_value) {
  2302. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2303. << ext_inst_name() << ": "
  2304. << "expected literal N to be equal to the number of "
  2305. "components of Result Type";
  2306. }
  2307. break;
  2308. }
  2309. case OpenCLLIB::Vstoren: {
  2310. if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) {
  2311. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2312. << ext_inst_name() << ": expected Result Type to be void";
  2313. }
  2314. const uint32_t data_type = _.GetOperandTypeId(inst, 4);
  2315. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  2316. const uint32_t p_type = _.GetOperandTypeId(inst, 6);
  2317. if (!_.IsFloatVectorType(data_type) && !_.IsIntVectorType(data_type)) {
  2318. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2319. << ext_inst_name() << ": "
  2320. << "expected Data to be an int or float vector";
  2321. }
  2322. const uint32_t num_components = _.GetDimension(data_type);
  2323. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2324. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2325. << ext_inst_name() << ": "
  2326. << "expected Data to have 2, 3, 4, 8 or 16 components";
  2327. }
  2328. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2329. if (!size_t_bit_width) {
  2330. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2331. << ext_inst_name()
  2332. << " can only be used with physical addressing models";
  2333. }
  2334. if (!_.IsIntScalarType(offset_type) ||
  2335. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2336. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2337. << ext_inst_name() << ": "
  2338. << "expected operand Offset to be of type size_t ("
  2339. << size_t_bit_width
  2340. << "-bit integer for the addressing model used in the module)";
  2341. }
  2342. spv::StorageClass p_storage_class;
  2343. uint32_t p_data_type = 0;
  2344. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2345. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2346. << ext_inst_name() << ": "
  2347. << "expected operand P to be a pointer";
  2348. }
  2349. if (p_storage_class != spv::StorageClass::Generic &&
  2350. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  2351. p_storage_class != spv::StorageClass::Workgroup &&
  2352. p_storage_class != spv::StorageClass::Function) {
  2353. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2354. << ext_inst_name() << ": "
  2355. << "expected operand P storage class to be Generic, "
  2356. "CrossWorkgroup, Workgroup or Function";
  2357. }
  2358. if (_.GetComponentType(data_type) != p_data_type) {
  2359. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2360. << ext_inst_name() << ": "
  2361. << "expected operand P data type to be equal to the type of "
  2362. "operand Data components";
  2363. }
  2364. break;
  2365. }
  2366. case OpenCLLIB::Vload_half: {
  2367. if (!_.IsFloatScalarType(result_type)) {
  2368. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2369. << ext_inst_name() << ": "
  2370. << "expected Result Type to be a float scalar type";
  2371. }
  2372. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2373. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2374. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2375. if (!size_t_bit_width) {
  2376. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2377. << ext_inst_name()
  2378. << " can only be used with physical addressing models";
  2379. }
  2380. if (!_.IsIntScalarType(offset_type) ||
  2381. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2382. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2383. << ext_inst_name() << ": "
  2384. << "expected operand Offset to be of type size_t ("
  2385. << size_t_bit_width
  2386. << "-bit integer for the addressing model used in the module)";
  2387. }
  2388. spv::StorageClass p_storage_class;
  2389. uint32_t p_data_type = 0;
  2390. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2391. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2392. << ext_inst_name() << ": "
  2393. << "expected operand P to be a pointer";
  2394. }
  2395. if (p_storage_class != spv::StorageClass::UniformConstant &&
  2396. p_storage_class != spv::StorageClass::Generic &&
  2397. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  2398. p_storage_class != spv::StorageClass::Workgroup &&
  2399. p_storage_class != spv::StorageClass::Function) {
  2400. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2401. << ext_inst_name() << ": "
  2402. << "expected operand P storage class to be UniformConstant, "
  2403. "Generic, CrossWorkgroup, Workgroup or Function";
  2404. }
  2405. if ((!_.IsFloatScalarType(p_data_type) ||
  2406. _.GetBitWidth(p_data_type) != 16) &&
  2407. !_.ContainsUntypedPointer(p_type)) {
  2408. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2409. << ext_inst_name() << ": "
  2410. << "expected operand P data type to be 16-bit float scalar";
  2411. }
  2412. break;
  2413. }
  2414. case OpenCLLIB::Vload_halfn:
  2415. case OpenCLLIB::Vloada_halfn: {
  2416. if (!_.IsFloatVectorType(result_type)) {
  2417. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2418. << ext_inst_name() << ": "
  2419. << "expected Result Type to be a float vector type";
  2420. }
  2421. const uint32_t num_components = _.GetDimension(result_type);
  2422. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2423. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2424. << ext_inst_name() << ": "
  2425. << "expected Result Type to have 2, 3, 4, 8 or 16 components";
  2426. }
  2427. const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  2428. const uint32_t p_type = _.GetOperandTypeId(inst, 5);
  2429. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2430. if (!size_t_bit_width) {
  2431. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2432. << ext_inst_name()
  2433. << " can only be used with physical addressing models";
  2434. }
  2435. if (!_.IsIntScalarType(offset_type) ||
  2436. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2437. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2438. << ext_inst_name() << ": "
  2439. << "expected operand Offset to be of type size_t ("
  2440. << size_t_bit_width
  2441. << "-bit integer for the addressing model used in the module)";
  2442. }
  2443. spv::StorageClass p_storage_class;
  2444. uint32_t p_data_type = 0;
  2445. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2446. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2447. << ext_inst_name() << ": "
  2448. << "expected operand P to be a pointer";
  2449. }
  2450. if (p_storage_class != spv::StorageClass::UniformConstant &&
  2451. p_storage_class != spv::StorageClass::Generic &&
  2452. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  2453. p_storage_class != spv::StorageClass::Workgroup &&
  2454. p_storage_class != spv::StorageClass::Function) {
  2455. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2456. << ext_inst_name() << ": "
  2457. << "expected operand P storage class to be UniformConstant, "
  2458. "Generic, CrossWorkgroup, Workgroup or Function";
  2459. }
  2460. if ((!_.IsFloatScalarType(p_data_type) ||
  2461. _.GetBitWidth(p_data_type) != 16) &&
  2462. !_.ContainsUntypedPointer(p_type)) {
  2463. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2464. << ext_inst_name() << ": "
  2465. << "expected operand P data type to be 16-bit float scalar";
  2466. }
  2467. const uint32_t n_value = inst->word(7);
  2468. if (num_components != n_value) {
  2469. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2470. << ext_inst_name() << ": "
  2471. << "expected literal N to be equal to the number of "
  2472. "components of Result Type";
  2473. }
  2474. break;
  2475. }
  2476. case OpenCLLIB::Vstore_half:
  2477. case OpenCLLIB::Vstore_half_r:
  2478. case OpenCLLIB::Vstore_halfn:
  2479. case OpenCLLIB::Vstore_halfn_r:
  2480. case OpenCLLIB::Vstorea_halfn:
  2481. case OpenCLLIB::Vstorea_halfn_r: {
  2482. if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) {
  2483. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2484. << ext_inst_name() << ": expected Result Type to be void";
  2485. }
  2486. const uint32_t data_type = _.GetOperandTypeId(inst, 4);
  2487. const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
  2488. const uint32_t p_type = _.GetOperandTypeId(inst, 6);
  2489. const uint32_t data_type_bit_width = _.GetBitWidth(data_type);
  2490. if (ext_inst_key == OpenCLLIB::Vstore_half ||
  2491. ext_inst_key == OpenCLLIB::Vstore_half_r) {
  2492. if (!_.IsFloatScalarType(data_type) ||
  2493. (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  2494. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2495. << ext_inst_name() << ": "
  2496. << "expected Data to be a 32 or 64-bit float scalar";
  2497. }
  2498. } else {
  2499. if (!_.IsFloatVectorType(data_type) ||
  2500. (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  2501. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2502. << ext_inst_name() << ": "
  2503. << "expected Data to be a 32 or 64-bit float vector";
  2504. }
  2505. const uint32_t num_components = _.GetDimension(data_type);
  2506. if (num_components > 4 && num_components != 8 &&
  2507. num_components != 16) {
  2508. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2509. << ext_inst_name() << ": "
  2510. << "expected Data to have 2, 3, 4, 8 or 16 components";
  2511. }
  2512. }
  2513. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2514. if (!size_t_bit_width) {
  2515. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2516. << ext_inst_name()
  2517. << " can only be used with physical addressing models";
  2518. }
  2519. if (!_.IsIntScalarType(offset_type) ||
  2520. _.GetBitWidth(offset_type) != size_t_bit_width) {
  2521. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2522. << ext_inst_name() << ": "
  2523. << "expected operand Offset to be of type size_t ("
  2524. << size_t_bit_width
  2525. << "-bit integer for the addressing model used in the module)";
  2526. }
  2527. spv::StorageClass p_storage_class;
  2528. uint32_t p_data_type = 0;
  2529. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2530. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2531. << ext_inst_name() << ": "
  2532. << "expected operand P to be a pointer";
  2533. }
  2534. if (p_storage_class != spv::StorageClass::Generic &&
  2535. p_storage_class != spv::StorageClass::CrossWorkgroup &&
  2536. p_storage_class != spv::StorageClass::Workgroup &&
  2537. p_storage_class != spv::StorageClass::Function) {
  2538. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2539. << ext_inst_name() << ": "
  2540. << "expected operand P storage class to be Generic, "
  2541. "CrossWorkgroup, Workgroup or Function";
  2542. }
  2543. if ((!_.IsFloatScalarType(p_data_type) ||
  2544. _.GetBitWidth(p_data_type) != 16) &&
  2545. !_.ContainsUntypedPointer(p_type)) {
  2546. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2547. << ext_inst_name() << ": "
  2548. << "expected operand P data type to be 16-bit float scalar";
  2549. }
  2550. // Rounding mode enum is checked by assembler.
  2551. break;
  2552. }
  2553. case OpenCLLIB::Shuffle:
  2554. case OpenCLLIB::Shuffle2: {
  2555. if (!_.IsFloatVectorType(result_type) &&
  2556. !_.IsIntVectorType(result_type)) {
  2557. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2558. << ext_inst_name() << ": "
  2559. << "expected Result Type to be an int or float vector type";
  2560. }
  2561. const uint32_t result_num_components = _.GetDimension(result_type);
  2562. if (result_num_components != 2 && result_num_components != 4 &&
  2563. result_num_components != 8 && result_num_components != 16) {
  2564. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2565. << ext_inst_name() << ": "
  2566. << "expected Result Type to have 2, 4, 8 or 16 components";
  2567. }
  2568. uint32_t operand_index = 4;
  2569. const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
  2570. if (ext_inst_key == OpenCLLIB::Shuffle2) {
  2571. const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
  2572. if (x_type != y_type) {
  2573. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2574. << ext_inst_name() << ": "
  2575. << "expected operands X and Y to be of the same type";
  2576. }
  2577. }
  2578. const uint32_t shuffle_mask_type =
  2579. _.GetOperandTypeId(inst, operand_index++);
  2580. if (!_.IsFloatVectorType(x_type) && !_.IsIntVectorType(x_type)) {
  2581. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2582. << ext_inst_name() << ": "
  2583. << "expected operand X to be an int or float vector";
  2584. }
  2585. const uint32_t x_num_components = _.GetDimension(x_type);
  2586. if (x_num_components != 2 && x_num_components != 4 &&
  2587. x_num_components != 8 && x_num_components != 16) {
  2588. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2589. << ext_inst_name() << ": "
  2590. << "expected operand X to have 2, 4, 8 or 16 components";
  2591. }
  2592. const uint32_t result_component_type = _.GetComponentType(result_type);
  2593. if (result_component_type != _.GetComponentType(x_type)) {
  2594. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2595. << ext_inst_name() << ": "
  2596. << "expected operand X and Result Type to have equal "
  2597. "component types";
  2598. }
  2599. if (!_.IsIntVectorType(shuffle_mask_type)) {
  2600. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2601. << ext_inst_name() << ": "
  2602. << "expected operand Shuffle Mask to be an int vector";
  2603. }
  2604. if (result_num_components != _.GetDimension(shuffle_mask_type)) {
  2605. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2606. << ext_inst_name() << ": "
  2607. << "expected operand Shuffle Mask to have the same number of "
  2608. "components as Result Type";
  2609. }
  2610. if (_.GetBitWidth(result_component_type) !=
  2611. _.GetBitWidth(shuffle_mask_type)) {
  2612. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2613. << ext_inst_name() << ": "
  2614. << "expected operand Shuffle Mask components to have the same "
  2615. "bit width as Result Type components";
  2616. }
  2617. break;
  2618. }
  2619. case OpenCLLIB::Printf: {
  2620. if (!_.IsIntScalarType(result_type) ||
  2621. _.GetBitWidth(result_type) != 32) {
  2622. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2623. << ext_inst_name() << ": "
  2624. << "expected Result Type to be a 32-bit int type";
  2625. }
  2626. const uint32_t format_type = _.GetOperandTypeId(inst, 4);
  2627. spv::StorageClass format_storage_class;
  2628. uint32_t format_data_type = 0;
  2629. if (!_.GetPointerTypeInfo(format_type, &format_data_type,
  2630. &format_storage_class)) {
  2631. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2632. << ext_inst_name() << ": "
  2633. << "expected operand Format to be a pointer";
  2634. }
  2635. if (_.HasExtension(
  2636. Extension::kSPV_EXT_relaxed_printf_string_address_space)) {
  2637. if (format_storage_class != spv::StorageClass::UniformConstant &&
  2638. // Extension SPV_EXT_relaxed_printf_string_address_space allows
  2639. // format strings in Global, Local, Private and Generic address
  2640. // spaces
  2641. // Global
  2642. format_storage_class != spv::StorageClass::CrossWorkgroup &&
  2643. // Local
  2644. format_storage_class != spv::StorageClass::Workgroup &&
  2645. // Private
  2646. format_storage_class != spv::StorageClass::Function &&
  2647. // Generic
  2648. format_storage_class != spv::StorageClass::Generic) {
  2649. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2650. << ext_inst_name() << ": "
  2651. << "expected Format storage class to be UniformConstant, "
  2652. "Crossworkgroup, Workgroup, Function, or Generic";
  2653. }
  2654. } else {
  2655. if (format_storage_class != spv::StorageClass::UniformConstant) {
  2656. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2657. << ext_inst_name() << ": "
  2658. << "expected Format storage class to be UniformConstant";
  2659. }
  2660. }
  2661. // If pointer points to an array, get the type of an element
  2662. if (_.IsIntArrayType(format_data_type))
  2663. format_data_type = _.GetComponentType(format_data_type);
  2664. if ((!_.IsIntScalarType(format_data_type) ||
  2665. _.GetBitWidth(format_data_type) != 8) &&
  2666. !_.ContainsUntypedPointer(format_type)) {
  2667. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2668. << ext_inst_name() << ": "
  2669. << "expected Format data type to be 8-bit int";
  2670. }
  2671. break;
  2672. }
  2673. case OpenCLLIB::Prefetch: {
  2674. if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) {
  2675. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2676. << ext_inst_name() << ": expected Result Type to be void";
  2677. }
  2678. const uint32_t p_type = _.GetOperandTypeId(inst, 4);
  2679. const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5);
  2680. spv::StorageClass p_storage_class;
  2681. uint32_t p_data_type = 0;
  2682. if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  2683. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2684. << ext_inst_name() << ": "
  2685. << "expected operand Ptr to be a pointer";
  2686. }
  2687. if (p_storage_class != spv::StorageClass::CrossWorkgroup) {
  2688. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2689. << ext_inst_name() << ": "
  2690. << "expected operand Ptr storage class to be CrossWorkgroup";
  2691. }
  2692. if (!_.IsFloatScalarOrVectorType(p_data_type) &&
  2693. !_.IsIntScalarOrVectorType(p_data_type)) {
  2694. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2695. << ext_inst_name() << ": "
  2696. << "expected Ptr data type to be int or float scalar or "
  2697. "vector";
  2698. }
  2699. const uint32_t num_components = _.GetDimension(p_data_type);
  2700. if (num_components > 4 && num_components != 8 && num_components != 16) {
  2701. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2702. << ext_inst_name() << ": "
  2703. << "expected Result Type to be a scalar or a vector with 2, "
  2704. "3, 4, 8 or 16 components";
  2705. }
  2706. const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
  2707. if (!size_t_bit_width) {
  2708. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2709. << ext_inst_name()
  2710. << " can only be used with physical addressing models";
  2711. }
  2712. if (!_.IsIntScalarType(num_elements_type) ||
  2713. _.GetBitWidth(num_elements_type) != size_t_bit_width) {
  2714. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2715. << ext_inst_name() << ": "
  2716. << "expected operand Num Elements to be of type size_t ("
  2717. << size_t_bit_width
  2718. << "-bit integer for the addressing model used in the module)";
  2719. }
  2720. break;
  2721. }
  2722. }
  2723. } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
  2724. ext_inst_type ==
  2725. SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
  2726. if (!_.IsVoidType(result_type)) {
  2727. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2728. << ext_inst_name() << ": "
  2729. << "expected result type must be a result id of "
  2730. << "OpTypeVoid";
  2731. }
  2732. const bool vulkanDebugInfo =
  2733. ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
  2734. auto num_words = inst->words().size();
  2735. // Handle any non-common NonSemanticShaderDebugInfo instructions.
  2736. if (vulkanDebugInfo) {
  2737. const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
  2738. NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
  2739. switch (ext_inst_key) {
  2740. // The following block of instructions will be handled by the common
  2741. // validation.
  2742. case NonSemanticShaderDebugInfo100DebugInfoNone:
  2743. case NonSemanticShaderDebugInfo100DebugCompilationUnit:
  2744. case NonSemanticShaderDebugInfo100DebugTypePointer:
  2745. case NonSemanticShaderDebugInfo100DebugTypeQualifier:
  2746. case NonSemanticShaderDebugInfo100DebugTypeArray:
  2747. case NonSemanticShaderDebugInfo100DebugTypeVector:
  2748. case NonSemanticShaderDebugInfo100DebugTypedef:
  2749. case NonSemanticShaderDebugInfo100DebugTypeFunction:
  2750. case NonSemanticShaderDebugInfo100DebugTypeEnum:
  2751. case NonSemanticShaderDebugInfo100DebugTypeComposite:
  2752. case NonSemanticShaderDebugInfo100DebugTypeMember:
  2753. case NonSemanticShaderDebugInfo100DebugTypeInheritance:
  2754. case NonSemanticShaderDebugInfo100DebugTypePtrToMember:
  2755. case NonSemanticShaderDebugInfo100DebugTypeTemplate:
  2756. case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter:
  2757. case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter:
  2758. case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack:
  2759. case NonSemanticShaderDebugInfo100DebugGlobalVariable:
  2760. case NonSemanticShaderDebugInfo100DebugFunctionDeclaration:
  2761. case NonSemanticShaderDebugInfo100DebugFunction:
  2762. case NonSemanticShaderDebugInfo100DebugLexicalBlock:
  2763. case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator:
  2764. case NonSemanticShaderDebugInfo100DebugScope:
  2765. case NonSemanticShaderDebugInfo100DebugNoScope:
  2766. case NonSemanticShaderDebugInfo100DebugInlinedAt:
  2767. case NonSemanticShaderDebugInfo100DebugLocalVariable:
  2768. case NonSemanticShaderDebugInfo100DebugInlinedVariable:
  2769. case NonSemanticShaderDebugInfo100DebugValue:
  2770. case NonSemanticShaderDebugInfo100DebugOperation:
  2771. case NonSemanticShaderDebugInfo100DebugExpression:
  2772. case NonSemanticShaderDebugInfo100DebugMacroDef:
  2773. case NonSemanticShaderDebugInfo100DebugMacroUndef:
  2774. case NonSemanticShaderDebugInfo100DebugImportedEntity:
  2775. case NonSemanticShaderDebugInfo100DebugSource:
  2776. break;
  2777. // These checks are for operands that are differnet in
  2778. // ShaderDebugInfo100
  2779. case NonSemanticShaderDebugInfo100DebugTypeBasic: {
  2780. CHECK_CONST_UINT_OPERAND("Flags", 8);
  2781. break;
  2782. }
  2783. case NonSemanticShaderDebugInfo100DebugDeclare: {
  2784. for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
  2785. auto index_inst = _.FindDef(inst->word(word_index));
  2786. auto type_id = index_inst != nullptr ? index_inst->type_id() : 0;
  2787. if (type_id == 0 || !IsIntScalar(_, type_id, false, false))
  2788. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2789. << ext_inst_name() << ": "
  2790. << "expected index must be scalar integer";
  2791. }
  2792. break;
  2793. }
  2794. case NonSemanticShaderDebugInfo100DebugTypeMatrix: {
  2795. CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5);
  2796. CHECK_CONST_UINT_OPERAND("Vector Count", 6);
  2797. uint32_t vector_count = inst->word(6);
  2798. uint64_t const_val;
  2799. if (!_.EvalConstantValUint64(vector_count, &const_val)) {
  2800. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2801. << ext_inst_name()
  2802. << ": Vector Count must be 32-bit integer OpConstant";
  2803. }
  2804. vector_count = const_val & 0xffffffff;
  2805. if (!vector_count || vector_count > 4) {
  2806. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2807. << ext_inst_name() << ": Vector Count must be positive "
  2808. << "integer less than or equal to 4";
  2809. }
  2810. break;
  2811. }
  2812. case NonSemanticShaderDebugInfo100DebugFunctionDefinition: {
  2813. CHECK_DEBUG_OPERAND("Function", CommonDebugInfoDebugFunction, 5);
  2814. CHECK_OPERAND("Definition", spv::Op::OpFunction, 6);
  2815. const auto* current_function = inst->function();
  2816. if (current_function->first_block()->id() != inst->block()->id()) {
  2817. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2818. << ext_inst_name()
  2819. << ": must be in the entry basic block of the function";
  2820. }
  2821. const uint32_t definition_id = inst->word(6);
  2822. if (definition_id != current_function->id()) {
  2823. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2824. << ext_inst_name()
  2825. << ": operand Definition must point to the OpFunction it is "
  2826. "inside";
  2827. }
  2828. break;
  2829. }
  2830. case NonSemanticShaderDebugInfo100DebugLine: {
  2831. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 5);
  2832. CHECK_CONST_UINT_OPERAND("Line Start", 6);
  2833. CHECK_CONST_UINT_OPERAND("Line End", 7);
  2834. CHECK_CONST_UINT_OPERAND("Column Start", 8);
  2835. CHECK_CONST_UINT_OPERAND("Column End", 9);
  2836. // above already validates if 32-bit and non-spec constant
  2837. // but want to use EvalInt32IfConst to be consistent with other Eval
  2838. // locations
  2839. bool is_int32 = false, is_const_int32 = false;
  2840. uint32_t line_start = 0;
  2841. uint32_t line_end = 0;
  2842. uint32_t column_start = 0;
  2843. uint32_t column_end = 0;
  2844. std::tie(is_int32, is_const_int32, line_start) =
  2845. _.EvalInt32IfConst(inst->word(6));
  2846. std::tie(is_int32, is_const_int32, line_end) =
  2847. _.EvalInt32IfConst(inst->word(7));
  2848. std::tie(is_int32, is_const_int32, column_start) =
  2849. _.EvalInt32IfConst(inst->word(8));
  2850. std::tie(is_int32, is_const_int32, column_end) =
  2851. _.EvalInt32IfConst(inst->word(9));
  2852. if (line_end < line_start) {
  2853. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2854. << ext_inst_name() << ": operand Line End (" << line_end
  2855. << ") is less than Line Start (" << line_start << ")";
  2856. } else if (line_start == line_end && column_end < column_start) {
  2857. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2858. << ext_inst_name() << ": operand Column End (" << column_end
  2859. << ") is less than Column Start (" << column_start
  2860. << ") when Line Start equals Line End";
  2861. }
  2862. break;
  2863. }
  2864. case NonSemanticShaderDebugInfo100DebugSourceContinued: {
  2865. CHECK_OPERAND("Text", spv::Op::OpString, 5);
  2866. break;
  2867. }
  2868. case NonSemanticShaderDebugInfo100DebugBuildIdentifier: {
  2869. CHECK_OPERAND("Identifier", spv::Op::OpString, 5);
  2870. CHECK_CONST_UINT_OPERAND("Flags", 6);
  2871. break;
  2872. }
  2873. case NonSemanticShaderDebugInfo100DebugStoragePath: {
  2874. CHECK_OPERAND("Path", spv::Op::OpString, 5);
  2875. break;
  2876. }
  2877. case NonSemanticShaderDebugInfo100DebugEntryPoint: {
  2878. CHECK_DEBUG_OPERAND("Entry Point", CommonDebugInfoDebugFunction, 5);
  2879. CHECK_DEBUG_OPERAND("Compilation Unit",
  2880. CommonDebugInfoDebugCompilationUnit, 6);
  2881. CHECK_OPERAND("Compiler Signature", spv::Op::OpString, 7);
  2882. CHECK_OPERAND("Command-line Arguments", spv::Op::OpString, 8);
  2883. break;
  2884. }
  2885. // Has no additional checks
  2886. case NonSemanticShaderDebugInfo100DebugNoLine:
  2887. break;
  2888. case NonSemanticShaderDebugInfo100InstructionsMax:
  2889. assert(0);
  2890. break;
  2891. }
  2892. }
  2893. // Handle any non-common OpenCL insts, then common
  2894. if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
  2895. OpenCLDebugInfo100Instructions(ext_inst_index) !=
  2896. OpenCLDebugInfo100DebugModuleINTEL) {
  2897. const CommonDebugInfoInstructions ext_inst_key =
  2898. CommonDebugInfoInstructions(ext_inst_index);
  2899. switch (ext_inst_key) {
  2900. case CommonDebugInfoDebugInfoNone:
  2901. case CommonDebugInfoDebugNoScope:
  2902. break;
  2903. // The binary parser validates the opcode for DebugInfoNone,
  2904. // DebugNoScope, DebugOperation. We just check the parameters to
  2905. // DebugOperation are properly constants for vulkan debug info.
  2906. case CommonDebugInfoDebugOperation: {
  2907. CHECK_CONST_UINT_OPERAND("Operation", 5);
  2908. for (uint32_t i = 6; i < num_words; ++i) {
  2909. CHECK_CONST_UINT_OPERAND("Operand", i);
  2910. }
  2911. break;
  2912. }
  2913. case CommonDebugInfoDebugCompilationUnit: {
  2914. CHECK_CONST_UINT_OPERAND("Version", 5);
  2915. CHECK_CONST_UINT_OPERAND("DWARF Version", 6);
  2916. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  2917. CHECK_CONST_UINT_OPERAND("Language", 8);
  2918. break;
  2919. }
  2920. case CommonDebugInfoDebugSource: {
  2921. CHECK_OPERAND("File", spv::Op::OpString, 5);
  2922. if (num_words == 7) CHECK_OPERAND("Text", spv::Op::OpString, 6);
  2923. break;
  2924. }
  2925. case CommonDebugInfoDebugTypeBasic: {
  2926. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  2927. CHECK_OPERAND("Size", spv::Op::OpConstant, 6);
  2928. CHECK_CONST_UINT_OPERAND("Encoding", 7);
  2929. break;
  2930. }
  2931. case CommonDebugInfoDebugTypePointer: {
  2932. auto validate_base_type = ValidateOperandDebugType(
  2933. _, "Base Type", inst, 5, ext_inst_name, false);
  2934. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2935. CHECK_CONST_UINT_OPERAND("Storage Class", 6);
  2936. CHECK_CONST_UINT_OPERAND("Flags", 7);
  2937. break;
  2938. }
  2939. case CommonDebugInfoDebugTypeQualifier: {
  2940. auto validate_base_type = ValidateOperandDebugType(
  2941. _, "Base Type", inst, 5, ext_inst_name, false);
  2942. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2943. CHECK_CONST_UINT_OPERAND("Type Qualifier", 6);
  2944. break;
  2945. }
  2946. case CommonDebugInfoDebugTypeVector: {
  2947. auto validate_base_type =
  2948. ValidateOperandBaseType(_, inst, 5, ext_inst_name);
  2949. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2950. CHECK_CONST_UINT_OPERAND("Component Count", 6);
  2951. uint32_t component_count = inst->word(6);
  2952. if (vulkanDebugInfo) {
  2953. uint64_t const_val;
  2954. if (!_.EvalConstantValUint64(component_count, &const_val)) {
  2955. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2956. << ext_inst_name()
  2957. << ": Component Count must be 32-bit integer OpConstant";
  2958. }
  2959. component_count = const_val & 0xffffffff;
  2960. }
  2961. if (!component_count || component_count > 4) {
  2962. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  2963. << ext_inst_name() << ": Component Count must be positive "
  2964. << "integer less than or equal to 4";
  2965. }
  2966. break;
  2967. }
  2968. case CommonDebugInfoDebugTypeArray: {
  2969. auto validate_base_type = ValidateOperandDebugType(
  2970. _, "Base Type", inst, 5, ext_inst_name, false);
  2971. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  2972. for (uint32_t i = 6; i < num_words; ++i) {
  2973. bool invalid = false;
  2974. auto* component_count = _.FindDef(inst->word(i));
  2975. if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) {
  2976. // TODO: We need a spec discussion for the runtime array for
  2977. // OpenCL.
  2978. if (!vulkanDebugInfo && !component_count->word(3)) {
  2979. invalid = true;
  2980. }
  2981. } else if (component_count->words().size() > 6 &&
  2982. (CommonDebugInfoInstructions(component_count->word(4)) ==
  2983. CommonDebugInfoDebugLocalVariable ||
  2984. CommonDebugInfoInstructions(component_count->word(4)) ==
  2985. CommonDebugInfoDebugGlobalVariable)) {
  2986. auto* component_count_type = _.FindDef(component_count->word(6));
  2987. if (component_count_type->words().size() > 7) {
  2988. uint32_t encoding = component_count_type->word(7);
  2989. if (CommonDebugInfoInstructions(component_count_type->word(
  2990. 4)) != CommonDebugInfoDebugTypeBasic ||
  2991. (vulkanDebugInfo && !IsUint32Constant(_, encoding)) ||
  2992. OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
  2993. vulkanDebugInfo
  2994. ? GetUint32Constant(_, encoding)
  2995. : encoding) != OpenCLDebugInfo100Unsigned) {
  2996. invalid = true;
  2997. } else {
  2998. // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable
  2999. // must have Unsigned encoding and 32 or 64 as its size in
  3000. // bits.
  3001. Instruction* size_in_bits =
  3002. _.FindDef(component_count_type->word(6));
  3003. if (!_.IsIntScalarType(size_in_bits->type_id()) ||
  3004. (size_in_bits->word(3) != 32 &&
  3005. size_in_bits->word(3) != 64)) {
  3006. invalid = true;
  3007. }
  3008. }
  3009. } else {
  3010. invalid = true;
  3011. }
  3012. } else {
  3013. invalid = true;
  3014. }
  3015. if (invalid) {
  3016. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3017. << ext_inst_name() << ": Component Count must be "
  3018. << "OpConstant with a 32- or 64-bits integer scalar type "
  3019. "or "
  3020. << "DebugGlobalVariable or DebugLocalVariable with a 32- "
  3021. "or "
  3022. << "64-bits unsigned integer scalar type";
  3023. }
  3024. }
  3025. break;
  3026. }
  3027. case CommonDebugInfoDebugTypedef: {
  3028. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3029. auto validate_base_type =
  3030. ValidateOperandBaseType(_, inst, 6, ext_inst_name);
  3031. if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  3032. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3033. CHECK_CONST_UINT_OPERAND("Line", 8);
  3034. CHECK_CONST_UINT_OPERAND("Column", 9);
  3035. auto validate_parent =
  3036. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  3037. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3038. break;
  3039. }
  3040. case CommonDebugInfoDebugTypeFunction: {
  3041. CHECK_CONST_UINT_OPERAND("Flags", 5);
  3042. auto* return_type = _.FindDef(inst->word(6));
  3043. // TODO: We need a spec discussion that we have to allow return and
  3044. // parameter types of a DebugTypeFunction to have template parameter.
  3045. if (return_type->opcode() != spv::Op::OpTypeVoid) {
  3046. auto validate_return = ValidateOperandDebugType(
  3047. _, "Return Type", inst, 6, ext_inst_name, true);
  3048. if (validate_return != SPV_SUCCESS) return validate_return;
  3049. }
  3050. for (uint32_t word_index = 7; word_index < num_words; ++word_index) {
  3051. auto validate_param = ValidateOperandDebugType(
  3052. _, "Parameter Types", inst, word_index, ext_inst_name, true);
  3053. if (validate_param != SPV_SUCCESS) return validate_param;
  3054. }
  3055. break;
  3056. }
  3057. case CommonDebugInfoDebugTypeEnum: {
  3058. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3059. if (!DoesDebugInfoOperandMatchExpectation(
  3060. _,
  3061. [](CommonDebugInfoInstructions dbg_inst) {
  3062. return dbg_inst == CommonDebugInfoDebugInfoNone;
  3063. },
  3064. inst, 6)) {
  3065. auto validate_underlying_type = ValidateOperandDebugType(
  3066. _, "Underlying Types", inst, 6, ext_inst_name, false);
  3067. if (validate_underlying_type != SPV_SUCCESS)
  3068. return validate_underlying_type;
  3069. }
  3070. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3071. CHECK_CONST_UINT_OPERAND("Line", 8);
  3072. CHECK_CONST_UINT_OPERAND("Column", 9);
  3073. auto validate_parent =
  3074. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  3075. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3076. CHECK_OPERAND("Size", spv::Op::OpConstant, 11);
  3077. auto* size = _.FindDef(inst->word(11));
  3078. if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) {
  3079. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3080. << ext_inst_name() << ": expected operand Size is a "
  3081. << "positive integer";
  3082. }
  3083. CHECK_CONST_UINT_OPERAND("Flags", 12);
  3084. for (uint32_t word_index = 13; word_index + 1 < num_words;
  3085. word_index += 2) {
  3086. CHECK_OPERAND("Value", spv::Op::OpConstant, word_index);
  3087. CHECK_OPERAND("Name", spv::Op::OpString, word_index + 1);
  3088. }
  3089. break;
  3090. }
  3091. case CommonDebugInfoDebugTypeComposite: {
  3092. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3093. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3094. CHECK_CONST_UINT_OPERAND("Line", 8);
  3095. CHECK_CONST_UINT_OPERAND("Column", 9);
  3096. auto validate_parent =
  3097. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  3098. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3099. CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  3100. if (!DoesDebugInfoOperandMatchExpectation(
  3101. _,
  3102. [](CommonDebugInfoInstructions dbg_inst) {
  3103. return dbg_inst == CommonDebugInfoDebugInfoNone;
  3104. },
  3105. inst, 12)) {
  3106. CHECK_OPERAND("Size", spv::Op::OpConstant, 12);
  3107. }
  3108. CHECK_CONST_UINT_OPERAND("Flags", 13);
  3109. for (uint32_t word_index = 14; word_index < num_words; ++word_index) {
  3110. if (!DoesDebugInfoOperandMatchExpectation(
  3111. _,
  3112. [](CommonDebugInfoInstructions dbg_inst) {
  3113. return dbg_inst == CommonDebugInfoDebugTypeMember ||
  3114. dbg_inst == CommonDebugInfoDebugFunction ||
  3115. dbg_inst == CommonDebugInfoDebugTypeInheritance;
  3116. },
  3117. inst, word_index)) {
  3118. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3119. << ext_inst_name() << ": "
  3120. << "expected operand Members "
  3121. << "must be DebugTypeMember, DebugFunction, or "
  3122. "DebugTypeInheritance";
  3123. }
  3124. }
  3125. break;
  3126. }
  3127. case CommonDebugInfoDebugTypeMember: {
  3128. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3129. // TODO: We need a spec discussion that we have to allow member types
  3130. // to have template parameter.
  3131. auto validate_type =
  3132. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
  3133. if (validate_type != SPV_SUCCESS) return validate_type;
  3134. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3135. CHECK_CONST_UINT_OPERAND("Line", 8);
  3136. CHECK_CONST_UINT_OPERAND("Column", 9);
  3137. // NonSemantic.Shader.DebugInfo doesn't have the Parent operand
  3138. if (vulkanDebugInfo) {
  3139. CHECK_OPERAND("Offset", spv::Op::OpConstant, 10);
  3140. CHECK_OPERAND("Size", spv::Op::OpConstant, 11);
  3141. CHECK_CONST_UINT_OPERAND("Flags", 12);
  3142. if (num_words == 14)
  3143. CHECK_OPERAND("Value", spv::Op::OpConstant, 13);
  3144. } else {
  3145. CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite,
  3146. 10);
  3147. CHECK_OPERAND("Offset", spv::Op::OpConstant, 11);
  3148. CHECK_OPERAND("Size", spv::Op::OpConstant, 12);
  3149. CHECK_CONST_UINT_OPERAND("Flags", 13);
  3150. if (num_words == 15)
  3151. CHECK_OPERAND("Value", spv::Op::OpConstant, 14);
  3152. }
  3153. break;
  3154. }
  3155. case CommonDebugInfoDebugTypeInheritance: {
  3156. CHECK_DEBUG_OPERAND("Child", CommonDebugInfoDebugTypeComposite, 5);
  3157. auto* debug_inst = _.FindDef(inst->word(5));
  3158. auto composite_type =
  3159. OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
  3160. if (composite_type != OpenCLDebugInfo100Class &&
  3161. composite_type != OpenCLDebugInfo100Structure) {
  3162. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3163. << ext_inst_name() << ": "
  3164. << "expected operand Child must be class or struct debug "
  3165. "type";
  3166. }
  3167. CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, 6);
  3168. debug_inst = _.FindDef(inst->word(6));
  3169. composite_type =
  3170. OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
  3171. if (composite_type != OpenCLDebugInfo100Class &&
  3172. composite_type != OpenCLDebugInfo100Structure) {
  3173. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3174. << ext_inst_name() << ": "
  3175. << "expected operand Parent must be class or struct debug "
  3176. "type";
  3177. }
  3178. CHECK_OPERAND("Offset", spv::Op::OpConstant, 7);
  3179. CHECK_OPERAND("Size", spv::Op::OpConstant, 8);
  3180. CHECK_CONST_UINT_OPERAND("Flags", 9);
  3181. break;
  3182. }
  3183. case CommonDebugInfoDebugFunction: {
  3184. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3185. CHECK_DEBUG_OPERAND("Type", CommonDebugInfoDebugTypeFunction, 6);
  3186. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3187. CHECK_CONST_UINT_OPERAND("Line", 8);
  3188. CHECK_CONST_UINT_OPERAND("Column", 9);
  3189. auto validate_parent =
  3190. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  3191. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3192. CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  3193. CHECK_CONST_UINT_OPERAND("Flags", 12);
  3194. CHECK_CONST_UINT_OPERAND("Scope Line", 13);
  3195. // NonSemantic.Shader.DebugInfo.100 doesn't include a reference to the
  3196. // OpFunction
  3197. if (vulkanDebugInfo) {
  3198. if (num_words == 15) {
  3199. CHECK_DEBUG_OPERAND("Declaration",
  3200. CommonDebugInfoDebugFunctionDeclaration, 14);
  3201. }
  3202. } else {
  3203. if (!DoesDebugInfoOperandMatchExpectation(
  3204. _,
  3205. [](CommonDebugInfoInstructions dbg_inst) {
  3206. return dbg_inst == CommonDebugInfoDebugInfoNone;
  3207. },
  3208. inst, 14)) {
  3209. CHECK_OPERAND("Function", spv::Op::OpFunction, 14);
  3210. }
  3211. if (num_words == 16) {
  3212. CHECK_DEBUG_OPERAND("Declaration",
  3213. CommonDebugInfoDebugFunctionDeclaration, 15);
  3214. }
  3215. }
  3216. break;
  3217. }
  3218. case CommonDebugInfoDebugFunctionDeclaration: {
  3219. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3220. CHECK_DEBUG_OPERAND("Type", CommonDebugInfoDebugTypeFunction, 6);
  3221. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3222. CHECK_CONST_UINT_OPERAND("Line", 8);
  3223. CHECK_CONST_UINT_OPERAND("Column", 9);
  3224. auto validate_parent =
  3225. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  3226. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3227. CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  3228. CHECK_CONST_UINT_OPERAND("Flags", 12);
  3229. break;
  3230. }
  3231. case CommonDebugInfoDebugLexicalBlock: {
  3232. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 5);
  3233. CHECK_CONST_UINT_OPERAND("Line", 6);
  3234. CHECK_CONST_UINT_OPERAND("Column", 7);
  3235. auto validate_parent =
  3236. ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name);
  3237. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3238. if (num_words == 10) CHECK_OPERAND("Name", spv::Op::OpString, 9);
  3239. break;
  3240. }
  3241. case CommonDebugInfoDebugScope: {
  3242. auto validate_scope =
  3243. ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name);
  3244. if (validate_scope != SPV_SUCCESS) return validate_scope;
  3245. if (num_words == 7) {
  3246. CHECK_DEBUG_OPERAND("Inlined At", CommonDebugInfoDebugInlinedAt, 6);
  3247. }
  3248. break;
  3249. }
  3250. case CommonDebugInfoDebugLocalVariable: {
  3251. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3252. // TODO: We need a spec discussion that we have to allow local
  3253. // variable types to have template parameter.
  3254. auto validate_type =
  3255. ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
  3256. if (validate_type != SPV_SUCCESS) return validate_type;
  3257. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3258. CHECK_CONST_UINT_OPERAND("Line", 8);
  3259. CHECK_CONST_UINT_OPERAND("Column", 9);
  3260. auto validate_parent =
  3261. ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
  3262. if (validate_parent != SPV_SUCCESS) return validate_parent;
  3263. CHECK_CONST_UINT_OPERAND("Flags", 11);
  3264. if (num_words == 13) {
  3265. CHECK_CONST_UINT_OPERAND("ArgNumber", 12);
  3266. }
  3267. break;
  3268. }
  3269. case CommonDebugInfoDebugDeclare: {
  3270. CHECK_DEBUG_OPERAND("Local Variable",
  3271. CommonDebugInfoDebugLocalVariable, 5);
  3272. auto* operand = _.FindDef(inst->word(6));
  3273. if (operand->opcode() != spv::Op::OpVariable &&
  3274. operand->opcode() != spv::Op::OpFunctionParameter) {
  3275. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3276. << ext_inst_name() << ": "
  3277. << "expected operand Variable must be a result id of "
  3278. "OpVariable or OpFunctionParameter";
  3279. }
  3280. CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7);
  3281. break;
  3282. }
  3283. case CommonDebugInfoDebugExpression: {
  3284. for (uint32_t word_index = 5; word_index < num_words; ++word_index) {
  3285. CHECK_DEBUG_OPERAND("Operation", CommonDebugInfoDebugOperation,
  3286. word_index);
  3287. }
  3288. break;
  3289. }
  3290. case CommonDebugInfoDebugTypeTemplate: {
  3291. if (!DoesDebugInfoOperandMatchExpectation(
  3292. _,
  3293. [](CommonDebugInfoInstructions dbg_inst) {
  3294. return dbg_inst == CommonDebugInfoDebugTypeComposite ||
  3295. dbg_inst == CommonDebugInfoDebugFunction;
  3296. },
  3297. inst, 5)) {
  3298. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3299. << ext_inst_name() << ": "
  3300. << "expected operand Target must be DebugTypeComposite "
  3301. << "or DebugFunction";
  3302. }
  3303. for (uint32_t word_index = 6; word_index < num_words; ++word_index) {
  3304. if (!DoesDebugInfoOperandMatchExpectation(
  3305. _,
  3306. [](CommonDebugInfoInstructions dbg_inst) {
  3307. return dbg_inst ==
  3308. CommonDebugInfoDebugTypeTemplateParameter ||
  3309. dbg_inst ==
  3310. CommonDebugInfoDebugTypeTemplateTemplateParameter;
  3311. },
  3312. inst, word_index)) {
  3313. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3314. << ext_inst_name() << ": "
  3315. << "expected operand Parameters must be "
  3316. << "DebugTypeTemplateParameter or "
  3317. << "DebugTypeTemplateTemplateParameter";
  3318. }
  3319. }
  3320. break;
  3321. }
  3322. case CommonDebugInfoDebugTypeTemplateParameter: {
  3323. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3324. auto validate_actual_type = ValidateOperandDebugType(
  3325. _, "Actual Type", inst, 6, ext_inst_name, false);
  3326. if (validate_actual_type != SPV_SUCCESS) return validate_actual_type;
  3327. if (!DoesDebugInfoOperandMatchExpectation(
  3328. _,
  3329. [](CommonDebugInfoInstructions dbg_inst) {
  3330. return dbg_inst == CommonDebugInfoDebugInfoNone;
  3331. },
  3332. inst, 7)) {
  3333. CHECK_OPERAND("Value", spv::Op::OpConstant, 7);
  3334. }
  3335. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 8);
  3336. CHECK_CONST_UINT_OPERAND("Line", 9);
  3337. CHECK_CONST_UINT_OPERAND("Column", 10);
  3338. break;
  3339. }
  3340. case CommonDebugInfoDebugGlobalVariable: {
  3341. CHECK_OPERAND("Name", spv::Op::OpString, 5);
  3342. auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
  3343. ext_inst_name, false);
  3344. if (validate_type != SPV_SUCCESS) return validate_type;
  3345. CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  3346. CHECK_CONST_UINT_OPERAND("Line", 8);
  3347. CHECK_CONST_UINT_OPERAND("Column", 9);
  3348. auto validate_scope =
  3349. ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name);
  3350. if (validate_scope != SPV_SUCCESS) return validate_scope;
  3351. CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  3352. if (!DoesDebugInfoOperandMatchExpectation(
  3353. _,
  3354. [](CommonDebugInfoInstructions dbg_inst) {
  3355. return dbg_inst == CommonDebugInfoDebugInfoNone;
  3356. },
  3357. inst, 12)) {
  3358. auto* operand = _.FindDef(inst->word(12));
  3359. if (operand->opcode() != spv::Op::OpVariable &&
  3360. operand->opcode() != spv::Op::OpConstant) {
  3361. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3362. << ext_inst_name() << ": "
  3363. << "expected operand Variable must be a result id of "
  3364. "OpVariable or OpConstant or DebugInfoNone";
  3365. }
  3366. }
  3367. if (num_words == 15) {
  3368. CHECK_DEBUG_OPERAND("Static Member Declaration",
  3369. CommonDebugInfoDebugTypeMember, 14);
  3370. }
  3371. break;
  3372. }
  3373. case CommonDebugInfoDebugInlinedAt: {
  3374. CHECK_CONST_UINT_OPERAND("Line", 5);
  3375. auto validate_scope =
  3376. ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name);
  3377. if (validate_scope != SPV_SUCCESS) return validate_scope;
  3378. if (num_words == 8) {
  3379. CHECK_DEBUG_OPERAND("Inlined", CommonDebugInfoDebugInlinedAt, 7);
  3380. }
  3381. break;
  3382. }
  3383. case CommonDebugInfoDebugValue: {
  3384. CHECK_DEBUG_OPERAND("Local Variable",
  3385. CommonDebugInfoDebugLocalVariable, 5);
  3386. CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7);
  3387. for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
  3388. // TODO: The following code simply checks if it is a const int
  3389. // scalar or a DebugLocalVariable or DebugGlobalVariable, but we
  3390. // have to check it using the same validation for Indexes of
  3391. // OpAccessChain.
  3392. if (!IsConstWithIntScalarType(_, inst, word_index) &&
  3393. !IsDebugVariableWithIntScalarType(_, inst, word_index)) {
  3394. return _.diag(SPV_ERROR_INVALID_DATA, inst)
  3395. << ext_inst_name() << ": expected operand Indexes is "
  3396. << "OpConstant, DebugGlobalVariable, or "
  3397. << "type is OpConstant with an integer scalar type";
  3398. }
  3399. }
  3400. break;
  3401. }
  3402. // TODO: Add validation rules for remaining cases as well.
  3403. case CommonDebugInfoDebugTypePtrToMember:
  3404. case CommonDebugInfoDebugTypeTemplateTemplateParameter:
  3405. case CommonDebugInfoDebugTypeTemplateParameterPack:
  3406. case CommonDebugInfoDebugLexicalBlockDiscriminator:
  3407. case CommonDebugInfoDebugInlinedVariable:
  3408. case CommonDebugInfoDebugMacroDef:
  3409. case CommonDebugInfoDebugMacroUndef:
  3410. case CommonDebugInfoDebugImportedEntity:
  3411. break;
  3412. case CommonDebugInfoInstructionsMax:
  3413. assert(0);
  3414. break;
  3415. }
  3416. }
  3417. } else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
  3418. auto import_inst = _.FindDef(inst->GetOperandAs<uint32_t>(2));
  3419. const std::string name = import_inst->GetOperandAs<std::string>(1);
  3420. const std::string reflection = "NonSemantic.ClspvReflection.";
  3421. char* end_ptr;
  3422. auto version_string = name.substr(reflection.size());
  3423. if (version_string.empty()) {
  3424. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  3425. << "Missing NonSemantic.ClspvReflection import version";
  3426. }
  3427. uint32_t version = static_cast<uint32_t>(
  3428. std::strtoul(version_string.c_str(), &end_ptr, 10));
  3429. if (end_ptr && *end_ptr != '\0') {
  3430. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  3431. << "NonSemantic.ClspvReflection import does not encode the "
  3432. "version correctly";
  3433. }
  3434. if (version == 0 || version > NonSemanticClspvReflectionRevision) {
  3435. return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
  3436. << "Unknown NonSemantic.ClspvReflection import version";
  3437. }
  3438. return ValidateClspvReflectionInstruction(_, inst, version);
  3439. }
  3440. return SPV_SUCCESS;
  3441. }
  3442. spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) {
  3443. const spv::Op opcode = inst->opcode();
  3444. if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst);
  3445. if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst);
  3446. if (spvIsExtendedInstruction(opcode)) return ValidateExtInst(_, inst);
  3447. return SPV_SUCCESS;
  3448. }
  3449. } // namespace val
  3450. } // namespace spvtools