val_id_test.cpp 213 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573
  1. // Copyright (c) 2015-2016 The Khronos Group 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. #include <sstream>
  15. #include <string>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "test/test_fixture.h"
  19. #include "test/unit_spirv.h"
  20. #include "test/val/val_fixtures.h"
  21. // NOTE: The tests in this file are ONLY testing ID usage, there for the input
  22. // SPIR-V does not follow the logical layout rules from the spec in all cases in
  23. // order to makes the tests smaller. Validation of the whole module is handled
  24. // in stages, ID validation is only one of these stages. All validation stages
  25. // are stand alone.
  26. namespace spvtools {
  27. namespace val {
  28. namespace {
  29. using spvtest::ScopedContext;
  30. using ::testing::HasSubstr;
  31. using ::testing::ValuesIn;
  32. using ValidateIdWithMessage = spvtest::ValidateBase<bool>;
  33. std::string kOpCapabilitySetupWithoutVector16 = R"(
  34. OpCapability Shader
  35. OpCapability Linkage
  36. OpCapability Addresses
  37. OpCapability Int8
  38. OpCapability Int16
  39. OpCapability Int64
  40. OpCapability Float64
  41. OpCapability LiteralSampler
  42. OpCapability Pipes
  43. OpCapability DeviceEnqueue
  44. )";
  45. std::string kOpCapabilitySetup = R"(
  46. OpCapability Shader
  47. OpCapability Linkage
  48. OpCapability Addresses
  49. OpCapability Int8
  50. OpCapability Int16
  51. OpCapability Int64
  52. OpCapability Float64
  53. OpCapability LiteralSampler
  54. OpCapability Pipes
  55. OpCapability DeviceEnqueue
  56. OpCapability Vector16
  57. )";
  58. std::string kOpVariablePtrSetUp = R"(
  59. OpCapability VariablePointers
  60. OpExtension "SPV_KHR_variable_pointers"
  61. )";
  62. std::string kGLSL450MemoryModel =
  63. kOpCapabilitySetup + kOpVariablePtrSetUp + R"(
  64. OpMemoryModel Logical GLSL450
  65. )";
  66. std::string kGLSL450MemoryModelWithoutVector16 =
  67. kOpCapabilitySetupWithoutVector16 + kOpVariablePtrSetUp + R"(
  68. OpMemoryModel Logical GLSL450
  69. )";
  70. std::string kNoKernelGLSL450MemoryModel = R"(
  71. OpCapability Shader
  72. OpCapability Linkage
  73. OpCapability Addresses
  74. OpCapability Int8
  75. OpCapability Int16
  76. OpCapability Int64
  77. OpCapability Float64
  78. OpMemoryModel Logical GLSL450
  79. )";
  80. std::string kOpenCLMemoryModel32 = R"(
  81. OpCapability Addresses
  82. OpCapability Linkage
  83. OpCapability Kernel
  84. %1 = OpExtInstImport "OpenCL.std"
  85. OpMemoryModel Physical32 OpenCL
  86. )";
  87. std::string kOpenCLMemoryModel64 = R"(
  88. OpCapability Addresses
  89. OpCapability Linkage
  90. OpCapability Kernel
  91. OpCapability Int64
  92. %1 = OpExtInstImport "OpenCL.std"
  93. OpMemoryModel Physical64 OpenCL
  94. )";
  95. std::string sampledImageSetup = R"(
  96. %void = OpTypeVoid
  97. %typeFuncVoid = OpTypeFunction %void
  98. %float = OpTypeFloat 32
  99. %v4float = OpTypeVector %float 4
  100. %image_type = OpTypeImage %float 2D 0 0 0 1 Unknown
  101. %_ptr_UniformConstant_img = OpTypePointer UniformConstant %image_type
  102. %tex = OpVariable %_ptr_UniformConstant_img UniformConstant
  103. %sampler_type = OpTypeSampler
  104. %_ptr_UniformConstant_sam = OpTypePointer UniformConstant %sampler_type
  105. %s = OpVariable %_ptr_UniformConstant_sam UniformConstant
  106. %sampled_image_type = OpTypeSampledImage %image_type
  107. %v2float = OpTypeVector %float 2
  108. %float_1 = OpConstant %float 1
  109. %float_2 = OpConstant %float 2
  110. %const_vec_1_1 = OpConstantComposite %v2float %float_1 %float_1
  111. %const_vec_2_2 = OpConstantComposite %v2float %float_2 %float_2
  112. %bool_type = OpTypeBool
  113. %spec_true = OpSpecConstantTrue %bool_type
  114. %main = OpFunction %void None %typeFuncVoid
  115. %label_1 = OpLabel
  116. %image_inst = OpLoad %image_type %tex
  117. %sampler_inst = OpLoad %sampler_type %s
  118. )";
  119. std::string BranchConditionalSetup = R"(
  120. OpCapability Shader
  121. %1 = OpExtInstImport "GLSL.std.450"
  122. OpMemoryModel Logical GLSL450
  123. OpEntryPoint Fragment %main "main"
  124. OpExecutionMode %main OriginUpperLeft
  125. OpSource GLSL 140
  126. OpName %main "main"
  127. ; type definitions
  128. %bool = OpTypeBool
  129. %uint = OpTypeInt 32 0
  130. %int = OpTypeInt 32 1
  131. %float = OpTypeFloat 32
  132. %v4float = OpTypeVector %float 4
  133. ; constants
  134. %true = OpConstantTrue %bool
  135. %i0 = OpConstant %int 0
  136. %i1 = OpConstant %int 1
  137. %f0 = OpConstant %float 0
  138. %f1 = OpConstant %float 1
  139. ; main function header
  140. %void = OpTypeVoid
  141. %voidfunc = OpTypeFunction %void
  142. %main = OpFunction %void None %voidfunc
  143. %lmain = OpLabel
  144. )";
  145. std::string BranchConditionalTail = R"(
  146. %target_t = OpLabel
  147. OpNop
  148. OpBranch %end
  149. %target_f = OpLabel
  150. OpNop
  151. OpBranch %end
  152. %end = OpLabel
  153. OpReturn
  154. OpFunctionEnd
  155. )";
  156. // TODO: OpUndef
  157. TEST_F(ValidateIdWithMessage, OpName) {
  158. std::string spirv = kGLSL450MemoryModel + R"(
  159. OpName %2 "name"
  160. %1 = OpTypeInt 32 0
  161. %2 = OpTypePointer UniformConstant %1
  162. %3 = OpVariable %2 UniformConstant)";
  163. CompileSuccessfully(spirv.c_str());
  164. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  165. }
  166. TEST_F(ValidateIdWithMessage, OpMemberNameGood) {
  167. std::string spirv = kGLSL450MemoryModel + R"(
  168. OpMemberName %2 0 "foo"
  169. %1 = OpTypeInt 32 0
  170. %2 = OpTypeStruct %1)";
  171. CompileSuccessfully(spirv.c_str());
  172. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  173. }
  174. TEST_F(ValidateIdWithMessage, OpMemberNameTypeBad) {
  175. std::string spirv = kGLSL450MemoryModel + R"(
  176. OpMemberName %1 0 "foo"
  177. %1 = OpTypeInt 32 0)";
  178. CompileSuccessfully(spirv.c_str());
  179. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  180. EXPECT_THAT(
  181. getDiagnosticString(),
  182. HasSubstr("OpMemberName Type <id> '1[%uint]' is not a struct type."));
  183. }
  184. TEST_F(ValidateIdWithMessage, OpMemberNameMemberBad) {
  185. std::string spirv = kGLSL450MemoryModel + R"(
  186. OpMemberName %1 1 "foo"
  187. %2 = OpTypeInt 32 0
  188. %1 = OpTypeStruct %2)";
  189. CompileSuccessfully(spirv.c_str());
  190. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  191. EXPECT_THAT(
  192. getDiagnosticString(),
  193. HasSubstr("OpMemberName Member <id> '1[%_struct_1]' index is larger "
  194. "than Type <id> '1[%_struct_1]'s member count."));
  195. }
  196. TEST_F(ValidateIdWithMessage, OpLineGood) {
  197. std::string spirv = kGLSL450MemoryModel + R"(
  198. %1 = OpString "/path/to/source.file"
  199. OpLine %1 0 0
  200. %2 = OpTypeInt 32 0
  201. %3 = OpTypePointer Input %2
  202. %4 = OpVariable %3 Input)";
  203. CompileSuccessfully(spirv.c_str());
  204. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  205. }
  206. TEST_F(ValidateIdWithMessage, OpLineFileBad) {
  207. std::string spirv = kGLSL450MemoryModel + R"(
  208. %1 = OpTypeInt 32 0
  209. OpLine %1 0 0
  210. )";
  211. CompileSuccessfully(spirv.c_str());
  212. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  213. EXPECT_THAT(getDiagnosticString(),
  214. HasSubstr("OpLine Target <id> '1[%uint]' is not an OpString."));
  215. }
  216. TEST_F(ValidateIdWithMessage, OpDecorateGood) {
  217. std::string spirv = kGLSL450MemoryModel + R"(
  218. OpDecorate %2 GLSLShared
  219. %1 = OpTypeInt 64 0
  220. %2 = OpTypeStruct %1 %1)";
  221. CompileSuccessfully(spirv.c_str());
  222. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  223. }
  224. TEST_F(ValidateIdWithMessage, OpDecorateBad) {
  225. std::string spirv = kGLSL450MemoryModel + R"(
  226. OpDecorate %1 GLSLShared)";
  227. CompileSuccessfully(spirv.c_str());
  228. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  229. EXPECT_THAT(getDiagnosticString(),
  230. HasSubstr("forward referenced IDs have not been defined"));
  231. }
  232. TEST_F(ValidateIdWithMessage, OpMemberDecorateGood) {
  233. std::string spirv = kGLSL450MemoryModel + R"(
  234. OpMemberDecorate %2 0 RelaxedPrecision
  235. %1 = OpTypeInt 32 0
  236. %2 = OpTypeStruct %1 %1)";
  237. CompileSuccessfully(spirv.c_str());
  238. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  239. }
  240. TEST_F(ValidateIdWithMessage, OpMemberDecorateBad) {
  241. std::string spirv = kGLSL450MemoryModel + R"(
  242. OpMemberDecorate %1 0 RelaxedPrecision
  243. %1 = OpTypeInt 32 0)";
  244. CompileSuccessfully(spirv.c_str());
  245. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  246. EXPECT_THAT(getDiagnosticString(),
  247. HasSubstr("OpMemberDecorate Structure type <id> '1[%uint]' is "
  248. "not a struct type."));
  249. }
  250. TEST_F(ValidateIdWithMessage, OpMemberDecorateMemberBad) {
  251. std::string spirv = kGLSL450MemoryModel + R"(
  252. OpMemberDecorate %1 3 RelaxedPrecision
  253. %int = OpTypeInt 32 0
  254. %1 = OpTypeStruct %int %int)";
  255. CompileSuccessfully(spirv.c_str());
  256. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  257. EXPECT_THAT(getDiagnosticString(),
  258. HasSubstr("Index 3 provided in OpMemberDecorate for struct <id> "
  259. "1[%_struct_1] is out of bounds. The structure has 2 "
  260. "members. Largest valid index is 1."));
  261. }
  262. TEST_F(ValidateIdWithMessage, OpGroupDecorateGood) {
  263. std::string spirv = kGLSL450MemoryModel + R"(
  264. %1 = OpDecorationGroup
  265. OpDecorate %1 RelaxedPrecision
  266. OpDecorate %1 GLSLShared
  267. OpGroupDecorate %1 %3 %4
  268. %2 = OpTypeInt 32 0
  269. %3 = OpConstant %2 42
  270. %4 = OpConstant %2 23)";
  271. CompileSuccessfully(spirv.c_str());
  272. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  273. }
  274. TEST_F(ValidateIdWithMessage, OpDecorationGroupBad) {
  275. std::string spirv = kGLSL450MemoryModel + R"(
  276. %1 = OpDecorationGroup
  277. OpDecorate %1 RelaxedPrecision
  278. OpDecorate %1 GLSLShared
  279. OpMemberDecorate %1 0 Constant
  280. )";
  281. CompileSuccessfully(spirv.c_str());
  282. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  283. EXPECT_THAT(getDiagnosticString(),
  284. HasSubstr("Result id of OpDecorationGroup can only "
  285. "be targeted by OpName, OpGroupDecorate, "
  286. "OpDecorate, OpDecorateId, and OpGroupMemberDecorate"));
  287. }
  288. TEST_F(ValidateIdWithMessage, OpGroupDecorateDecorationGroupBad) {
  289. std::string spirv = R"(
  290. OpCapability Shader
  291. OpCapability Linkage
  292. %1 = OpExtInstImport "GLSL.std.450"
  293. OpMemoryModel Logical GLSL450
  294. OpGroupDecorate %1 %2 %3
  295. %2 = OpTypeInt 32 0
  296. %3 = OpConstant %2 42)";
  297. CompileSuccessfully(spirv.c_str());
  298. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  299. EXPECT_THAT(getDiagnosticString(),
  300. HasSubstr("OpGroupDecorate Decoration group <id> '1[%1]' is not "
  301. "a decoration group."));
  302. }
  303. TEST_F(ValidateIdWithMessage, OpGroupDecorateTargetBad) {
  304. std::string spirv = kGLSL450MemoryModel + R"(
  305. %1 = OpDecorationGroup
  306. OpDecorate %1 RelaxedPrecision
  307. OpDecorate %1 GLSLShared
  308. OpGroupDecorate %1 %3
  309. %2 = OpTypeInt 32 0)";
  310. CompileSuccessfully(spirv.c_str());
  311. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  312. EXPECT_THAT(getDiagnosticString(),
  313. HasSubstr("forward referenced IDs have not been defined"));
  314. }
  315. TEST_F(ValidateIdWithMessage, OpGroupMemberDecorateDecorationGroupBad) {
  316. std::string spirv = R"(
  317. OpCapability Shader
  318. OpCapability Linkage
  319. %1 = OpExtInstImport "GLSL.std.450"
  320. OpMemoryModel Logical GLSL450
  321. OpGroupMemberDecorate %1 %2 0
  322. %2 = OpTypeInt 32 0)";
  323. CompileSuccessfully(spirv.c_str());
  324. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  325. EXPECT_THAT(getDiagnosticString(),
  326. HasSubstr("OpGroupMemberDecorate Decoration group <id> '1[%1]' "
  327. "is not a decoration group."));
  328. }
  329. TEST_F(ValidateIdWithMessage, OpGroupMemberDecorateIdNotStructBad) {
  330. std::string spirv = kGLSL450MemoryModel + R"(
  331. %1 = OpDecorationGroup
  332. OpGroupMemberDecorate %1 %2 0
  333. %2 = OpTypeInt 32 0)";
  334. CompileSuccessfully(spirv.c_str());
  335. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  336. EXPECT_THAT(getDiagnosticString(),
  337. HasSubstr("OpGroupMemberDecorate Structure type <id> '2[%uint]' "
  338. "is not a struct type."));
  339. }
  340. TEST_F(ValidateIdWithMessage, OpGroupMemberDecorateIndexOutOfBoundBad) {
  341. std::string spirv = kGLSL450MemoryModel + R"(
  342. OpDecorate %1 Offset 0
  343. %1 = OpDecorationGroup
  344. OpGroupMemberDecorate %1 %struct 3
  345. %float = OpTypeFloat 32
  346. %struct = OpTypeStruct %float %float %float
  347. )";
  348. CompileSuccessfully(spirv.c_str());
  349. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  350. EXPECT_THAT(getDiagnosticString(),
  351. HasSubstr("Index 3 provided in OpGroupMemberDecorate for struct "
  352. "<id> 2[%_struct_2] is out of bounds. The structure "
  353. "has 3 members. Largest valid index is 2."));
  354. }
  355. // TODO: OpExtInst
  356. TEST_F(ValidateIdWithMessage, OpEntryPointGood) {
  357. std::string spirv = kGLSL450MemoryModel + R"(
  358. OpEntryPoint GLCompute %3 ""
  359. %1 = OpTypeVoid
  360. %2 = OpTypeFunction %1
  361. %3 = OpFunction %1 None %2
  362. %4 = OpLabel
  363. OpReturn
  364. OpFunctionEnd
  365. )";
  366. CompileSuccessfully(spirv.c_str());
  367. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  368. }
  369. TEST_F(ValidateIdWithMessage, OpEntryPointFunctionBad) {
  370. std::string spirv = kGLSL450MemoryModel + R"(
  371. OpEntryPoint GLCompute %1 ""
  372. %1 = OpTypeVoid)";
  373. CompileSuccessfully(spirv.c_str());
  374. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  375. EXPECT_THAT(getDiagnosticString(),
  376. HasSubstr("OpEntryPoint Entry Point <id> '1[%void]' is not a "
  377. "function."));
  378. }
  379. TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBad) {
  380. std::string spirv = kGLSL450MemoryModel + R"(
  381. OpEntryPoint GLCompute %1 ""
  382. %2 = OpTypeVoid
  383. %3 = OpTypeFunction %2 %2
  384. %1 = OpFunction %2 None %3
  385. %4 = OpLabel
  386. OpReturn
  387. OpFunctionEnd)";
  388. CompileSuccessfully(spirv.c_str());
  389. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  390. EXPECT_THAT(getDiagnosticString(),
  391. HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
  392. "parameter count is not zero"));
  393. }
  394. TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBad) {
  395. std::string spirv = kGLSL450MemoryModel + R"(
  396. OpEntryPoint GLCompute %1 ""
  397. %2 = OpTypeInt 32 0
  398. %ret = OpConstant %2 0
  399. %3 = OpTypeFunction %2
  400. %1 = OpFunction %2 None %3
  401. %4 = OpLabel
  402. OpReturnValue %ret
  403. OpFunctionEnd)";
  404. CompileSuccessfully(spirv.c_str());
  405. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  406. EXPECT_THAT(getDiagnosticString(),
  407. HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
  408. "return type is not void."));
  409. }
  410. TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBadInVulkan) {
  411. std::string spirv = R"(
  412. OpCapability Shader
  413. OpMemoryModel Logical GLSL450
  414. OpEntryPoint GLCompute %1 ""
  415. %2 = OpTypeVoid
  416. %3 = OpTypeFunction %2 %2
  417. %1 = OpFunction %2 None %3
  418. %4 = OpLabel
  419. OpReturn
  420. OpFunctionEnd)";
  421. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  422. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  423. EXPECT_THAT(getDiagnosticString(),
  424. AnyVUID("VUID-StandaloneSpirv-None-04633"));
  425. EXPECT_THAT(getDiagnosticString(),
  426. HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
  427. "parameter count is not zero"));
  428. }
  429. TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBadInVulkan) {
  430. std::string spirv = R"(
  431. OpCapability Shader
  432. OpMemoryModel Logical GLSL450
  433. OpEntryPoint GLCompute %1 ""
  434. %2 = OpTypeInt 32 0
  435. %ret = OpConstant %2 0
  436. %3 = OpTypeFunction %2
  437. %1 = OpFunction %2 None %3
  438. %4 = OpLabel
  439. OpReturnValue %ret
  440. OpFunctionEnd)";
  441. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  442. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  443. EXPECT_THAT(getDiagnosticString(),
  444. AnyVUID("VUID-StandaloneSpirv-None-04633"));
  445. EXPECT_THAT(getDiagnosticString(),
  446. HasSubstr("OpEntryPoint Entry Point <id> '1[%1]'s function "
  447. "return type is not void."));
  448. }
  449. TEST_F(ValidateIdWithMessage, OpEntryPointInterfaceIsNotVariableTypeBad) {
  450. std::string spirv = R"(
  451. OpCapability Shader
  452. OpCapability Geometry
  453. OpMemoryModel Logical GLSL450
  454. OpEntryPoint Geometry %main "main" %ptr_builtin_1
  455. OpExecutionMode %main InputPoints
  456. OpExecutionMode %main OutputPoints
  457. OpMemberDecorate %struct_1 0 BuiltIn InvocationId
  458. %int = OpTypeInt 32 1
  459. %void = OpTypeVoid
  460. %func = OpTypeFunction %void
  461. %struct_1 = OpTypeStruct %int
  462. %ptr_builtin_1 = OpTypePointer Input %struct_1
  463. %main = OpFunction %void None %func
  464. %5 = OpLabel
  465. OpReturn
  466. OpFunctionEnd
  467. )";
  468. CompileSuccessfully(spirv);
  469. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  470. EXPECT_THAT(getDiagnosticString(),
  471. HasSubstr("Interfaces passed to OpEntryPoint must be of type "
  472. "OpTypeVariable. Found OpTypePointer."));
  473. }
  474. TEST_F(ValidateIdWithMessage, OpEntryPointInterfaceStorageClassBad) {
  475. std::string spirv = R"(
  476. OpCapability Shader
  477. OpCapability Geometry
  478. OpMemoryModel Logical GLSL450
  479. OpEntryPoint Geometry %main "main" %in_1
  480. OpExecutionMode %main InputPoints
  481. OpExecutionMode %main OutputPoints
  482. OpMemberDecorate %struct_1 0 BuiltIn InvocationId
  483. %int = OpTypeInt 32 1
  484. %void = OpTypeVoid
  485. %func = OpTypeFunction %void
  486. %struct_1 = OpTypeStruct %int
  487. %ptr_builtin_1 = OpTypePointer Uniform %struct_1
  488. %in_1 = OpVariable %ptr_builtin_1 Uniform
  489. %main = OpFunction %void None %func
  490. %5 = OpLabel
  491. OpReturn
  492. OpFunctionEnd
  493. )";
  494. CompileSuccessfully(spirv);
  495. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  496. EXPECT_THAT(getDiagnosticString(),
  497. HasSubstr("OpEntryPoint interfaces must be OpVariables with "
  498. "Storage Class of Input(1) or Output(3). Found Storage "
  499. "Class 2 for Entry Point id 1."));
  500. }
  501. TEST_F(ValidateIdWithMessage, OpExecutionModeGood) {
  502. std::string spirv = kGLSL450MemoryModel + R"(
  503. OpEntryPoint GLCompute %3 ""
  504. OpExecutionMode %3 LocalSize 1 1 1
  505. %1 = OpTypeVoid
  506. %2 = OpTypeFunction %1
  507. %3 = OpFunction %1 None %2
  508. %4 = OpLabel
  509. OpReturn
  510. OpFunctionEnd)";
  511. CompileSuccessfully(spirv.c_str());
  512. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  513. }
  514. TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointMissing) {
  515. std::string spirv = kGLSL450MemoryModel + R"(
  516. OpExecutionMode %3 LocalSize 1 1 1
  517. %1 = OpTypeVoid
  518. %2 = OpTypeFunction %1
  519. %3 = OpFunction %1 None %2
  520. %4 = OpLabel
  521. OpReturn
  522. OpFunctionEnd)";
  523. CompileSuccessfully(spirv.c_str());
  524. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  525. EXPECT_THAT(getDiagnosticString(),
  526. HasSubstr("OpExecutionMode Entry Point <id> '1[%1]' is not the "
  527. "Entry Point operand of an OpEntryPoint."));
  528. }
  529. TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointBad) {
  530. std::string spirv = kGLSL450MemoryModel + R"(
  531. OpEntryPoint GLCompute %3 "" %a
  532. OpExecutionMode %a LocalSize 1 1 1
  533. %void = OpTypeVoid
  534. %ptr = OpTypePointer Input %void
  535. %a = OpVariable %ptr Input
  536. %2 = OpTypeFunction %void
  537. %3 = OpFunction %void None %2
  538. %4 = OpLabel
  539. OpReturn
  540. OpFunctionEnd)";
  541. CompileSuccessfully(spirv.c_str());
  542. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  543. EXPECT_THAT(getDiagnosticString(),
  544. HasSubstr("OpExecutionMode Entry Point <id> '2[%2]' is not the "
  545. "Entry Point operand of an OpEntryPoint."));
  546. }
  547. TEST_F(ValidateIdWithMessage, OpTypeVectorFloat) {
  548. std::string spirv = kGLSL450MemoryModel + R"(
  549. %1 = OpTypeFloat 32
  550. %2 = OpTypeVector %1 4)";
  551. CompileSuccessfully(spirv.c_str());
  552. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  553. }
  554. TEST_F(ValidateIdWithMessage, OpTypeVectorInt) {
  555. std::string spirv = kGLSL450MemoryModel + R"(
  556. %1 = OpTypeInt 32 0
  557. %2 = OpTypeVector %1 4)";
  558. CompileSuccessfully(spirv.c_str());
  559. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  560. }
  561. TEST_F(ValidateIdWithMessage, OpTypeVectorUInt) {
  562. std::string spirv = kGLSL450MemoryModel + R"(
  563. %1 = OpTypeInt 64 0
  564. %2 = OpTypeVector %1 4)";
  565. CompileSuccessfully(spirv.c_str());
  566. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  567. }
  568. TEST_F(ValidateIdWithMessage, OpTypeVectorBool) {
  569. std::string spirv = kGLSL450MemoryModel + R"(
  570. %1 = OpTypeBool
  571. %2 = OpTypeVector %1 4)";
  572. CompileSuccessfully(spirv.c_str());
  573. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  574. }
  575. TEST_F(ValidateIdWithMessage, OpTypeVectorComponentTypeBad) {
  576. std::string spirv = kGLSL450MemoryModel + R"(
  577. %1 = OpTypeFloat 32
  578. %2 = OpTypePointer UniformConstant %1
  579. %3 = OpTypeVector %2 4)";
  580. CompileSuccessfully(spirv.c_str());
  581. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  582. EXPECT_THAT(
  583. getDiagnosticString(),
  584. HasSubstr("OpTypeVector Component Type <id> "
  585. "'2[%_ptr_UniformConstant_float]' is not a scalar type."));
  586. }
  587. TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountLessThanTwoBad) {
  588. std::string spirv = kGLSL450MemoryModel + R"(
  589. %1 = OpTypeFloat 32
  590. %2 = OpTypeVector %1 1)";
  591. CompileSuccessfully(spirv.c_str());
  592. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  593. EXPECT_THAT(
  594. getDiagnosticString(),
  595. HasSubstr("Illegal number of components (1) for TypeVector\n %v1float = "
  596. "OpTypeVector %float 1\n"));
  597. }
  598. TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountGreaterThanFourBad) {
  599. std::string spirv = kGLSL450MemoryModel + R"(
  600. %1 = OpTypeFloat 32
  601. %2 = OpTypeVector %1 5)";
  602. CompileSuccessfully(spirv.c_str());
  603. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  604. EXPECT_THAT(
  605. getDiagnosticString(),
  606. HasSubstr("Illegal number of components (5) for TypeVector\n %v5float = "
  607. "OpTypeVector %float 5\n"));
  608. }
  609. TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountEightWithoutVector16Bad) {
  610. std::string spirv = kGLSL450MemoryModelWithoutVector16 + R"(
  611. %1 = OpTypeFloat 32
  612. %2 = OpTypeVector %1 8)";
  613. CompileSuccessfully(spirv.c_str());
  614. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  615. EXPECT_THAT(
  616. getDiagnosticString(),
  617. HasSubstr("Having 8 components for TypeVector requires the Vector16 "
  618. "capability\n %v8float = OpTypeVector %float 8\n"));
  619. }
  620. TEST_F(ValidateIdWithMessage,
  621. OpTypeVectorColumnCountSixteenWithoutVector16Bad) {
  622. std::string spirv = kGLSL450MemoryModelWithoutVector16 + R"(
  623. %1 = OpTypeFloat 32
  624. %2 = OpTypeVector %1 16)";
  625. CompileSuccessfully(spirv.c_str());
  626. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  627. EXPECT_THAT(
  628. getDiagnosticString(),
  629. HasSubstr("Having 16 components for TypeVector requires the Vector16 "
  630. "capability\n %v16float = OpTypeVector %float 16\n"));
  631. }
  632. TEST_F(ValidateIdWithMessage, OpTypeVectorColumnCountOfEightWithVector16Good) {
  633. std::string spirv = kGLSL450MemoryModel + R"(
  634. %1 = OpTypeFloat 32
  635. %2 = OpTypeVector %1 8)";
  636. CompileSuccessfully(spirv.c_str());
  637. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  638. }
  639. TEST_F(ValidateIdWithMessage,
  640. OpTypeVectorColumnCountOfSixteenWithVector16Good) {
  641. std::string spirv = kGLSL450MemoryModel + R"(
  642. %1 = OpTypeFloat 32
  643. %2 = OpTypeVector %1 16)";
  644. CompileSuccessfully(spirv.c_str());
  645. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  646. }
  647. TEST_F(ValidateIdWithMessage, OpTypeMatrixGood) {
  648. std::string spirv = kGLSL450MemoryModel + R"(
  649. %1 = OpTypeFloat 32
  650. %2 = OpTypeVector %1 2
  651. %3 = OpTypeMatrix %2 3)";
  652. CompileSuccessfully(spirv.c_str());
  653. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  654. }
  655. TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnTypeNonVectorBad) {
  656. std::string spirv = kGLSL450MemoryModel + R"(
  657. %1 = OpTypeFloat 32
  658. %2 = OpTypeMatrix %1 3)";
  659. CompileSuccessfully(spirv.c_str());
  660. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  661. EXPECT_THAT(
  662. getDiagnosticString(),
  663. HasSubstr("olumns in a matrix must be of type vector.\n %mat3float = "
  664. "OpTypeMatrix %float 3\n"));
  665. }
  666. TEST_F(ValidateIdWithMessage, OpTypeMatrixVectorTypeNonFloatBad) {
  667. std::string spirv = kGLSL450MemoryModel + R"(
  668. %1 = OpTypeInt 16 0
  669. %2 = OpTypeVector %1 2
  670. %3 = OpTypeMatrix %2 2)";
  671. CompileSuccessfully(spirv.c_str());
  672. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  673. EXPECT_THAT(
  674. getDiagnosticString(),
  675. HasSubstr("Matrix types can only be parameterized with floating-point "
  676. "types.\n %mat2v2ushort = OpTypeMatrix %v2ushort 2\n"));
  677. }
  678. TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnCountLessThanTwoBad) {
  679. std::string spirv = kGLSL450MemoryModel + R"(
  680. %1 = OpTypeFloat 32
  681. %2 = OpTypeVector %1 2
  682. %3 = OpTypeMatrix %2 1)";
  683. CompileSuccessfully(spirv.c_str());
  684. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  685. EXPECT_THAT(
  686. getDiagnosticString(),
  687. HasSubstr("Matrix types can only be parameterized as having only 2, 3, "
  688. "or 4 columns.\n %mat1v2float = OpTypeMatrix %v2float 1\n"));
  689. }
  690. TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnCountGreaterThanFourBad) {
  691. std::string spirv = kGLSL450MemoryModel + R"(
  692. %1 = OpTypeFloat 32
  693. %2 = OpTypeVector %1 2
  694. %3 = OpTypeMatrix %2 8)";
  695. CompileSuccessfully(spirv.c_str());
  696. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  697. EXPECT_THAT(
  698. getDiagnosticString(),
  699. HasSubstr("Matrix types can only be parameterized as having only 2, 3, "
  700. "or 4 columns.\n %mat8v2float = OpTypeMatrix %v2float 8\n"));
  701. }
  702. TEST_F(ValidateIdWithMessage, OpTypeSamplerGood) {
  703. // In Rev31, OpTypeSampler takes no arguments.
  704. std::string spirv = kGLSL450MemoryModel + R"(
  705. %s = OpTypeSampler)";
  706. CompileSuccessfully(spirv.c_str());
  707. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  708. }
  709. TEST_F(ValidateIdWithMessage, OpTypeArrayGood) {
  710. std::string spirv = kGLSL450MemoryModel + R"(
  711. %1 = OpTypeInt 32 0
  712. %2 = OpConstant %1 1
  713. %3 = OpTypeArray %1 %2)";
  714. CompileSuccessfully(spirv.c_str());
  715. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  716. }
  717. TEST_F(ValidateIdWithMessage, OpTypeArrayElementTypeBad) {
  718. std::string spirv = kGLSL450MemoryModel + R"(
  719. %1 = OpTypeInt 32 0
  720. %2 = OpConstant %1 1
  721. %3 = OpTypeArray %2 %2)";
  722. CompileSuccessfully(spirv.c_str());
  723. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  724. EXPECT_THAT(getDiagnosticString(),
  725. HasSubstr("OpTypeArray Element Type <id> '2[%uint_1]' is not a "
  726. "type."));
  727. }
  728. // Signed or unsigned.
  729. enum Signed { kSigned, kUnsigned };
  730. // Creates an assembly module declaring OpTypeArray with the given length.
  731. std::string MakeArrayLength(const std::string& len, Signed isSigned, int width,
  732. int max_int_width = 64,
  733. bool use_vulkan_memory_model = false) {
  734. std::ostringstream ss;
  735. ss << R"(
  736. OpCapability Shader
  737. )";
  738. if (use_vulkan_memory_model) {
  739. ss << " OpCapability VulkanMemoryModel\n";
  740. }
  741. if (width == 16) {
  742. ss << " OpCapability Int16\n";
  743. }
  744. if (max_int_width > 32) {
  745. ss << "\n OpCapability Int64\n";
  746. }
  747. if (use_vulkan_memory_model) {
  748. ss << " OpExtension \"SPV_KHR_vulkan_memory_model\"\n";
  749. ss << "OpMemoryModel Logical Vulkan\n";
  750. } else {
  751. ss << "OpMemoryModel Logical GLSL450\n";
  752. }
  753. ss << "OpEntryPoint GLCompute %main \"main\"\n";
  754. ss << "OpExecutionMode %main LocalSize 1 1 1\n";
  755. ss << " %t = OpTypeInt " << width << (isSigned == kSigned ? " 1" : " 0");
  756. ss << " %l = OpConstant %t " << len;
  757. ss << " %a = OpTypeArray %t %l";
  758. ss << " %void = OpTypeVoid \n"
  759. " %voidfn = OpTypeFunction %void \n"
  760. " %main = OpFunction %void None %voidfn \n"
  761. " %entry = OpLabel\n"
  762. " OpReturn\n"
  763. " OpFunctionEnd\n";
  764. return ss.str();
  765. }
  766. // Tests OpTypeArray. Parameter is the width (in bits) of the array-length's
  767. // type.
  768. class OpTypeArrayLengthTest
  769. : public spvtest::TextToBinaryTestBase<::testing::TestWithParam<int>> {
  770. protected:
  771. OpTypeArrayLengthTest()
  772. : env_(SPV_ENV_UNIVERSAL_1_0),
  773. position_(spv_position_t{0, 0, 0}),
  774. diagnostic_(spvDiagnosticCreate(&position_, "")) {}
  775. ~OpTypeArrayLengthTest() { spvDiagnosticDestroy(diagnostic_); }
  776. // Runs spvValidate() on v, printing any errors via spvDiagnosticPrint().
  777. spv_result_t Val(const SpirvVector& v, const std::string& expected_err = "") {
  778. spv_const_binary_t cbinary{v.data(), v.size()};
  779. spvDiagnosticDestroy(diagnostic_);
  780. diagnostic_ = nullptr;
  781. const auto status =
  782. spvValidate(ScopedContext(env_).context, &cbinary, &diagnostic_);
  783. if (status != SPV_SUCCESS) {
  784. spvDiagnosticPrint(diagnostic_);
  785. EXPECT_THAT(std::string(diagnostic_->error),
  786. testing::ContainsRegex(expected_err));
  787. }
  788. return status;
  789. }
  790. protected:
  791. spv_target_env env_;
  792. private:
  793. spv_position_t position_; // For creating diagnostic_.
  794. spv_diagnostic diagnostic_;
  795. };
  796. TEST_P(OpTypeArrayLengthTest, LengthPositiveSmall) {
  797. const int width = GetParam();
  798. EXPECT_EQ(SPV_SUCCESS,
  799. Val(CompileSuccessfully(MakeArrayLength("1", kSigned, width))));
  800. EXPECT_EQ(SPV_SUCCESS,
  801. Val(CompileSuccessfully(MakeArrayLength("1", kUnsigned, width))));
  802. EXPECT_EQ(SPV_SUCCESS,
  803. Val(CompileSuccessfully(MakeArrayLength("2", kSigned, width))));
  804. EXPECT_EQ(SPV_SUCCESS,
  805. Val(CompileSuccessfully(MakeArrayLength("2", kUnsigned, width))));
  806. EXPECT_EQ(SPV_SUCCESS,
  807. Val(CompileSuccessfully(MakeArrayLength("55", kSigned, width))));
  808. EXPECT_EQ(SPV_SUCCESS,
  809. Val(CompileSuccessfully(MakeArrayLength("55", kUnsigned, width))));
  810. const std::string fpad(width / 4 - 1, 'F');
  811. EXPECT_EQ(
  812. SPV_SUCCESS,
  813. Val(CompileSuccessfully(MakeArrayLength("0x7" + fpad, kSigned, width))))
  814. << MakeArrayLength("0x7" + fpad, kSigned, width);
  815. }
  816. TEST_P(OpTypeArrayLengthTest, LengthZero) {
  817. const int width = GetParam();
  818. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  819. Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width)),
  820. "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
  821. "least 1."));
  822. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  823. Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width)),
  824. "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
  825. "least 1."));
  826. }
  827. TEST_P(OpTypeArrayLengthTest, LengthNegative) {
  828. const int width = GetParam();
  829. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  830. Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width)),
  831. "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
  832. "least 1."));
  833. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  834. Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width)),
  835. "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
  836. "least 1."));
  837. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  838. Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width)),
  839. "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
  840. "least 1."));
  841. const std::string neg_max = "0x8" + std::string(width / 4 - 1, '0');
  842. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  843. Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width)),
  844. "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
  845. "least 1."));
  846. }
  847. // Returns the string form of an integer of the form 0x80....0 of the
  848. // given bit width.
  849. std::string big_num_ending_0(int bit_width) {
  850. return "0x8" + std::string(bit_width / 4 - 1, '0');
  851. }
  852. // Returns the string form of an integer of the form 0x80..001 of the
  853. // given bit width.
  854. std::string big_num_ending_1(int bit_width) {
  855. return "0x8" + std::string(bit_width / 4 - 2, '0') + "1";
  856. }
  857. TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding0InVulkan) {
  858. env_ = SPV_ENV_VULKAN_1_0;
  859. const int width = GetParam();
  860. for (int max_int_width : {32, 64}) {
  861. if (width > max_int_width) {
  862. // Not valid to even make the OpConstant in this case.
  863. continue;
  864. }
  865. const auto module = CompileSuccessfully(MakeArrayLength(
  866. big_num_ending_0(width), kUnsigned, width, max_int_width));
  867. EXPECT_EQ(SPV_SUCCESS, Val(module));
  868. }
  869. }
  870. TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding1InVulkan) {
  871. env_ = SPV_ENV_VULKAN_1_0;
  872. const int width = GetParam();
  873. for (int max_int_width : {32, 64}) {
  874. if (width > max_int_width) {
  875. // Not valid to even make the OpConstant in this case.
  876. continue;
  877. }
  878. const auto module = CompileSuccessfully(MakeArrayLength(
  879. big_num_ending_1(width), kUnsigned, width, max_int_width));
  880. EXPECT_EQ(SPV_SUCCESS, Val(module));
  881. }
  882. }
  883. // The only valid widths for integers are 8, 16, 32, and 64.
  884. // Since the Int8 capability requires the Kernel capability, and the Kernel
  885. // capability prohibits usage of signed integers, we can skip 8-bit integers
  886. // here since the purpose of these tests is to check the validity of
  887. // OpTypeArray, not OpTypeInt.
  888. INSTANTIATE_TEST_SUITE_P(Widths, OpTypeArrayLengthTest,
  889. ValuesIn(std::vector<int>{16, 32, 64}));
  890. TEST_F(ValidateIdWithMessage, OpTypeArrayLengthNull) {
  891. std::string spirv = kGLSL450MemoryModel + R"(
  892. %i32 = OpTypeInt 32 0
  893. %len = OpConstantNull %i32
  894. %ary = OpTypeArray %i32 %len)";
  895. CompileSuccessfully(spirv.c_str());
  896. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  897. EXPECT_THAT(
  898. getDiagnosticString(),
  899. HasSubstr(
  900. "OpTypeArray Length <id> '2[%2]' default value must be at least 1."));
  901. }
  902. TEST_F(ValidateIdWithMessage, OpTypeArrayLengthSpecConst) {
  903. std::string spirv = kGLSL450MemoryModel + R"(
  904. %i32 = OpTypeInt 32 0
  905. %len = OpSpecConstant %i32 2
  906. %ary = OpTypeArray %i32 %len)";
  907. CompileSuccessfully(spirv.c_str());
  908. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  909. }
  910. TEST_F(ValidateIdWithMessage, OpTypeArrayLengthSpecConstOp) {
  911. std::string spirv = kGLSL450MemoryModel + R"(
  912. %i32 = OpTypeInt 32 0
  913. %c1 = OpConstant %i32 1
  914. %c2 = OpConstant %i32 2
  915. %len = OpSpecConstantOp %i32 IAdd %c1 %c2
  916. %ary = OpTypeArray %i32 %len)";
  917. CompileSuccessfully(spirv.c_str());
  918. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  919. }
  920. TEST_F(ValidateIdWithMessage, OpTypeRuntimeArrayGood) {
  921. std::string spirv = kGLSL450MemoryModel + R"(
  922. %1 = OpTypeInt 32 0
  923. %2 = OpTypeRuntimeArray %1)";
  924. CompileSuccessfully(spirv.c_str());
  925. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  926. }
  927. TEST_F(ValidateIdWithMessage, OpTypeRuntimeArrayBad) {
  928. std::string spirv = kGLSL450MemoryModel + R"(
  929. %1 = OpTypeInt 32 0
  930. %2 = OpConstant %1 0
  931. %3 = OpTypeRuntimeArray %2)";
  932. CompileSuccessfully(spirv.c_str());
  933. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  934. EXPECT_THAT(
  935. getDiagnosticString(),
  936. HasSubstr("OpTypeRuntimeArray Element Type <id> '2[%uint_0]' is not a "
  937. "type."));
  938. }
  939. // TODO: Object of this type can only be created with OpVariable using the
  940. // Unifrom Storage Class
  941. TEST_F(ValidateIdWithMessage, OpTypeStructGood) {
  942. std::string spirv = kGLSL450MemoryModel + R"(
  943. %1 = OpTypeInt 32 0
  944. %2 = OpTypeFloat 64
  945. %3 = OpTypePointer Input %1
  946. %4 = OpTypeStruct %1 %2 %3)";
  947. CompileSuccessfully(spirv.c_str());
  948. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  949. }
  950. TEST_F(ValidateIdWithMessage, OpTypeStructMemberTypeBad) {
  951. std::string spirv = kGLSL450MemoryModel + R"(
  952. %1 = OpTypeInt 32 0
  953. %2 = OpTypeFloat 64
  954. %3 = OpConstant %2 0.0
  955. %4 = OpTypeStruct %1 %2 %3)";
  956. CompileSuccessfully(spirv.c_str());
  957. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  958. EXPECT_THAT(getDiagnosticString(),
  959. HasSubstr("OpTypeStruct Member Type <id> '3[%double_0]' is not "
  960. "a type."));
  961. }
  962. TEST_F(ValidateIdWithMessage, OpTypeStructOpaqueTypeBad) {
  963. std::string spirv = R"(
  964. OpCapability Shader
  965. OpMemoryModel Logical GLSL450
  966. OpEntryPoint Vertex %main "main"
  967. %1 = OpTypeSampler
  968. %2 = OpTypeStruct %1
  969. %void = OpTypeVoid
  970. %3 = OpTypeFunction %void
  971. %main = OpFunction %void None %3
  972. %5 = OpLabel
  973. OpReturn
  974. OpFunctionEnd
  975. )";
  976. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  977. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  978. EXPECT_THAT(getDiagnosticString(),
  979. HasSubstr("OpTypeStruct must not contain an opaque type"));
  980. }
  981. TEST_F(ValidateIdWithMessage, OpTypePointerGood) {
  982. std::string spirv = kGLSL450MemoryModel + R"(
  983. %1 = OpTypeInt 32 0
  984. %2 = OpTypePointer Input %1)";
  985. CompileSuccessfully(spirv.c_str());
  986. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  987. }
  988. TEST_F(ValidateIdWithMessage, OpTypePointerBad) {
  989. std::string spirv = kGLSL450MemoryModel + R"(
  990. %1 = OpTypeInt 32 0
  991. %2 = OpConstant %1 0
  992. %3 = OpTypePointer Input %2)";
  993. CompileSuccessfully(spirv.c_str());
  994. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  995. EXPECT_THAT(getDiagnosticString(),
  996. HasSubstr("OpTypePointer Type <id> '2[%uint_0]' is not a "
  997. "type."));
  998. }
  999. TEST_F(ValidateIdWithMessage, OpTypeFunctionGood) {
  1000. std::string spirv = kGLSL450MemoryModel + R"(
  1001. %1 = OpTypeVoid
  1002. %2 = OpTypeFunction %1)";
  1003. CompileSuccessfully(spirv.c_str());
  1004. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1005. }
  1006. TEST_F(ValidateIdWithMessage, OpTypeFunctionReturnTypeBad) {
  1007. std::string spirv = kGLSL450MemoryModel + R"(
  1008. %1 = OpTypeInt 32 0
  1009. %2 = OpConstant %1 0
  1010. %3 = OpTypeFunction %2)";
  1011. CompileSuccessfully(spirv.c_str());
  1012. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1013. EXPECT_THAT(getDiagnosticString(),
  1014. HasSubstr("OpTypeFunction Return Type <id> '2[%uint_0]' is not "
  1015. "a type."));
  1016. }
  1017. TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterBad) {
  1018. std::string spirv = kGLSL450MemoryModel + R"(
  1019. %1 = OpTypeVoid
  1020. %2 = OpTypeInt 32 0
  1021. %3 = OpConstant %2 0
  1022. %4 = OpTypeFunction %1 %2 %3)";
  1023. CompileSuccessfully(spirv.c_str());
  1024. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1025. EXPECT_THAT(
  1026. getDiagnosticString(),
  1027. HasSubstr("OpTypeFunction Parameter Type <id> '3[%uint_0]' is not a "
  1028. "type."));
  1029. }
  1030. TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterTypeVoidBad) {
  1031. std::string spirv = kGLSL450MemoryModel + R"(
  1032. %1 = OpTypeVoid
  1033. %2 = OpTypeInt 32 0
  1034. %4 = OpTypeFunction %1 %2 %1)";
  1035. CompileSuccessfully(spirv.c_str());
  1036. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1037. EXPECT_THAT(getDiagnosticString(),
  1038. HasSubstr("OpTypeFunction Parameter Type <id> '1[%void]' cannot "
  1039. "be OpTypeVoid."));
  1040. }
  1041. TEST_F(ValidateIdWithMessage, OpTypePipeGood) {
  1042. std::string spirv = kGLSL450MemoryModel + R"(
  1043. %1 = OpTypeFloat 32
  1044. %2 = OpTypeVector %1 16
  1045. %3 = OpTypePipe ReadOnly)";
  1046. CompileSuccessfully(spirv.c_str());
  1047. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1048. }
  1049. TEST_F(ValidateIdWithMessage, OpConstantTrueGood) {
  1050. std::string spirv = kGLSL450MemoryModel + R"(
  1051. %1 = OpTypeBool
  1052. %2 = OpConstantTrue %1)";
  1053. CompileSuccessfully(spirv.c_str());
  1054. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1055. }
  1056. TEST_F(ValidateIdWithMessage, OpConstantTrueBad) {
  1057. std::string spirv = kGLSL450MemoryModel + R"(
  1058. %1 = OpTypeVoid
  1059. %2 = OpConstantTrue %1)";
  1060. CompileSuccessfully(spirv.c_str());
  1061. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1062. EXPECT_THAT(
  1063. getDiagnosticString(),
  1064. HasSubstr("OpConstantTrue Result Type <id> '1[%void]' is not a boolean "
  1065. "type."));
  1066. }
  1067. TEST_F(ValidateIdWithMessage, OpConstantFalseGood) {
  1068. std::string spirv = kGLSL450MemoryModel + R"(
  1069. %1 = OpTypeBool
  1070. %2 = OpConstantTrue %1)";
  1071. CompileSuccessfully(spirv.c_str());
  1072. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1073. }
  1074. TEST_F(ValidateIdWithMessage, OpConstantFalseBad) {
  1075. std::string spirv = kGLSL450MemoryModel + R"(
  1076. %1 = OpTypeVoid
  1077. %2 = OpConstantFalse %1)";
  1078. CompileSuccessfully(spirv.c_str());
  1079. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1080. EXPECT_THAT(
  1081. getDiagnosticString(),
  1082. HasSubstr("OpConstantFalse Result Type <id> '1[%void]' is not a boolean "
  1083. "type."));
  1084. }
  1085. TEST_F(ValidateIdWithMessage, OpConstantGood) {
  1086. std::string spirv = kGLSL450MemoryModel + R"(
  1087. %1 = OpTypeInt 32 0
  1088. %2 = OpConstant %1 1)";
  1089. CompileSuccessfully(spirv.c_str());
  1090. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1091. }
  1092. TEST_F(ValidateIdWithMessage, OpConstantBad) {
  1093. std::string spirv = kGLSL450MemoryModel + R"(
  1094. %1 = OpTypeVoid
  1095. %2 = OpConstant !1 !0)";
  1096. // The expected failure code is implementation dependent (currently
  1097. // INVALID_BINARY because the binary parser catches these cases) and may
  1098. // change over time, but this must always fail.
  1099. CompileSuccessfully(spirv.c_str());
  1100. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
  1101. }
  1102. TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorGood) {
  1103. std::string spirv = kGLSL450MemoryModel + R"(
  1104. %1 = OpTypeFloat 32
  1105. %2 = OpTypeVector %1 4
  1106. %3 = OpConstant %1 3.14
  1107. %4 = OpConstantComposite %2 %3 %3 %3 %3)";
  1108. CompileSuccessfully(spirv.c_str());
  1109. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1110. }
  1111. TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorWithUndefGood) {
  1112. std::string spirv = kGLSL450MemoryModel + R"(
  1113. %1 = OpTypeFloat 32
  1114. %2 = OpTypeVector %1 4
  1115. %3 = OpConstant %1 3.14
  1116. %9 = OpUndef %1
  1117. %4 = OpConstantComposite %2 %3 %3 %3 %9)";
  1118. CompileSuccessfully(spirv.c_str());
  1119. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1120. }
  1121. TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorResultTypeBad) {
  1122. std::string spirv = kGLSL450MemoryModel + R"(
  1123. %1 = OpTypeFloat 32
  1124. %2 = OpTypeVector %1 4
  1125. %3 = OpConstant %1 3.14
  1126. %4 = OpConstantComposite %1 %3 %3 %3 %3)";
  1127. CompileSuccessfully(spirv.c_str());
  1128. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1129. EXPECT_THAT(
  1130. getDiagnosticString(),
  1131. HasSubstr("OpConstantComposite Result Type <id> '1[%float]' is not a "
  1132. "composite type."));
  1133. }
  1134. TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorConstituentTypeBad) {
  1135. std::string spirv = kGLSL450MemoryModel + R"(
  1136. %1 = OpTypeFloat 32
  1137. %2 = OpTypeVector %1 4
  1138. %4 = OpTypeInt 32 0
  1139. %3 = OpConstant %1 3.14
  1140. %5 = OpConstant %4 42 ; bad type for constant value
  1141. %6 = OpConstantComposite %2 %3 %5 %3 %3)";
  1142. CompileSuccessfully(spirv.c_str());
  1143. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1144. EXPECT_THAT(
  1145. getDiagnosticString(),
  1146. HasSubstr("OpConstantComposite Constituent <id> '5[%uint_42]'s type "
  1147. "does not match Result Type <id> '2[%v4float]'s vector "
  1148. "element type."));
  1149. }
  1150. TEST_F(ValidateIdWithMessage,
  1151. OpConstantCompositeVectorConstituentUndefTypeBad) {
  1152. std::string spirv = kGLSL450MemoryModel + R"(
  1153. %1 = OpTypeFloat 32
  1154. %2 = OpTypeVector %1 4
  1155. %4 = OpTypeInt 32 0
  1156. %3 = OpConstant %1 3.14
  1157. %5 = OpUndef %4 ; bad type for undef value
  1158. %6 = OpConstantComposite %2 %3 %5 %3 %3)";
  1159. CompileSuccessfully(spirv.c_str());
  1160. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1161. EXPECT_THAT(
  1162. getDiagnosticString(),
  1163. HasSubstr("OpConstantComposite Constituent <id> '5[%5]'s type does not "
  1164. "match Result Type <id> '2[%v4float]'s vector element type."));
  1165. }
  1166. TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixGood) {
  1167. std::string spirv = kGLSL450MemoryModel + R"(
  1168. %1 = OpTypeFloat 32
  1169. %2 = OpTypeVector %1 4
  1170. %3 = OpTypeMatrix %2 4
  1171. %4 = OpConstant %1 1.0
  1172. %5 = OpConstant %1 0.0
  1173. %6 = OpConstantComposite %2 %4 %5 %5 %5
  1174. %7 = OpConstantComposite %2 %5 %4 %5 %5
  1175. %8 = OpConstantComposite %2 %5 %5 %4 %5
  1176. %9 = OpConstantComposite %2 %5 %5 %5 %4
  1177. %10 = OpConstantComposite %3 %6 %7 %8 %9)";
  1178. CompileSuccessfully(spirv.c_str());
  1179. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1180. }
  1181. TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixUndefGood) {
  1182. std::string spirv = kGLSL450MemoryModel + R"(
  1183. %1 = OpTypeFloat 32
  1184. %2 = OpTypeVector %1 4
  1185. %3 = OpTypeMatrix %2 4
  1186. %4 = OpConstant %1 1.0
  1187. %5 = OpConstant %1 0.0
  1188. %6 = OpConstantComposite %2 %4 %5 %5 %5
  1189. %7 = OpConstantComposite %2 %5 %4 %5 %5
  1190. %8 = OpConstantComposite %2 %5 %5 %4 %5
  1191. %9 = OpUndef %2
  1192. %10 = OpConstantComposite %3 %6 %7 %8 %9)";
  1193. CompileSuccessfully(spirv.c_str());
  1194. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1195. }
  1196. TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixConstituentTypeBad) {
  1197. std::string spirv = kGLSL450MemoryModel + R"(
  1198. %1 = OpTypeFloat 32
  1199. %2 = OpTypeVector %1 4
  1200. %11 = OpTypeVector %1 3
  1201. %3 = OpTypeMatrix %2 4
  1202. %4 = OpConstant %1 1.0
  1203. %5 = OpConstant %1 0.0
  1204. %6 = OpConstantComposite %2 %4 %5 %5 %5
  1205. %7 = OpConstantComposite %2 %5 %4 %5 %5
  1206. %8 = OpConstantComposite %2 %5 %5 %4 %5
  1207. %9 = OpConstantComposite %11 %5 %5 %5
  1208. %10 = OpConstantComposite %3 %6 %7 %8 %9)";
  1209. CompileSuccessfully(spirv.c_str());
  1210. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1211. EXPECT_THAT(getDiagnosticString(),
  1212. HasSubstr("OpConstantComposite Constituent <id> '10[%10]' vector "
  1213. "component count does not match Result Type <id> "
  1214. "'4[%mat4v4float]'s vector component count."));
  1215. }
  1216. TEST_F(ValidateIdWithMessage,
  1217. OpConstantCompositeMatrixConstituentUndefTypeBad) {
  1218. std::string spirv = kGLSL450MemoryModel + R"(
  1219. %1 = OpTypeFloat 32
  1220. %2 = OpTypeVector %1 4
  1221. %11 = OpTypeVector %1 3
  1222. %3 = OpTypeMatrix %2 4
  1223. %4 = OpConstant %1 1.0
  1224. %5 = OpConstant %1 0.0
  1225. %6 = OpConstantComposite %2 %4 %5 %5 %5
  1226. %7 = OpConstantComposite %2 %5 %4 %5 %5
  1227. %8 = OpConstantComposite %2 %5 %5 %4 %5
  1228. %9 = OpUndef %11
  1229. %10 = OpConstantComposite %3 %6 %7 %8 %9)";
  1230. CompileSuccessfully(spirv.c_str());
  1231. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1232. EXPECT_THAT(getDiagnosticString(),
  1233. HasSubstr("OpConstantComposite Constituent <id> '10[%10]' vector "
  1234. "component count does not match Result Type <id> "
  1235. "'4[%mat4v4float]'s vector component count."));
  1236. }
  1237. TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayGood) {
  1238. std::string spirv = kGLSL450MemoryModel + R"(
  1239. %1 = OpTypeInt 32 0
  1240. %2 = OpConstant %1 4
  1241. %3 = OpTypeArray %1 %2
  1242. %4 = OpConstantComposite %3 %2 %2 %2 %2)";
  1243. CompileSuccessfully(spirv.c_str());
  1244. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1245. }
  1246. TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayWithUndefGood) {
  1247. std::string spirv = kGLSL450MemoryModel + R"(
  1248. %1 = OpTypeInt 32 0
  1249. %2 = OpConstant %1 4
  1250. %9 = OpUndef %1
  1251. %3 = OpTypeArray %1 %2
  1252. %4 = OpConstantComposite %3 %2 %2 %2 %9)";
  1253. CompileSuccessfully(spirv.c_str());
  1254. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1255. }
  1256. TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentTypeBad) {
  1257. std::string spirv = kGLSL450MemoryModel + R"(
  1258. %1 = OpTypeInt 32 0
  1259. %2 = OpConstant %1 4
  1260. %3 = OpTypeArray %1 %2
  1261. %4 = OpConstantComposite %3 %2 %2 %2 %1)"; // Uses a type as operand
  1262. CompileSuccessfully(spirv.c_str());
  1263. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1264. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 1[%uint] cannot be a "
  1265. "type"));
  1266. }
  1267. TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentBad) {
  1268. std::string spirv = kGLSL450MemoryModel + R"(
  1269. %1 = OpTypeInt 32 0
  1270. %2 = OpConstant %1 4
  1271. %3 = OpTypeArray %1 %2
  1272. %4 = OpTypePointer Uniform %1
  1273. %5 = OpVariable %4 Uniform
  1274. %6 = OpConstantComposite %3 %2 %2 %2 %5)";
  1275. CompileSuccessfully(spirv.c_str());
  1276. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1277. EXPECT_THAT(getDiagnosticString(),
  1278. HasSubstr("OpConstantComposite Constituent <id> '5[%5]' is not a "
  1279. "constant or undef."));
  1280. }
  1281. TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentTypeBad) {
  1282. std::string spirv = kGLSL450MemoryModel + R"(
  1283. %1 = OpTypeInt 32 0
  1284. %2 = OpConstant %1 4
  1285. %3 = OpTypeArray %1 %2
  1286. %5 = OpTypeFloat 32
  1287. %6 = OpConstant %5 3.14 ; bad type for const value
  1288. %4 = OpConstantComposite %3 %2 %2 %2 %6)";
  1289. CompileSuccessfully(spirv.c_str());
  1290. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1291. EXPECT_THAT(getDiagnosticString(),
  1292. HasSubstr("OpConstantComposite Constituent <id> "
  1293. "'5[%float_3_1400001]'s type does not match Result "
  1294. "Type <id> '3[%_arr_uint_uint_4]'s array element "
  1295. "type."));
  1296. }
  1297. TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentUndefTypeBad) {
  1298. std::string spirv = kGLSL450MemoryModel + R"(
  1299. %1 = OpTypeInt 32 0
  1300. %2 = OpConstant %1 4
  1301. %3 = OpTypeArray %1 %2
  1302. %5 = OpTypeFloat 32
  1303. %6 = OpUndef %5 ; bad type for undef
  1304. %4 = OpConstantComposite %3 %2 %2 %2 %6)";
  1305. CompileSuccessfully(spirv.c_str());
  1306. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1307. EXPECT_THAT(getDiagnosticString(),
  1308. HasSubstr("OpConstantComposite Constituent <id> "
  1309. "'5[%5]'s type does not match Result "
  1310. "Type <id> '3[%_arr_uint_uint_4]'s array element "
  1311. "type."));
  1312. }
  1313. TEST_F(ValidateIdWithMessage, OpConstantCompositeStructGood) {
  1314. std::string spirv = kGLSL450MemoryModel + R"(
  1315. %1 = OpTypeInt 32 0
  1316. %2 = OpTypeInt 64 0
  1317. %3 = OpTypeStruct %1 %1 %2
  1318. %4 = OpConstant %1 42
  1319. %5 = OpConstant %2 4300000000
  1320. %6 = OpConstantComposite %3 %4 %4 %5)";
  1321. CompileSuccessfully(spirv.c_str());
  1322. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1323. }
  1324. TEST_F(ValidateIdWithMessage, OpConstantCompositeStructUndefGood) {
  1325. std::string spirv = kGLSL450MemoryModel + R"(
  1326. %1 = OpTypeInt 32 0
  1327. %2 = OpTypeInt 64 0
  1328. %3 = OpTypeStruct %1 %1 %2
  1329. %4 = OpConstant %1 42
  1330. %5 = OpUndef %2
  1331. %6 = OpConstantComposite %3 %4 %4 %5)";
  1332. CompileSuccessfully(spirv.c_str());
  1333. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1334. }
  1335. TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberTypeBad) {
  1336. std::string spirv = kGLSL450MemoryModel + R"(
  1337. %1 = OpTypeInt 32 0
  1338. %2 = OpTypeInt 64 0
  1339. %3 = OpTypeStruct %1 %1 %2
  1340. %4 = OpConstant %1 42
  1341. %5 = OpConstant %2 4300000000
  1342. %6 = OpConstantComposite %3 %4 %5 %4)";
  1343. CompileSuccessfully(spirv.c_str());
  1344. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1345. EXPECT_THAT(getDiagnosticString(),
  1346. HasSubstr("OpConstantComposite Constituent <id> "
  1347. "'5[%ulong_4300000000]' type does not match the "
  1348. "Result Type <id> '3[%_struct_3]'s member type."));
  1349. }
  1350. TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberUndefTypeBad) {
  1351. std::string spirv = kGLSL450MemoryModel + R"(
  1352. %1 = OpTypeInt 32 0
  1353. %2 = OpTypeInt 64 0
  1354. %3 = OpTypeStruct %1 %1 %2
  1355. %4 = OpConstant %1 42
  1356. %5 = OpUndef %2
  1357. %6 = OpConstantComposite %3 %4 %5 %4)";
  1358. CompileSuccessfully(spirv.c_str());
  1359. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1360. EXPECT_THAT(getDiagnosticString(),
  1361. HasSubstr("OpConstantComposite Constituent <id> '5[%5]' type "
  1362. "does not match the Result Type <id> '3[%_struct_3]'s "
  1363. "member type."));
  1364. }
  1365. TEST_F(ValidateIdWithMessage, OpConstantSamplerGood) {
  1366. std::string spirv = kGLSL450MemoryModel + R"(
  1367. %float = OpTypeFloat 32
  1368. %samplerType = OpTypeSampler
  1369. %3 = OpConstantSampler %samplerType ClampToEdge 0 Nearest)";
  1370. CompileSuccessfully(spirv.c_str());
  1371. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1372. }
  1373. TEST_F(ValidateIdWithMessage, OpConstantSamplerResultTypeBad) {
  1374. std::string spirv = kGLSL450MemoryModel + R"(
  1375. %1 = OpTypeFloat 32
  1376. %2 = OpConstantSampler %1 Clamp 0 Nearest)";
  1377. CompileSuccessfully(spirv.c_str());
  1378. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1379. EXPECT_THAT(
  1380. getDiagnosticString(),
  1381. HasSubstr(
  1382. "OpConstantSampler Result Type <id> '1[%float]' is not a sampler "
  1383. "type."));
  1384. }
  1385. TEST_F(ValidateIdWithMessage, OpConstantNullGood) {
  1386. std::string spirv = kGLSL450MemoryModel + R"(
  1387. %1 = OpTypeBool
  1388. %2 = OpConstantNull %1
  1389. %3 = OpTypeInt 32 0
  1390. %4 = OpConstantNull %3
  1391. %5 = OpTypeFloat 32
  1392. %6 = OpConstantNull %5
  1393. %7 = OpTypePointer UniformConstant %3
  1394. %8 = OpConstantNull %7
  1395. %9 = OpTypeEvent
  1396. %10 = OpConstantNull %9
  1397. %11 = OpTypeDeviceEvent
  1398. %12 = OpConstantNull %11
  1399. %13 = OpTypeReserveId
  1400. %14 = OpConstantNull %13
  1401. %15 = OpTypeQueue
  1402. %16 = OpConstantNull %15
  1403. %17 = OpTypeVector %5 2
  1404. %18 = OpConstantNull %17
  1405. %19 = OpTypeMatrix %17 2
  1406. %20 = OpConstantNull %19
  1407. %25 = OpConstant %3 8
  1408. %21 = OpTypeArray %3 %25
  1409. %22 = OpConstantNull %21
  1410. %23 = OpTypeStruct %3 %5 %1
  1411. %24 = OpConstantNull %23
  1412. %26 = OpTypeArray %17 %25
  1413. %27 = OpConstantNull %26
  1414. %28 = OpTypeStruct %7 %26 %26 %1
  1415. %29 = OpConstantNull %28
  1416. )";
  1417. CompileSuccessfully(spirv.c_str());
  1418. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1419. }
  1420. TEST_F(ValidateIdWithMessage, OpConstantNullBasicBad) {
  1421. std::string spirv = kGLSL450MemoryModel + R"(
  1422. %1 = OpTypeVoid
  1423. %2 = OpConstantNull %1)";
  1424. CompileSuccessfully(spirv.c_str());
  1425. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1426. EXPECT_THAT(
  1427. getDiagnosticString(),
  1428. HasSubstr("OpConstantNull Result Type <id> '1[%void]' cannot have a null "
  1429. "value."));
  1430. }
  1431. TEST_F(ValidateIdWithMessage, OpConstantNullArrayBad) {
  1432. std::string spirv = kGLSL450MemoryModel + R"(
  1433. %2 = OpTypeInt 32 0
  1434. %3 = OpTypeSampler
  1435. %4 = OpConstant %2 4
  1436. %5 = OpTypeArray %3 %4
  1437. %6 = OpConstantNull %5)";
  1438. CompileSuccessfully(spirv.c_str());
  1439. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1440. EXPECT_THAT(
  1441. getDiagnosticString(),
  1442. HasSubstr(
  1443. "OpConstantNull Result Type <id> '4[%_arr_2_uint_4]' cannot have a "
  1444. "null value."));
  1445. }
  1446. TEST_F(ValidateIdWithMessage, OpConstantNullStructBad) {
  1447. std::string spirv = kGLSL450MemoryModel + R"(
  1448. %2 = OpTypeSampler
  1449. %3 = OpTypeStruct %2 %2
  1450. %4 = OpConstantNull %3)";
  1451. CompileSuccessfully(spirv.c_str());
  1452. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1453. EXPECT_THAT(getDiagnosticString(),
  1454. HasSubstr("OpConstantNull Result Type <id> '2[%_struct_2]' "
  1455. "cannot have a null value."));
  1456. }
  1457. TEST_F(ValidateIdWithMessage, OpConstantNullRuntimeArrayBad) {
  1458. std::string spirv = kGLSL450MemoryModel + R"(
  1459. %bool = OpTypeBool
  1460. %array = OpTypeRuntimeArray %bool
  1461. %null = OpConstantNull %array)";
  1462. CompileSuccessfully(spirv.c_str());
  1463. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1464. EXPECT_THAT(
  1465. getDiagnosticString(),
  1466. HasSubstr(
  1467. "OpConstantNull Result Type <id> '2[%_runtimearr_bool]' cannot have "
  1468. "a null value."));
  1469. }
  1470. TEST_F(ValidateIdWithMessage, OpSpecConstantTrueGood) {
  1471. std::string spirv = kGLSL450MemoryModel + R"(
  1472. %1 = OpTypeBool
  1473. %2 = OpSpecConstantTrue %1)";
  1474. CompileSuccessfully(spirv.c_str());
  1475. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1476. }
  1477. TEST_F(ValidateIdWithMessage, OpSpecConstantTrueBad) {
  1478. std::string spirv = kGLSL450MemoryModel + R"(
  1479. %1 = OpTypeVoid
  1480. %2 = OpSpecConstantTrue %1)";
  1481. CompileSuccessfully(spirv.c_str());
  1482. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1483. EXPECT_THAT(getDiagnosticString(),
  1484. HasSubstr("OpSpecConstantTrue Result Type <id> '1[%void]' is not "
  1485. "a boolean type"));
  1486. }
  1487. TEST_F(ValidateIdWithMessage, OpSpecConstantFalseGood) {
  1488. std::string spirv = kGLSL450MemoryModel + R"(
  1489. %1 = OpTypeBool
  1490. %2 = OpSpecConstantFalse %1)";
  1491. CompileSuccessfully(spirv.c_str());
  1492. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1493. }
  1494. TEST_F(ValidateIdWithMessage, OpSpecConstantFalseBad) {
  1495. std::string spirv = kGLSL450MemoryModel + R"(
  1496. %1 = OpTypeVoid
  1497. %2 = OpSpecConstantFalse %1)";
  1498. CompileSuccessfully(spirv.c_str());
  1499. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1500. EXPECT_THAT(
  1501. getDiagnosticString(),
  1502. HasSubstr("OpSpecConstantFalse Result Type <id> '1[%void]' is not "
  1503. "a boolean type"));
  1504. }
  1505. TEST_F(ValidateIdWithMessage, OpSpecConstantGood) {
  1506. std::string spirv = kGLSL450MemoryModel + R"(
  1507. %1 = OpTypeFloat 32
  1508. %2 = OpSpecConstant %1 42)";
  1509. CompileSuccessfully(spirv.c_str());
  1510. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1511. }
  1512. TEST_F(ValidateIdWithMessage, OpSpecConstantBad) {
  1513. std::string spirv = kGLSL450MemoryModel + R"(
  1514. %1 = OpTypeVoid
  1515. %2 = OpSpecConstant !1 !4)";
  1516. // The expected failure code is implementation dependent (currently
  1517. // INVALID_BINARY because the binary parser catches these cases) and may
  1518. // change over time, but this must always fail.
  1519. CompileSuccessfully(spirv.c_str());
  1520. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
  1521. EXPECT_THAT(getDiagnosticString(),
  1522. HasSubstr("Type Id 1 is not a scalar numeric type"));
  1523. }
  1524. // Valid: SpecConstantComposite specializes to a vector.
  1525. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorGood) {
  1526. std::string spirv = kGLSL450MemoryModel + R"(
  1527. %1 = OpTypeFloat 32
  1528. %2 = OpTypeVector %1 4
  1529. %3 = OpSpecConstant %1 3.14
  1530. %4 = OpConstant %1 3.14
  1531. %5 = OpSpecConstantComposite %2 %3 %3 %4 %4)";
  1532. CompileSuccessfully(spirv.c_str());
  1533. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1534. }
  1535. // Valid: Vector of floats and Undefs.
  1536. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorWithUndefGood) {
  1537. std::string spirv = kGLSL450MemoryModel + R"(
  1538. %1 = OpTypeFloat 32
  1539. %2 = OpTypeVector %1 4
  1540. %3 = OpSpecConstant %1 3.14
  1541. %5 = OpConstant %1 3.14
  1542. %9 = OpUndef %1
  1543. %4 = OpSpecConstantComposite %2 %3 %5 %3 %9)";
  1544. CompileSuccessfully(spirv.c_str());
  1545. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1546. }
  1547. // Invalid: result type is float.
  1548. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorResultTypeBad) {
  1549. std::string spirv = kGLSL450MemoryModel + R"(
  1550. %1 = OpTypeFloat 32
  1551. %2 = OpTypeVector %1 4
  1552. %3 = OpSpecConstant %1 3.14
  1553. %4 = OpSpecConstantComposite %1 %3 %3 %3 %3)";
  1554. CompileSuccessfully(spirv.c_str());
  1555. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1556. EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a composite type"));
  1557. }
  1558. // Invalid: Vector contains a mix of Int and Float.
  1559. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorConstituentTypeBad) {
  1560. std::string spirv = kGLSL450MemoryModel + R"(
  1561. %1 = OpTypeFloat 32
  1562. %2 = OpTypeVector %1 4
  1563. %4 = OpTypeInt 32 0
  1564. %3 = OpSpecConstant %1 3.14
  1565. %5 = OpConstant %4 42 ; bad type for constant value
  1566. %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
  1567. CompileSuccessfully(spirv.c_str());
  1568. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1569. EXPECT_THAT(getDiagnosticString(),
  1570. HasSubstr("OpSpecConstantComposite Constituent <id> "
  1571. "'5[%uint_42]'s type does not match Result Type <id> "
  1572. "'2[%v4float]'s vector element type."));
  1573. }
  1574. // Invalid: Constituent is not a constant
  1575. TEST_F(ValidateIdWithMessage,
  1576. OpSpecConstantCompositeVectorConstituentNotConstantBad) {
  1577. std::string spirv = kGLSL450MemoryModel + R"(
  1578. %1 = OpTypeFloat 32
  1579. %2 = OpTypeVector %1 4
  1580. %3 = OpTypeInt 32 0
  1581. %4 = OpSpecConstant %1 3.14
  1582. %5 = OpTypePointer Uniform %1
  1583. %6 = OpVariable %5 Uniform
  1584. %7 = OpSpecConstantComposite %2 %6 %4 %4 %4)";
  1585. CompileSuccessfully(spirv.c_str());
  1586. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1587. EXPECT_THAT(getDiagnosticString(),
  1588. HasSubstr("OpSpecConstantComposite Constituent <id> '6[%6]' is "
  1589. "not a constant or undef."));
  1590. }
  1591. // Invalid: Vector contains a mix of Undef-int and Float.
  1592. TEST_F(ValidateIdWithMessage,
  1593. OpSpecConstantCompositeVectorConstituentUndefTypeBad) {
  1594. std::string spirv = kGLSL450MemoryModel + R"(
  1595. %1 = OpTypeFloat 32
  1596. %2 = OpTypeVector %1 4
  1597. %4 = OpTypeInt 32 0
  1598. %3 = OpSpecConstant %1 3.14
  1599. %5 = OpUndef %4 ; bad type for undef value
  1600. %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
  1601. CompileSuccessfully(spirv.c_str());
  1602. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1603. EXPECT_THAT(getDiagnosticString(),
  1604. HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]'s "
  1605. "type does not match Result Type <id> '2[%v4float]'s "
  1606. "vector element type."));
  1607. }
  1608. // Invalid: Vector expects 3 components, but 4 specified.
  1609. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeVectorNumComponentsBad) {
  1610. std::string spirv = kGLSL450MemoryModel + R"(
  1611. %1 = OpTypeFloat 32
  1612. %2 = OpTypeVector %1 3
  1613. %3 = OpConstant %1 3.14
  1614. %5 = OpSpecConstant %1 4.0
  1615. %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
  1616. CompileSuccessfully(spirv.c_str());
  1617. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1618. EXPECT_THAT(getDiagnosticString(),
  1619. HasSubstr("OpSpecConstantComposite Constituent <id> count does "
  1620. "not match Result Type <id> '2[%v3float]'s vector "
  1621. "component count."));
  1622. }
  1623. // Valid: 4x4 matrix of floats
  1624. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixGood) {
  1625. std::string spirv = kGLSL450MemoryModel + R"(
  1626. %1 = OpTypeFloat 32
  1627. %2 = OpTypeVector %1 4
  1628. %3 = OpTypeMatrix %2 4
  1629. %4 = OpConstant %1 1.0
  1630. %5 = OpSpecConstant %1 0.0
  1631. %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
  1632. %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
  1633. %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
  1634. %9 = OpSpecConstantComposite %2 %5 %5 %5 %4
  1635. %10 = OpSpecConstantComposite %3 %6 %7 %8 %9)";
  1636. CompileSuccessfully(spirv.c_str());
  1637. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1638. }
  1639. // Valid: Matrix in which one column is Undef
  1640. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixUndefGood) {
  1641. std::string spirv = kGLSL450MemoryModel + R"(
  1642. %1 = OpTypeFloat 32
  1643. %2 = OpTypeVector %1 4
  1644. %3 = OpTypeMatrix %2 4
  1645. %4 = OpConstant %1 1.0
  1646. %5 = OpSpecConstant %1 0.0
  1647. %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
  1648. %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
  1649. %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
  1650. %9 = OpUndef %2
  1651. %10 = OpSpecConstantComposite %3 %6 %7 %8 %9)";
  1652. CompileSuccessfully(spirv.c_str());
  1653. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1654. }
  1655. // Invalid: Matrix in which the sizes of column vectors are not equal.
  1656. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixConstituentTypeBad) {
  1657. std::string spirv = kGLSL450MemoryModel + R"(
  1658. %1 = OpTypeFloat 32
  1659. %2 = OpTypeVector %1 4
  1660. %3 = OpTypeVector %1 3
  1661. %4 = OpTypeMatrix %2 4
  1662. %5 = OpSpecConstant %1 1.0
  1663. %6 = OpConstant %1 0.0
  1664. %7 = OpSpecConstantComposite %2 %5 %6 %6 %6
  1665. %8 = OpSpecConstantComposite %2 %6 %5 %6 %6
  1666. %9 = OpSpecConstantComposite %2 %6 %6 %5 %6
  1667. %10 = OpSpecConstantComposite %3 %6 %6 %6
  1668. %11 = OpSpecConstantComposite %4 %7 %8 %9 %10)";
  1669. CompileSuccessfully(spirv.c_str());
  1670. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1671. EXPECT_THAT(getDiagnosticString(),
  1672. HasSubstr("OpSpecConstantComposite Constituent <id> '10[%10]' "
  1673. "vector component count does not match Result Type "
  1674. "<id> '4[%mat4v4float]'s vector component count."));
  1675. }
  1676. // Invalid: Matrix type expects 4 columns but only 3 specified.
  1677. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixNumColsBad) {
  1678. std::string spirv = kGLSL450MemoryModel + R"(
  1679. %1 = OpTypeFloat 32
  1680. %2 = OpTypeVector %1 4
  1681. %3 = OpTypeMatrix %2 4
  1682. %4 = OpSpecConstant %1 1.0
  1683. %5 = OpConstant %1 0.0
  1684. %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
  1685. %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
  1686. %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
  1687. %10 = OpSpecConstantComposite %3 %6 %7 %8)";
  1688. CompileSuccessfully(spirv.c_str());
  1689. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1690. EXPECT_THAT(
  1691. getDiagnosticString(),
  1692. HasSubstr("OpSpecConstantComposite Constituent <id> count does "
  1693. "not match Result Type <id> '3[%mat4v4float]'s matrix column "
  1694. "count."));
  1695. }
  1696. // Invalid: Composite contains a non-const/undef component
  1697. TEST_F(ValidateIdWithMessage,
  1698. OpSpecConstantCompositeMatrixConstituentNotConstBad) {
  1699. std::string spirv = kGLSL450MemoryModel + R"(
  1700. %1 = OpTypeFloat 32
  1701. %2 = OpConstant %1 0.0
  1702. %3 = OpTypeVector %1 4
  1703. %4 = OpTypeMatrix %3 4
  1704. %5 = OpSpecConstantComposite %3 %2 %2 %2 %2
  1705. %6 = OpTypePointer Uniform %1
  1706. %7 = OpVariable %6 Uniform
  1707. %8 = OpSpecConstantComposite %4 %5 %5 %5 %7)";
  1708. CompileSuccessfully(spirv.c_str());
  1709. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1710. EXPECT_THAT(getDiagnosticString(),
  1711. HasSubstr("OpSpecConstantComposite Constituent <id> '7[%7]' is "
  1712. "not a constant or undef."));
  1713. }
  1714. // Invalid: Composite contains a column that is *not* a vector (it's an array)
  1715. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixColTypeBad) {
  1716. std::string spirv = kGLSL450MemoryModel + R"(
  1717. %1 = OpTypeFloat 32
  1718. %2 = OpTypeInt 32 0
  1719. %3 = OpSpecConstant %2 4
  1720. %4 = OpConstant %1 0.0
  1721. %5 = OpTypeVector %1 4
  1722. %6 = OpTypeArray %2 %3
  1723. %7 = OpTypeMatrix %5 4
  1724. %8 = OpSpecConstantComposite %6 %3 %3 %3 %3
  1725. %9 = OpSpecConstantComposite %5 %4 %4 %4 %4
  1726. %10 = OpSpecConstantComposite %7 %9 %9 %9 %8)";
  1727. CompileSuccessfully(spirv.c_str());
  1728. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1729. EXPECT_THAT(getDiagnosticString(),
  1730. HasSubstr("OpSpecConstantComposite Constituent <id> '8[%8]' type "
  1731. "does not match Result Type <id> '7[%mat4v4float]'s "
  1732. "matrix column type."));
  1733. }
  1734. // Invalid: Matrix with an Undef column of the wrong size.
  1735. TEST_F(ValidateIdWithMessage,
  1736. OpSpecConstantCompositeMatrixConstituentUndefTypeBad) {
  1737. std::string spirv = kGLSL450MemoryModel + R"(
  1738. %1 = OpTypeFloat 32
  1739. %2 = OpTypeVector %1 4
  1740. %3 = OpTypeVector %1 3
  1741. %4 = OpTypeMatrix %2 4
  1742. %5 = OpSpecConstant %1 1.0
  1743. %6 = OpSpecConstant %1 0.0
  1744. %7 = OpSpecConstantComposite %2 %5 %6 %6 %6
  1745. %8 = OpSpecConstantComposite %2 %6 %5 %6 %6
  1746. %9 = OpSpecConstantComposite %2 %6 %6 %5 %6
  1747. %10 = OpUndef %3
  1748. %11 = OpSpecConstantComposite %4 %7 %8 %9 %10)";
  1749. CompileSuccessfully(spirv.c_str());
  1750. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1751. EXPECT_THAT(getDiagnosticString(),
  1752. HasSubstr("OpSpecConstantComposite Constituent <id> '10[%10]' "
  1753. "vector component count does not match Result Type "
  1754. "<id> '4[%mat4v4float]'s vector component count."));
  1755. }
  1756. // Invalid: Matrix in which some columns are Int and some are Float.
  1757. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeMatrixColumnTypeBad) {
  1758. std::string spirv = kGLSL450MemoryModel + R"(
  1759. %1 = OpTypeInt 32 0
  1760. %2 = OpTypeFloat 32
  1761. %3 = OpTypeVector %1 2
  1762. %4 = OpTypeVector %2 2
  1763. %5 = OpTypeMatrix %4 2
  1764. %6 = OpSpecConstant %1 42
  1765. %7 = OpConstant %2 3.14
  1766. %8 = OpSpecConstantComposite %3 %6 %6
  1767. %9 = OpSpecConstantComposite %4 %7 %7
  1768. %10 = OpSpecConstantComposite %5 %8 %9)";
  1769. CompileSuccessfully(spirv.c_str());
  1770. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1771. EXPECT_THAT(getDiagnosticString(),
  1772. HasSubstr("OpSpecConstantComposite Constituent <id> '8[%8]' "
  1773. "component type does not match Result Type <id> "
  1774. "'5[%mat2v2float]'s matrix column component type."));
  1775. }
  1776. // Valid: Array of integers
  1777. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayGood) {
  1778. std::string spirv = kGLSL450MemoryModel + R"(
  1779. %1 = OpTypeInt 32 0
  1780. %2 = OpSpecConstant %1 4
  1781. %5 = OpConstant %1 5
  1782. %3 = OpTypeArray %1 %2
  1783. %6 = OpTypeArray %1 %5
  1784. %4 = OpSpecConstantComposite %3 %2 %2 %2 %2
  1785. %7 = OpSpecConstantComposite %3 %5 %5 %5 %5)";
  1786. CompileSuccessfully(spirv.c_str());
  1787. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1788. }
  1789. // Invalid: Expecting an array of 4 components, but 3 specified.
  1790. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayNumComponentsBad) {
  1791. std::string spirv = kGLSL450MemoryModel + R"(
  1792. %1 = OpTypeInt 32 0
  1793. %2 = OpConstant %1 4
  1794. %3 = OpTypeArray %1 %2
  1795. %4 = OpSpecConstantComposite %3 %2 %2 %2)";
  1796. CompileSuccessfully(spirv.c_str());
  1797. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1798. EXPECT_THAT(getDiagnosticString(),
  1799. HasSubstr("OpSpecConstantComposite Constituent count does not "
  1800. "match Result Type <id> '3[%_arr_uint_uint_4]'s array "
  1801. "length."));
  1802. }
  1803. // Valid: Array of Integers and Undef-int
  1804. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayWithUndefGood) {
  1805. std::string spirv = kGLSL450MemoryModel + R"(
  1806. %1 = OpTypeInt 32 0
  1807. %2 = OpSpecConstant %1 4
  1808. %9 = OpUndef %1
  1809. %3 = OpTypeArray %1 %2
  1810. %4 = OpSpecConstantComposite %3 %2 %2 %2 %9)";
  1811. CompileSuccessfully(spirv.c_str());
  1812. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1813. }
  1814. // Invalid: Array uses a type as operand.
  1815. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayConstConstituentBad) {
  1816. std::string spirv = kGLSL450MemoryModel + R"(
  1817. %1 = OpTypeInt 32 0
  1818. %2 = OpConstant %1 4
  1819. %3 = OpTypeArray %1 %2
  1820. %4 = OpTypePointer Uniform %1
  1821. %5 = OpVariable %4 Uniform
  1822. %6 = OpSpecConstantComposite %3 %2 %2 %2 %5)";
  1823. CompileSuccessfully(spirv.c_str());
  1824. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1825. EXPECT_THAT(getDiagnosticString(),
  1826. HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]' is "
  1827. "not a constant or undef."));
  1828. }
  1829. // Invalid: Array has a mix of Int and Float components.
  1830. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeArrayConstituentTypeBad) {
  1831. std::string spirv = kGLSL450MemoryModel + R"(
  1832. %1 = OpTypeInt 32 0
  1833. %2 = OpConstant %1 4
  1834. %3 = OpTypeArray %1 %2
  1835. %4 = OpTypeFloat 32
  1836. %5 = OpSpecConstant %4 3.14 ; bad type for const value
  1837. %6 = OpSpecConstantComposite %3 %2 %2 %2 %5)";
  1838. CompileSuccessfully(spirv.c_str());
  1839. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1840. EXPECT_THAT(getDiagnosticString(),
  1841. HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]'s "
  1842. "type does not match Result Type <id> "
  1843. "'3[%_arr_uint_uint_4]'s array element type."));
  1844. }
  1845. // Invalid: Array has a mix of Int and Undef-float.
  1846. TEST_F(ValidateIdWithMessage,
  1847. OpSpecConstantCompositeArrayConstituentUndefTypeBad) {
  1848. std::string spirv = kGLSL450MemoryModel + R"(
  1849. %1 = OpTypeInt 32 0
  1850. %2 = OpSpecConstant %1 4
  1851. %3 = OpTypeArray %1 %2
  1852. %5 = OpTypeFloat 32
  1853. %6 = OpUndef %5 ; bad type for undef
  1854. %4 = OpSpecConstantComposite %3 %2 %2 %2 %6)";
  1855. CompileSuccessfully(spirv.c_str());
  1856. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1857. EXPECT_THAT(getDiagnosticString(),
  1858. HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]'s "
  1859. "type does not match Result Type <id> "
  1860. "'3[%_arr_uint_2]'s array element type."));
  1861. }
  1862. // Valid: Struct of {Int32,Int32,Int64}.
  1863. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructGood) {
  1864. std::string spirv = kGLSL450MemoryModel + R"(
  1865. %1 = OpTypeInt 32 0
  1866. %2 = OpTypeInt 64 0
  1867. %3 = OpTypeStruct %1 %1 %2
  1868. %4 = OpConstant %1 42
  1869. %5 = OpSpecConstant %2 4300000000
  1870. %6 = OpSpecConstantComposite %3 %4 %4 %5)";
  1871. CompileSuccessfully(spirv.c_str());
  1872. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1873. }
  1874. // Invalid: missing one int32 struct member.
  1875. TEST_F(ValidateIdWithMessage,
  1876. OpSpecConstantCompositeStructMissingComponentBad) {
  1877. std::string spirv = kGLSL450MemoryModel + R"(
  1878. %1 = OpTypeInt 32 0
  1879. %3 = OpTypeStruct %1 %1 %1
  1880. %4 = OpConstant %1 42
  1881. %5 = OpSpecConstant %1 430
  1882. %6 = OpSpecConstantComposite %3 %4 %5)";
  1883. CompileSuccessfully(spirv.c_str());
  1884. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1885. EXPECT_THAT(getDiagnosticString(),
  1886. HasSubstr("OpSpecConstantComposite Constituent <id> "
  1887. "'2[%_struct_2]' count does not match Result Type "
  1888. "<id> '2[%_struct_2]'s struct member count."));
  1889. }
  1890. // Valid: Struct uses Undef-int64.
  1891. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructUndefGood) {
  1892. std::string spirv = kGLSL450MemoryModel + R"(
  1893. %1 = OpTypeInt 32 0
  1894. %2 = OpTypeInt 64 0
  1895. %3 = OpTypeStruct %1 %1 %2
  1896. %4 = OpSpecConstant %1 42
  1897. %5 = OpUndef %2
  1898. %6 = OpSpecConstantComposite %3 %4 %4 %5)";
  1899. CompileSuccessfully(spirv.c_str());
  1900. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1901. }
  1902. // Invalid: Composite contains non-const/undef component.
  1903. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructNonConstBad) {
  1904. std::string spirv = kGLSL450MemoryModel + R"(
  1905. %1 = OpTypeInt 32 0
  1906. %2 = OpTypeInt 64 0
  1907. %3 = OpTypeStruct %1 %1 %2
  1908. %4 = OpSpecConstant %1 42
  1909. %5 = OpUndef %2
  1910. %6 = OpTypePointer Uniform %1
  1911. %7 = OpVariable %6 Uniform
  1912. %8 = OpSpecConstantComposite %3 %4 %7 %5)";
  1913. CompileSuccessfully(spirv.c_str());
  1914. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1915. EXPECT_THAT(getDiagnosticString(),
  1916. HasSubstr("OpSpecConstantComposite Constituent <id> '7[%7]' is "
  1917. "not a constant or undef."));
  1918. }
  1919. // Invalid: Struct component type does not match expected specialization type.
  1920. // Second component was expected to be Int32, but got Int64.
  1921. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructMemberTypeBad) {
  1922. std::string spirv = kGLSL450MemoryModel + R"(
  1923. %1 = OpTypeInt 32 0
  1924. %2 = OpTypeInt 64 0
  1925. %3 = OpTypeStruct %1 %1 %2
  1926. %4 = OpConstant %1 42
  1927. %5 = OpSpecConstant %2 4300000000
  1928. %6 = OpSpecConstantComposite %3 %4 %5 %4)";
  1929. CompileSuccessfully(spirv.c_str());
  1930. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1931. EXPECT_THAT(getDiagnosticString(),
  1932. HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]' type "
  1933. "does not match the Result Type <id> '3[%_struct_3]'s "
  1934. "member type."));
  1935. }
  1936. // Invalid: Undef-int64 used when Int32 was expected.
  1937. TEST_F(ValidateIdWithMessage, OpSpecConstantCompositeStructMemberUndefTypeBad) {
  1938. std::string spirv = kGLSL450MemoryModel + R"(
  1939. %1 = OpTypeInt 32 0
  1940. %2 = OpTypeInt 64 0
  1941. %3 = OpTypeStruct %1 %1 %2
  1942. %4 = OpSpecConstant %1 42
  1943. %5 = OpUndef %2
  1944. %6 = OpSpecConstantComposite %3 %4 %5 %4)";
  1945. CompileSuccessfully(spirv.c_str());
  1946. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1947. EXPECT_THAT(getDiagnosticString(),
  1948. HasSubstr("OpSpecConstantComposite Constituent <id> '5[%5]' type "
  1949. "does not match the Result Type <id> '3[%_struct_3]'s "
  1950. "member type."));
  1951. }
  1952. // TODO: OpSpecConstantOp
  1953. TEST_F(ValidateIdWithMessage, OpVariableGood) {
  1954. std::string spirv = kGLSL450MemoryModel + R"(
  1955. %1 = OpTypeInt 32 0
  1956. %2 = OpTypePointer Input %1
  1957. %3 = OpVariable %2 Input)";
  1958. CompileSuccessfully(spirv.c_str());
  1959. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1960. }
  1961. TEST_F(ValidateIdWithMessage, OpVariableInitializerConstantGood) {
  1962. std::string spirv = kGLSL450MemoryModel + R"(
  1963. %1 = OpTypeInt 32 0
  1964. %2 = OpTypePointer Input %1
  1965. %3 = OpConstant %1 42
  1966. %4 = OpVariable %2 Input %3)";
  1967. CompileSuccessfully(spirv.c_str());
  1968. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1969. }
  1970. TEST_F(ValidateIdWithMessage, OpVariableInitializerGlobalVariableGood) {
  1971. std::string spirv = kGLSL450MemoryModel + R"(
  1972. %1 = OpTypeInt 32 0
  1973. %2 = OpTypePointer Uniform %1
  1974. %3 = OpVariable %2 Uniform
  1975. %4 = OpTypePointer Private %2 ; pointer to pointer
  1976. %5 = OpVariable %4 Private %3
  1977. )";
  1978. CompileSuccessfully(spirv.c_str());
  1979. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  1980. }
  1981. // TODO: Positive test OpVariable with OpConstantNull of OpTypePointer
  1982. TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
  1983. std::string spirv = kGLSL450MemoryModel + R"(
  1984. %1 = OpTypeInt 32 0
  1985. %2 = OpVariable %1 Input)";
  1986. CompileSuccessfully(spirv.c_str());
  1987. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1988. EXPECT_THAT(
  1989. getDiagnosticString(),
  1990. HasSubstr("OpVariable Result Type <id> '1[%uint]' is not a pointer "
  1991. "type."));
  1992. }
  1993. TEST_F(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) {
  1994. std::string spirv = kGLSL450MemoryModel + R"(
  1995. %1 = OpTypeInt 32 0
  1996. %2 = OpTypePointer Input %1
  1997. %3 = OpVariable %2 Input %2)";
  1998. CompileSuccessfully(spirv.c_str());
  1999. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2000. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 2[%_ptr_Input_uint] "
  2001. "cannot be a type"));
  2002. }
  2003. TEST_F(ValidateIdWithMessage, OpVariableInitializerIsFunctionVarBad) {
  2004. std::string spirv = kGLSL450MemoryModel + R"(
  2005. %int = OpTypeInt 32 0
  2006. %ptrint = OpTypePointer Function %int
  2007. %ptrptrint = OpTypePointer Function %ptrint
  2008. %void = OpTypeVoid
  2009. %fnty = OpTypeFunction %void
  2010. %main = OpFunction %void None %fnty
  2011. %entry = OpLabel
  2012. %var = OpVariable %ptrint Function
  2013. %varinit = OpVariable %ptrptrint Function %var ; Can't initialize function variable.
  2014. OpReturn
  2015. OpFunctionEnd
  2016. )";
  2017. CompileSuccessfully(spirv.c_str());
  2018. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2019. EXPECT_THAT(getDiagnosticString(),
  2020. HasSubstr("OpVariable Initializer <id> '8[%8]' is not a constant "
  2021. "or module-scope variable"));
  2022. }
  2023. TEST_F(ValidateIdWithMessage, OpVariableInitializerIsModuleVarGood) {
  2024. std::string spirv = kGLSL450MemoryModel + R"(
  2025. %int = OpTypeInt 32 0
  2026. %ptrint = OpTypePointer Uniform %int
  2027. %mvar = OpVariable %ptrint Uniform
  2028. %ptrptrint = OpTypePointer Function %ptrint
  2029. %void = OpTypeVoid
  2030. %fnty = OpTypeFunction %void
  2031. %main = OpFunction %void None %fnty
  2032. %entry = OpLabel
  2033. %goodvar = OpVariable %ptrptrint Function %mvar ; This is ok
  2034. OpReturn
  2035. OpFunctionEnd
  2036. )";
  2037. CompileSuccessfully(spirv.c_str());
  2038. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2039. }
  2040. TEST_F(ValidateIdWithMessage, OpVariableContainsBoolBad) {
  2041. std::string spirv = kGLSL450MemoryModel + R"(
  2042. %bool = OpTypeBool
  2043. %int = OpTypeInt 32 0
  2044. %block = OpTypeStruct %bool %int
  2045. %_ptr_Uniform_block = OpTypePointer Uniform %block
  2046. %var = OpVariable %_ptr_Uniform_block Uniform
  2047. %void = OpTypeVoid
  2048. %fnty = OpTypeFunction %void
  2049. %main = OpFunction %void None %fnty
  2050. %entry = OpLabel
  2051. %load = OpLoad %block %var
  2052. OpReturn
  2053. OpFunctionEnd
  2054. )";
  2055. CompileSuccessfully(spirv.c_str());
  2056. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2057. EXPECT_THAT(getDiagnosticString(),
  2058. HasSubstr("If OpTypeBool is stored in conjunction with OpVariable"
  2059. ", it can only be used with non-externally visible "
  2060. "shader Storage Classes: Workgroup, CrossWorkgroup, "
  2061. "Private, and Function"));
  2062. }
  2063. TEST_F(ValidateIdWithMessage, OpVariableContainsBoolPointerGood) {
  2064. std::string spirv = kGLSL450MemoryModel + R"(
  2065. %bool = OpTypeBool
  2066. %boolptr = OpTypePointer Uniform %bool
  2067. %int = OpTypeInt 32 0
  2068. %block = OpTypeStruct %boolptr %int
  2069. %_ptr_Uniform_block = OpTypePointer Uniform %block
  2070. %var = OpVariable %_ptr_Uniform_block Uniform
  2071. %void = OpTypeVoid
  2072. %fnty = OpTypeFunction %void
  2073. %main = OpFunction %void None %fnty
  2074. %entry = OpLabel
  2075. %load = OpLoad %block %var
  2076. OpReturn
  2077. OpFunctionEnd
  2078. )";
  2079. CompileSuccessfully(spirv.c_str());
  2080. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2081. }
  2082. TEST_F(ValidateIdWithMessage, OpVariableContainsBuiltinBoolGood) {
  2083. std::string spirv = kGLSL450MemoryModel + R"(
  2084. OpMemberDecorate %input 0 BuiltIn FrontFacing
  2085. %bool = OpTypeBool
  2086. %input = OpTypeStruct %bool
  2087. %_ptr_input = OpTypePointer Input %input
  2088. %var = OpVariable %_ptr_input Input
  2089. %void = OpTypeVoid
  2090. %fnty = OpTypeFunction %void
  2091. %main = OpFunction %void None %fnty
  2092. %entry = OpLabel
  2093. %load = OpLoad %input %var
  2094. OpReturn
  2095. OpFunctionEnd
  2096. )";
  2097. CompileSuccessfully(spirv.c_str());
  2098. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2099. }
  2100. TEST_F(ValidateIdWithMessage, OpVariableContainsRayPayloadBoolGood) {
  2101. std::string spirv = R"(
  2102. OpCapability RayTracingNV
  2103. OpCapability Shader
  2104. OpCapability Linkage
  2105. OpExtension "SPV_NV_ray_tracing"
  2106. OpMemoryModel Logical GLSL450
  2107. %bool = OpTypeBool
  2108. %PerRayData = OpTypeStruct %bool
  2109. %_ptr_PerRayData = OpTypePointer RayPayloadNV %PerRayData
  2110. %var = OpVariable %_ptr_PerRayData RayPayloadNV
  2111. %void = OpTypeVoid
  2112. %fnty = OpTypeFunction %void
  2113. %main = OpFunction %void None %fnty
  2114. %entry = OpLabel
  2115. %load = OpLoad %PerRayData %var
  2116. OpReturn
  2117. OpFunctionEnd
  2118. )";
  2119. CompileSuccessfully(spirv.c_str());
  2120. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2121. }
  2122. TEST_F(ValidateIdWithMessage, OpVariablePointerNoVariablePointersBad) {
  2123. const std::string spirv = R"(
  2124. OpCapability Shader
  2125. OpCapability Linkage
  2126. OpMemoryModel Logical GLSL450
  2127. %void = OpTypeVoid
  2128. %int = OpTypeInt 32 0
  2129. %_ptr_workgroup_int = OpTypePointer Workgroup %int
  2130. %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
  2131. %voidfn = OpTypeFunction %void
  2132. %func = OpFunction %void None %voidfn
  2133. %entry = OpLabel
  2134. %var = OpVariable %_ptr_function_ptr Function
  2135. OpReturn
  2136. OpFunctionEnd
  2137. )";
  2138. CompileSuccessfully(spirv);
  2139. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2140. EXPECT_THAT(
  2141. getDiagnosticString(),
  2142. HasSubstr(
  2143. "In Logical addressing, variables may not allocate a pointer type"));
  2144. }
  2145. TEST_F(ValidateIdWithMessage,
  2146. OpVariablePointerNoVariablePointersRelaxedLogicalGood) {
  2147. const std::string spirv = R"(
  2148. OpCapability Shader
  2149. OpCapability Linkage
  2150. OpMemoryModel Logical GLSL450
  2151. %void = OpTypeVoid
  2152. %int = OpTypeInt 32 0
  2153. %_ptr_workgroup_int = OpTypePointer Workgroup %int
  2154. %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
  2155. %voidfn = OpTypeFunction %void
  2156. %func = OpFunction %void None %voidfn
  2157. %entry = OpLabel
  2158. %var = OpVariable %_ptr_function_ptr Function
  2159. OpReturn
  2160. OpFunctionEnd
  2161. )";
  2162. auto options = getValidatorOptions();
  2163. options->relax_logical_pointer = true;
  2164. CompileSuccessfully(spirv);
  2165. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2166. }
  2167. TEST_F(ValidateIdWithMessage, OpFunctionWithNonMemoryObject) {
  2168. // DXC generates code that looks like when given something like:
  2169. // T t;
  2170. // t.s.fn_1();
  2171. // This needs to be accepted before legalization takes place, so we
  2172. // will include it with the relaxed logical pointer.
  2173. const std::string spirv = R"(
  2174. OpCapability Shader
  2175. OpMemoryModel Logical GLSL450
  2176. OpEntryPoint Vertex %1 "main"
  2177. OpSource HLSL 600
  2178. %int = OpTypeInt 32 1
  2179. %int_0 = OpConstant %int 0
  2180. %void = OpTypeVoid
  2181. %9 = OpTypeFunction %void
  2182. %_struct_5 = OpTypeStruct
  2183. %_struct_6 = OpTypeStruct %_struct_5
  2184. %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
  2185. %_ptr_Function__struct_5 = OpTypePointer Function %_struct_5
  2186. %23 = OpTypeFunction %void %_ptr_Function__struct_5
  2187. %1 = OpFunction %void None %9
  2188. %10 = OpLabel
  2189. %11 = OpVariable %_ptr_Function__struct_6 Function
  2190. %20 = OpAccessChain %_ptr_Function__struct_5 %11 %int_0
  2191. %21 = OpFunctionCall %void %12 %20
  2192. OpReturn
  2193. OpFunctionEnd
  2194. %12 = OpFunction %void None %23
  2195. %13 = OpFunctionParameter %_ptr_Function__struct_5
  2196. %14 = OpLabel
  2197. OpReturn
  2198. OpFunctionEnd
  2199. )";
  2200. auto options = getValidatorOptions();
  2201. options->relax_logical_pointer = true;
  2202. CompileSuccessfully(spirv);
  2203. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2204. }
  2205. TEST_F(ValidateIdWithMessage,
  2206. OpVariablePointerVariablePointersStorageBufferGood) {
  2207. const std::string spirv = R"(
  2208. OpCapability Shader
  2209. OpCapability Linkage
  2210. OpCapability VariablePointersStorageBuffer
  2211. OpExtension "SPV_KHR_variable_pointers"
  2212. OpMemoryModel Logical GLSL450
  2213. %void = OpTypeVoid
  2214. %int = OpTypeInt 32 0
  2215. %_ptr_workgroup_int = OpTypePointer Workgroup %int
  2216. %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
  2217. %voidfn = OpTypeFunction %void
  2218. %func = OpFunction %void None %voidfn
  2219. %entry = OpLabel
  2220. %var = OpVariable %_ptr_function_ptr Function
  2221. OpReturn
  2222. OpFunctionEnd
  2223. )";
  2224. CompileSuccessfully(spirv);
  2225. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2226. }
  2227. TEST_F(ValidateIdWithMessage, OpVariablePointerVariablePointersGood) {
  2228. const std::string spirv = R"(
  2229. OpCapability Shader
  2230. OpCapability Linkage
  2231. OpCapability VariablePointers
  2232. OpExtension "SPV_KHR_variable_pointers"
  2233. OpMemoryModel Logical GLSL450
  2234. %void = OpTypeVoid
  2235. %int = OpTypeInt 32 0
  2236. %_ptr_workgroup_int = OpTypePointer Workgroup %int
  2237. %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
  2238. %voidfn = OpTypeFunction %void
  2239. %func = OpFunction %void None %voidfn
  2240. %entry = OpLabel
  2241. %var = OpVariable %_ptr_function_ptr Function
  2242. OpReturn
  2243. OpFunctionEnd
  2244. )";
  2245. CompileSuccessfully(spirv);
  2246. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2247. }
  2248. TEST_F(ValidateIdWithMessage, OpVariablePointerVariablePointersBad) {
  2249. const std::string spirv = R"(
  2250. OpCapability Shader
  2251. OpCapability VariablePointers
  2252. OpExtension "SPV_KHR_variable_pointers"
  2253. OpMemoryModel Logical GLSL450
  2254. %void = OpTypeVoid
  2255. %int = OpTypeInt 32 0
  2256. %_ptr_workgroup_int = OpTypePointer Workgroup %int
  2257. %_ptr_uniform_ptr = OpTypePointer Uniform %_ptr_workgroup_int
  2258. %var = OpVariable %_ptr_uniform_ptr Uniform
  2259. )";
  2260. CompileSuccessfully(spirv);
  2261. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2262. EXPECT_THAT(getDiagnosticString(),
  2263. HasSubstr("In Logical addressing with variable pointers, "
  2264. "variables that allocate pointers must be in Function "
  2265. "or Private storage classes"));
  2266. }
  2267. TEST_F(ValidateIdWithMessage, OpLoadGood) {
  2268. std::string spirv = kGLSL450MemoryModel + R"(
  2269. %1 = OpTypeVoid
  2270. %2 = OpTypeInt 32 0
  2271. %3 = OpTypePointer UniformConstant %2
  2272. %4 = OpTypeFunction %1
  2273. %5 = OpVariable %3 UniformConstant
  2274. %6 = OpFunction %1 None %4
  2275. %7 = OpLabel
  2276. %8 = OpLoad %2 %5
  2277. OpReturn
  2278. OpFunctionEnd
  2279. )";
  2280. CompileSuccessfully(spirv.c_str());
  2281. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2282. }
  2283. // TODO: Add tests that exercise VariablePointersStorageBuffer instead of
  2284. // VariablePointers.
  2285. void createVariablePointerSpirvProgram(std::ostringstream* spirv,
  2286. std::string result_strategy,
  2287. bool use_varptr_cap,
  2288. bool add_helper_function) {
  2289. *spirv << "OpCapability Shader ";
  2290. if (use_varptr_cap) {
  2291. *spirv << "OpCapability VariablePointers ";
  2292. *spirv << "OpExtension \"SPV_KHR_variable_pointers\" ";
  2293. }
  2294. *spirv << "OpExtension \"SPV_KHR_storage_buffer_storage_class\" ";
  2295. *spirv << R"(
  2296. OpMemoryModel Logical GLSL450
  2297. OpEntryPoint GLCompute %main "main"
  2298. %void = OpTypeVoid
  2299. %voidf = OpTypeFunction %void
  2300. %bool = OpTypeBool
  2301. %i32 = OpTypeInt 32 1
  2302. %f32 = OpTypeFloat 32
  2303. %f32ptr = OpTypePointer StorageBuffer %f32
  2304. %i = OpConstant %i32 1
  2305. %zero = OpConstant %i32 0
  2306. %float_1 = OpConstant %f32 1.0
  2307. %ptr1 = OpVariable %f32ptr StorageBuffer
  2308. %ptr2 = OpVariable %f32ptr StorageBuffer
  2309. )";
  2310. if (add_helper_function) {
  2311. *spirv << R"(
  2312. ; ////////////////////////////////////////////////////////////
  2313. ;;;; Function that returns a pointer
  2314. ; ////////////////////////////////////////////////////////////
  2315. %selector_func_type = OpTypeFunction %f32ptr %bool %f32ptr %f32ptr
  2316. %choose_input_func = OpFunction %f32ptr None %selector_func_type
  2317. %is_neg_param = OpFunctionParameter %bool
  2318. %first_ptr_param = OpFunctionParameter %f32ptr
  2319. %second_ptr_param = OpFunctionParameter %f32ptr
  2320. %selector_func_begin = OpLabel
  2321. %result_ptr = OpSelect %f32ptr %is_neg_param %first_ptr_param %second_ptr_param
  2322. OpReturnValue %result_ptr
  2323. OpFunctionEnd
  2324. )";
  2325. }
  2326. *spirv << R"(
  2327. %main = OpFunction %void None %voidf
  2328. %label = OpLabel
  2329. )";
  2330. *spirv << result_strategy;
  2331. *spirv << R"(
  2332. OpReturn
  2333. OpFunctionEnd
  2334. )";
  2335. }
  2336. // With the VariablePointer Capability, OpLoad should allow loading a
  2337. // VaiablePointer. In this test the variable pointer is obtained by an OpSelect
  2338. TEST_F(ValidateIdWithMessage, OpLoadVarPtrOpSelectGood) {
  2339. std::string result_strategy = R"(
  2340. %isneg = OpSLessThan %bool %i %zero
  2341. %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
  2342. %result = OpLoad %f32 %varptr
  2343. )";
  2344. std::ostringstream spirv;
  2345. createVariablePointerSpirvProgram(&spirv, result_strategy,
  2346. true /* Add VariablePointers Capability? */,
  2347. false /* Use Helper Function? */);
  2348. CompileSuccessfully(spirv.str());
  2349. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2350. }
  2351. // Without the VariablePointers Capability, OpLoad will not allow loading
  2352. // through a variable pointer.
  2353. // Disabled since using OpSelect with pointers without VariablePointers will
  2354. // fail LogicalsPass.
  2355. TEST_F(ValidateIdWithMessage, DISABLED_OpLoadVarPtrOpSelectBad) {
  2356. std::string result_strategy = R"(
  2357. %isneg = OpSLessThan %bool %i %zero
  2358. %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
  2359. %result = OpLoad %f32 %varptr
  2360. )";
  2361. std::ostringstream spirv;
  2362. createVariablePointerSpirvProgram(&spirv, result_strategy,
  2363. false /* Add VariablePointers Capability?*/,
  2364. false /* Use Helper Function? */);
  2365. CompileSuccessfully(spirv.str());
  2366. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2367. EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a logical pointer."));
  2368. }
  2369. // With the VariablePointer Capability, OpLoad should allow loading a
  2370. // VaiablePointer. In this test the variable pointer is obtained by an OpPhi
  2371. TEST_F(ValidateIdWithMessage, OpLoadVarPtrOpPhiGood) {
  2372. std::string result_strategy = R"(
  2373. %is_neg = OpSLessThan %bool %i %zero
  2374. OpSelectionMerge %end_label None
  2375. OpBranchConditional %is_neg %take_ptr_1 %take_ptr_2
  2376. %take_ptr_1 = OpLabel
  2377. OpBranch %end_label
  2378. %take_ptr_2 = OpLabel
  2379. OpBranch %end_label
  2380. %end_label = OpLabel
  2381. %varptr = OpPhi %f32ptr %ptr1 %take_ptr_1 %ptr2 %take_ptr_2
  2382. %result = OpLoad %f32 %varptr
  2383. )";
  2384. std::ostringstream spirv;
  2385. createVariablePointerSpirvProgram(&spirv, result_strategy,
  2386. true /* Add VariablePointers Capability?*/,
  2387. false /* Use Helper Function? */);
  2388. CompileSuccessfully(spirv.str());
  2389. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2390. }
  2391. // Without the VariablePointers Capability, OpPhi can have a pointer result
  2392. // type.
  2393. TEST_F(ValidateIdWithMessage, OpPhiBad) {
  2394. std::string result_strategy = R"(
  2395. %is_neg = OpSLessThan %bool %i %zero
  2396. OpSelectionMerge %end_label None
  2397. OpBranchConditional %is_neg %take_ptr_1 %take_ptr_2
  2398. %take_ptr_1 = OpLabel
  2399. OpBranch %end_label
  2400. %take_ptr_2 = OpLabel
  2401. OpBranch %end_label
  2402. %end_label = OpLabel
  2403. %varptr = OpPhi %f32ptr %ptr1 %take_ptr_1 %ptr2 %take_ptr_2
  2404. %result = OpLoad %f32 %varptr
  2405. )";
  2406. std::ostringstream spirv;
  2407. createVariablePointerSpirvProgram(&spirv, result_strategy,
  2408. false /* Add VariablePointers Capability?*/,
  2409. false /* Use Helper Function? */);
  2410. CompileSuccessfully(spirv.str());
  2411. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2412. EXPECT_THAT(getDiagnosticString(),
  2413. HasSubstr("Using pointers with OpPhi requires capability "
  2414. "VariablePointers or VariablePointersStorageBuffer"));
  2415. }
  2416. // With the VariablePointer Capability, OpLoad should allow loading through a
  2417. // VaiablePointer. In this test the variable pointer is obtained from an
  2418. // OpFunctionCall (return value from a function)
  2419. TEST_F(ValidateIdWithMessage, OpLoadVarPtrOpFunctionCallGood) {
  2420. std::ostringstream spirv;
  2421. std::string result_strategy = R"(
  2422. %isneg = OpSLessThan %bool %i %zero
  2423. %varptr = OpFunctionCall %f32ptr %choose_input_func %isneg %ptr1 %ptr2
  2424. %result = OpLoad %f32 %varptr
  2425. )";
  2426. createVariablePointerSpirvProgram(&spirv, result_strategy,
  2427. true /* Add VariablePointers Capability?*/,
  2428. true /* Use Helper Function? */);
  2429. CompileSuccessfully(spirv.str());
  2430. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2431. }
  2432. TEST_F(ValidateIdWithMessage, OpLoadResultTypeBad) {
  2433. std::string spirv = kGLSL450MemoryModel + R"(
  2434. %1 = OpTypeVoid
  2435. %2 = OpTypeInt 32 0
  2436. %3 = OpTypePointer UniformConstant %2
  2437. %4 = OpTypeFunction %1
  2438. %5 = OpVariable %3 UniformConstant
  2439. %6 = OpFunction %1 None %4
  2440. %7 = OpLabel
  2441. %8 = OpLoad %3 %5
  2442. OpReturn
  2443. OpFunctionEnd
  2444. )";
  2445. CompileSuccessfully(spirv.c_str());
  2446. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2447. EXPECT_THAT(getDiagnosticString(),
  2448. HasSubstr("OpLoad Result Type <id> "
  2449. "'3[%_ptr_UniformConstant_uint]' does not match "
  2450. "Pointer <id> '5[%5]'s type."));
  2451. }
  2452. TEST_F(ValidateIdWithMessage, OpLoadPointerBad) {
  2453. std::string spirv = kGLSL450MemoryModel + R"(
  2454. %1 = OpTypeVoid
  2455. %2 = OpTypeInt 32 0
  2456. %3 = OpTypePointer UniformConstant %2
  2457. %4 = OpTypeFunction %1
  2458. %5 = OpFunction %1 None %4
  2459. %6 = OpLabel
  2460. %7 = OpLoad %2 %8
  2461. OpReturn
  2462. OpFunctionEnd
  2463. )";
  2464. CompileSuccessfully(spirv.c_str());
  2465. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2466. // Prove that SSA checks trigger for a bad Id value.
  2467. // The next test case show the not-a-logical-pointer case.
  2468. EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 8[%8] has not been "
  2469. "defined"));
  2470. }
  2471. // Disabled as bitcasting type to object is now not valid.
  2472. TEST_F(ValidateIdWithMessage, DISABLED_OpLoadLogicalPointerBad) {
  2473. std::string spirv = kGLSL450MemoryModel + R"(
  2474. %1 = OpTypeVoid
  2475. %2 = OpTypeInt 32 0
  2476. %3 = OpTypeFloat 32
  2477. %4 = OpTypePointer UniformConstant %2
  2478. %5 = OpTypePointer UniformConstant %3
  2479. %6 = OpTypeFunction %1
  2480. %7 = OpFunction %1 None %6
  2481. %8 = OpLabel
  2482. %9 = OpBitcast %5 %4 ; Not valid in logical addressing
  2483. %10 = OpLoad %3 %9 ; Should trigger message
  2484. OpReturn
  2485. OpFunctionEnd
  2486. )";
  2487. CompileSuccessfully(spirv.c_str());
  2488. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2489. // Once we start checking bitcasts, we might catch that
  2490. // as the error first, instead of catching it here.
  2491. // I don't know if it's possible to generate a bad case
  2492. // if/when the validator is complete.
  2493. EXPECT_THAT(getDiagnosticString(),
  2494. HasSubstr("OpLoad Pointer <id> '9' is not a logical pointer."));
  2495. }
  2496. TEST_F(ValidateIdWithMessage, OpStoreGood) {
  2497. std::string spirv = kGLSL450MemoryModel + R"(
  2498. %1 = OpTypeVoid
  2499. %2 = OpTypeInt 32 0
  2500. %3 = OpTypePointer Uniform %2
  2501. %4 = OpTypeFunction %1
  2502. %5 = OpConstant %2 42
  2503. %6 = OpVariable %3 Uniform
  2504. %7 = OpFunction %1 None %4
  2505. %8 = OpLabel
  2506. OpStore %6 %5
  2507. OpReturn
  2508. OpFunctionEnd)";
  2509. CompileSuccessfully(spirv.c_str());
  2510. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2511. }
  2512. TEST_F(ValidateIdWithMessage, OpStorePointerBad) {
  2513. std::string spirv = kGLSL450MemoryModel + R"(
  2514. %1 = OpTypeVoid
  2515. %2 = OpTypeInt 32 0
  2516. %3 = OpTypePointer UniformConstant %2
  2517. %4 = OpTypeFunction %1
  2518. %5 = OpConstant %2 42
  2519. %6 = OpVariable %3 UniformConstant
  2520. %7 = OpConstant %2 0
  2521. %8 = OpFunction %1 None %4
  2522. %9 = OpLabel
  2523. OpStore %7 %5
  2524. OpReturn
  2525. OpFunctionEnd)";
  2526. CompileSuccessfully(spirv.c_str());
  2527. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2528. EXPECT_THAT(getDiagnosticString(),
  2529. HasSubstr("OpStore Pointer <id> '7[%uint_0]' is not a logical "
  2530. "pointer."));
  2531. }
  2532. // Disabled as bitcasting type to object is now not valid.
  2533. TEST_F(ValidateIdWithMessage, DISABLED_OpStoreLogicalPointerBad) {
  2534. std::string spirv = kGLSL450MemoryModel + R"(
  2535. %1 = OpTypeVoid
  2536. %2 = OpTypeInt 32 0
  2537. %3 = OpTypeFloat 32
  2538. %4 = OpTypePointer UniformConstant %2
  2539. %5 = OpTypePointer UniformConstant %3
  2540. %6 = OpTypeFunction %1
  2541. %7 = OpConstantNull %5
  2542. %8 = OpFunction %1 None %6
  2543. %9 = OpLabel
  2544. %10 = OpBitcast %5 %4 ; Not valid in logical addressing
  2545. %11 = OpStore %10 %7 ; Should trigger message
  2546. OpReturn
  2547. OpFunctionEnd
  2548. )";
  2549. CompileSuccessfully(spirv.c_str());
  2550. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2551. EXPECT_THAT(getDiagnosticString(),
  2552. HasSubstr("OpStore Pointer <id> '10' is not a logical pointer."));
  2553. }
  2554. // Without the VariablePointer Capability, OpStore should may not store
  2555. // through a variable pointer.
  2556. // Disabled since using OpSelect with pointers without VariablePointers will
  2557. // fail LogicalsPass.
  2558. TEST_F(ValidateIdWithMessage, DISABLED_OpStoreVarPtrBad) {
  2559. std::string result_strategy = R"(
  2560. %isneg = OpSLessThan %bool %i %zero
  2561. %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
  2562. OpStore %varptr %float_1
  2563. )";
  2564. std::ostringstream spirv;
  2565. createVariablePointerSpirvProgram(
  2566. &spirv, result_strategy, false /* Add VariablePointers Capability? */,
  2567. false /* Use Helper Function? */);
  2568. CompileSuccessfully(spirv.str());
  2569. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2570. EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a logical pointer."));
  2571. }
  2572. // With the VariablePointer Capability, OpStore should allow storing through a
  2573. // variable pointer.
  2574. TEST_F(ValidateIdWithMessage, OpStoreVarPtrGood) {
  2575. std::string result_strategy = R"(
  2576. %isneg = OpSLessThan %bool %i %zero
  2577. %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
  2578. OpStore %varptr %float_1
  2579. )";
  2580. std::ostringstream spirv;
  2581. createVariablePointerSpirvProgram(&spirv, result_strategy,
  2582. true /* Add VariablePointers Capability? */,
  2583. false /* Use Helper Function? */);
  2584. CompileSuccessfully(spirv.str());
  2585. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2586. }
  2587. TEST_F(ValidateIdWithMessage, OpStoreObjectGood) {
  2588. std::string spirv = kGLSL450MemoryModel + R"(
  2589. %1 = OpTypeVoid
  2590. %2 = OpTypeInt 32 0
  2591. %3 = OpTypePointer Uniform %2
  2592. %4 = OpTypeFunction %1
  2593. %5 = OpConstant %2 42
  2594. %6 = OpVariable %3 Uniform
  2595. %7 = OpFunction %1 None %4
  2596. %8 = OpLabel
  2597. %9 = OpFunctionCall %1 %10
  2598. OpStore %6 %9
  2599. OpReturn
  2600. OpFunctionEnd
  2601. %10 = OpFunction %1 None %4
  2602. %11 = OpLabel
  2603. OpReturn
  2604. OpFunctionEnd)";
  2605. CompileSuccessfully(spirv.c_str());
  2606. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2607. EXPECT_THAT(getDiagnosticString(),
  2608. HasSubstr("OpStore Object <id> '9[%9]'s type is void."));
  2609. }
  2610. TEST_F(ValidateIdWithMessage, OpStoreTypeBad) {
  2611. std::string spirv = kGLSL450MemoryModel + R"(
  2612. %1 = OpTypeVoid
  2613. %2 = OpTypeInt 32 0
  2614. %9 = OpTypeFloat 32
  2615. %3 = OpTypePointer Uniform %2
  2616. %4 = OpTypeFunction %1
  2617. %5 = OpConstant %9 3.14
  2618. %6 = OpVariable %3 Uniform
  2619. %7 = OpFunction %1 None %4
  2620. %8 = OpLabel
  2621. OpStore %6 %5
  2622. OpReturn
  2623. OpFunctionEnd)";
  2624. CompileSuccessfully(spirv.c_str());
  2625. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2626. EXPECT_THAT(getDiagnosticString(),
  2627. HasSubstr("OpStore Pointer <id> '7[%7]'s type does not match "
  2628. "Object <id> '6[%float_3_1400001]'s type."));
  2629. }
  2630. // The next series of test check test a relaxation of the rules for stores to
  2631. // structs. The first test checks that we get a failure when the option is not
  2632. // set to relax the rule.
  2633. // TODO: Add tests for layout compatible arrays and matricies when the validator
  2634. // relaxes the rules for them as well. Also need test to check for layout
  2635. // decorations specific to those types.
  2636. TEST_F(ValidateIdWithMessage, OpStoreTypeBadStruct) {
  2637. std::string spirv = kGLSL450MemoryModel + R"(
  2638. OpMemberDecorate %1 0 Offset 0
  2639. OpMemberDecorate %1 1 Offset 4
  2640. OpMemberDecorate %2 0 Offset 0
  2641. OpMemberDecorate %2 1 Offset 4
  2642. %3 = OpTypeVoid
  2643. %4 = OpTypeFloat 32
  2644. %1 = OpTypeStruct %4 %4
  2645. %5 = OpTypePointer Uniform %1
  2646. %2 = OpTypeStruct %4 %4
  2647. %6 = OpTypeFunction %3
  2648. %7 = OpConstant %4 3.14
  2649. %8 = OpVariable %5 Uniform
  2650. %9 = OpFunction %3 None %6
  2651. %10 = OpLabel
  2652. %11 = OpCompositeConstruct %2 %7 %7
  2653. OpStore %8 %11
  2654. OpReturn
  2655. OpFunctionEnd)";
  2656. CompileSuccessfully(spirv.c_str());
  2657. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2658. EXPECT_THAT(getDiagnosticString(),
  2659. HasSubstr("OpStore Pointer <id> '8[%8]'s type does not match "
  2660. "Object <id> '11[%11]'s type."));
  2661. }
  2662. // Same code as the last test. The difference is that we relax the rule.
  2663. // Because the structs %3 and %5 are defined the same way.
  2664. TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedStruct) {
  2665. std::string spirv = kGLSL450MemoryModel + R"(
  2666. OpMemberDecorate %1 0 Offset 0
  2667. OpMemberDecorate %1 1 Offset 4
  2668. OpMemberDecorate %2 0 Offset 0
  2669. OpMemberDecorate %2 1 Offset 4
  2670. %3 = OpTypeVoid
  2671. %4 = OpTypeFloat 32
  2672. %1 = OpTypeStruct %4 %4
  2673. %5 = OpTypePointer Uniform %1
  2674. %2 = OpTypeStruct %4 %4
  2675. %6 = OpTypeFunction %3
  2676. %7 = OpConstant %4 3.14
  2677. %8 = OpVariable %5 Uniform
  2678. %9 = OpFunction %3 None %6
  2679. %10 = OpLabel
  2680. %11 = OpCompositeConstruct %2 %7 %7
  2681. OpStore %8 %11
  2682. OpReturn
  2683. OpFunctionEnd)";
  2684. spvValidatorOptionsSetRelaxStoreStruct(options_, true);
  2685. CompileSuccessfully(spirv.c_str());
  2686. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2687. }
  2688. // Same code as the last test excect for an extra decoration on one of the
  2689. // members. With the relaxed rules, the code is still valid.
  2690. TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedStructWithExtraDecoration) {
  2691. std::string spirv = kGLSL450MemoryModel + R"(
  2692. OpMemberDecorate %1 0 Offset 0
  2693. OpMemberDecorate %1 1 Offset 4
  2694. OpMemberDecorate %1 0 RelaxedPrecision
  2695. OpMemberDecorate %2 0 Offset 0
  2696. OpMemberDecorate %2 1 Offset 4
  2697. %3 = OpTypeVoid
  2698. %4 = OpTypeFloat 32
  2699. %1 = OpTypeStruct %4 %4
  2700. %5 = OpTypePointer Uniform %1
  2701. %2 = OpTypeStruct %4 %4
  2702. %6 = OpTypeFunction %3
  2703. %7 = OpConstant %4 3.14
  2704. %8 = OpVariable %5 Uniform
  2705. %9 = OpFunction %3 None %6
  2706. %10 = OpLabel
  2707. %11 = OpCompositeConstruct %2 %7 %7
  2708. OpStore %8 %11
  2709. OpReturn
  2710. OpFunctionEnd)";
  2711. spvValidatorOptionsSetRelaxStoreStruct(options_, true);
  2712. CompileSuccessfully(spirv.c_str());
  2713. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2714. }
  2715. // This test check that we recursively traverse the struct to check if they are
  2716. // interchangable.
  2717. TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedNestedStruct) {
  2718. std::string spirv = kGLSL450MemoryModel + R"(
  2719. OpMemberDecorate %1 0 Offset 0
  2720. OpMemberDecorate %1 1 Offset 4
  2721. OpMemberDecorate %2 0 Offset 0
  2722. OpMemberDecorate %2 1 Offset 8
  2723. OpMemberDecorate %3 0 Offset 0
  2724. OpMemberDecorate %3 1 Offset 4
  2725. OpMemberDecorate %4 0 Offset 0
  2726. OpMemberDecorate %4 1 Offset 8
  2727. %5 = OpTypeVoid
  2728. %6 = OpTypeInt 32 0
  2729. %7 = OpTypeFloat 32
  2730. %1 = OpTypeStruct %7 %6
  2731. %2 = OpTypeStruct %1 %1
  2732. %8 = OpTypePointer Uniform %2
  2733. %3 = OpTypeStruct %7 %6
  2734. %4 = OpTypeStruct %3 %3
  2735. %9 = OpTypeFunction %5
  2736. %10 = OpConstant %6 7
  2737. %11 = OpConstant %7 3.14
  2738. %12 = OpConstantComposite %3 %11 %10
  2739. %13 = OpVariable %8 Uniform
  2740. %14 = OpFunction %5 None %9
  2741. %15 = OpLabel
  2742. %16 = OpCompositeConstruct %4 %12 %12
  2743. OpStore %13 %16
  2744. OpReturn
  2745. OpFunctionEnd)";
  2746. spvValidatorOptionsSetRelaxStoreStruct(options_, true);
  2747. CompileSuccessfully(spirv.c_str());
  2748. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2749. }
  2750. // This test check that the even with the relaxed rules an error is identified
  2751. // if the members of the struct are in a different order.
  2752. TEST_F(ValidateIdWithMessage, OpStoreTypeBadRelaxedStruct1) {
  2753. std::string spirv = kGLSL450MemoryModel + R"(
  2754. OpMemberDecorate %1 0 Offset 0
  2755. OpMemberDecorate %1 1 Offset 4
  2756. OpMemberDecorate %2 0 Offset 0
  2757. OpMemberDecorate %2 1 Offset 8
  2758. OpMemberDecorate %3 0 Offset 0
  2759. OpMemberDecorate %3 1 Offset 4
  2760. OpMemberDecorate %4 0 Offset 0
  2761. OpMemberDecorate %4 1 Offset 8
  2762. %5 = OpTypeVoid
  2763. %6 = OpTypeInt 32 0
  2764. %7 = OpTypeFloat 32
  2765. %1 = OpTypeStruct %6 %7
  2766. %2 = OpTypeStruct %1 %1
  2767. %8 = OpTypePointer Uniform %2
  2768. %3 = OpTypeStruct %7 %6
  2769. %4 = OpTypeStruct %3 %3
  2770. %9 = OpTypeFunction %5
  2771. %10 = OpConstant %6 7
  2772. %11 = OpConstant %7 3.14
  2773. %12 = OpConstantComposite %3 %11 %10
  2774. %13 = OpVariable %8 Uniform
  2775. %14 = OpFunction %5 None %9
  2776. %15 = OpLabel
  2777. %16 = OpCompositeConstruct %4 %12 %12
  2778. OpStore %13 %16
  2779. OpReturn
  2780. OpFunctionEnd)";
  2781. spvValidatorOptionsSetRelaxStoreStruct(options_, true);
  2782. CompileSuccessfully(spirv.c_str());
  2783. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2784. EXPECT_THAT(
  2785. getDiagnosticString(),
  2786. HasSubstr("OpStore Pointer <id> '13[%13]'s layout does not match Object "
  2787. "<id> '16[%16]'s layout."));
  2788. }
  2789. // This test check that the even with the relaxed rules an error is identified
  2790. // if the members of the struct are at different offsets.
  2791. TEST_F(ValidateIdWithMessage, OpStoreTypeBadRelaxedStruct2) {
  2792. std::string spirv = kGLSL450MemoryModel + R"(
  2793. OpMemberDecorate %1 0 Offset 4
  2794. OpMemberDecorate %1 1 Offset 0
  2795. OpMemberDecorate %2 0 Offset 0
  2796. OpMemberDecorate %2 1 Offset 8
  2797. OpMemberDecorate %3 0 Offset 0
  2798. OpMemberDecorate %3 1 Offset 4
  2799. OpMemberDecorate %4 0 Offset 0
  2800. OpMemberDecorate %4 1 Offset 8
  2801. %5 = OpTypeVoid
  2802. %6 = OpTypeInt 32 0
  2803. %7 = OpTypeFloat 32
  2804. %1 = OpTypeStruct %7 %6
  2805. %2 = OpTypeStruct %1 %1
  2806. %8 = OpTypePointer Uniform %2
  2807. %3 = OpTypeStruct %7 %6
  2808. %4 = OpTypeStruct %3 %3
  2809. %9 = OpTypeFunction %5
  2810. %10 = OpConstant %6 7
  2811. %11 = OpConstant %7 3.14
  2812. %12 = OpConstantComposite %3 %11 %10
  2813. %13 = OpVariable %8 Uniform
  2814. %14 = OpFunction %5 None %9
  2815. %15 = OpLabel
  2816. %16 = OpCompositeConstruct %4 %12 %12
  2817. OpStore %13 %16
  2818. OpReturn
  2819. OpFunctionEnd)";
  2820. spvValidatorOptionsSetRelaxStoreStruct(options_, true);
  2821. CompileSuccessfully(spirv.c_str());
  2822. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2823. EXPECT_THAT(
  2824. getDiagnosticString(),
  2825. HasSubstr("OpStore Pointer <id> '13[%13]'s layout does not match Object "
  2826. "<id> '16[%16]'s layout."));
  2827. }
  2828. TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerReturnPointer) {
  2829. const std::string spirv = R"(
  2830. OpCapability Shader
  2831. OpCapability Linkage
  2832. OpMemoryModel Logical GLSL450
  2833. %1 = OpTypeInt 32 1
  2834. %2 = OpTypePointer Function %1
  2835. %3 = OpTypeFunction %2 %2
  2836. %4 = OpFunction %2 None %3
  2837. %5 = OpFunctionParameter %2
  2838. %6 = OpLabel
  2839. OpReturnValue %5
  2840. OpFunctionEnd)";
  2841. spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
  2842. CompileSuccessfully(spirv.c_str());
  2843. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2844. }
  2845. TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerAllocPointer) {
  2846. const std::string spirv = R"(
  2847. OpCapability Shader
  2848. OpCapability Linkage
  2849. OpMemoryModel Logical GLSL450
  2850. %1 = OpTypeVoid
  2851. %2 = OpTypeInt 32 1
  2852. %3 = OpTypeFunction %1 ; void(void)
  2853. %4 = OpTypePointer Uniform %2 ; int*
  2854. %5 = OpTypePointer Private %4 ; int** (Private)
  2855. %6 = OpTypePointer Function %4 ; int** (Function)
  2856. %7 = OpVariable %5 Private
  2857. %8 = OpFunction %1 None %3
  2858. %9 = OpLabel
  2859. %10 = OpVariable %6 Function
  2860. OpReturn
  2861. OpFunctionEnd)";
  2862. spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
  2863. CompileSuccessfully(spirv.c_str());
  2864. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2865. }
  2866. TEST_F(ValidateIdWithMessage, OpStoreVoid) {
  2867. std::string spirv = kGLSL450MemoryModel + R"(
  2868. %1 = OpTypeVoid
  2869. %2 = OpTypeInt 32 0
  2870. %3 = OpTypePointer Uniform %2
  2871. %4 = OpTypeFunction %1
  2872. %6 = OpVariable %3 Uniform
  2873. %7 = OpFunction %1 None %4
  2874. %8 = OpLabel
  2875. %9 = OpFunctionCall %1 %7
  2876. OpStore %6 %9
  2877. OpReturn
  2878. OpFunctionEnd)";
  2879. CompileSuccessfully(spirv.c_str());
  2880. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2881. EXPECT_THAT(getDiagnosticString(),
  2882. HasSubstr("OpStore Object <id> '8[%8]'s type is void."));
  2883. }
  2884. TEST_F(ValidateIdWithMessage, OpStoreLabel) {
  2885. std::string spirv = kGLSL450MemoryModel + R"(
  2886. %1 = OpTypeVoid
  2887. %2 = OpTypeInt 32 0
  2888. %3 = OpTypePointer Uniform %2
  2889. %4 = OpTypeFunction %1
  2890. %6 = OpVariable %3 Uniform
  2891. %7 = OpFunction %1 None %4
  2892. %8 = OpLabel
  2893. OpStore %6 %8
  2894. OpReturn
  2895. OpFunctionEnd)";
  2896. CompileSuccessfully(spirv.c_str());
  2897. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2898. EXPECT_THAT(getDiagnosticString(),
  2899. HasSubstr("Operand 7[%7] requires a type"));
  2900. }
  2901. // TODO: enable when this bug is fixed:
  2902. // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
  2903. TEST_F(ValidateIdWithMessage, DISABLED_OpStoreFunction) {
  2904. std::string spirv = kGLSL450MemoryModel + R"(
  2905. %2 = OpTypeInt 32 0
  2906. %3 = OpTypePointer UniformConstant %2
  2907. %4 = OpTypeFunction %2
  2908. %5 = OpConstant %2 123
  2909. %6 = OpVariable %3 UniformConstant
  2910. %7 = OpFunction %2 None %4
  2911. %8 = OpLabel
  2912. OpStore %6 %7
  2913. OpReturnValue %5
  2914. OpFunctionEnd)";
  2915. CompileSuccessfully(spirv.c_str());
  2916. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2917. }
  2918. TEST_F(ValidateIdWithMessage, OpStoreBuiltin) {
  2919. std::string spirv = R"(
  2920. OpCapability Shader
  2921. %1 = OpExtInstImport "GLSL.std.450"
  2922. OpMemoryModel Logical GLSL450
  2923. OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
  2924. OpExecutionMode %main LocalSize 1 1 1
  2925. OpSource GLSL 450
  2926. OpName %main "main"
  2927. OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
  2928. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  2929. %int = OpTypeInt 32 1
  2930. %uint = OpTypeInt 32 0
  2931. %v3uint = OpTypeVector %uint 3
  2932. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  2933. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  2934. %zero = OpConstant %uint 0
  2935. %v3uint_000 = OpConstantComposite %v3uint %zero %zero %zero
  2936. %void = OpTypeVoid
  2937. %voidfunc = OpTypeFunction %void
  2938. %main = OpFunction %void None %voidfunc
  2939. %lmain = OpLabel
  2940. OpStore %gl_GlobalInvocationID %v3uint_000
  2941. OpReturn
  2942. OpFunctionEnd
  2943. )";
  2944. CompileSuccessfully(spirv.c_str());
  2945. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2946. EXPECT_THAT(getDiagnosticString(), HasSubstr("storage class is read-only"));
  2947. }
  2948. TEST_F(ValidateIdWithMessage, OpCopyMemoryGood) {
  2949. std::string spirv = kGLSL450MemoryModel + R"(
  2950. %1 = OpTypeVoid
  2951. %2 = OpTypeInt 32 0
  2952. %3 = OpTypePointer UniformConstant %2
  2953. %4 = OpConstant %2 42
  2954. %5 = OpVariable %3 UniformConstant %4
  2955. %6 = OpTypePointer Function %2
  2956. %7 = OpTypeFunction %1
  2957. %8 = OpFunction %1 None %7
  2958. %9 = OpLabel
  2959. %10 = OpVariable %6 Function
  2960. OpCopyMemory %10 %5 None
  2961. OpReturn
  2962. OpFunctionEnd
  2963. )";
  2964. CompileSuccessfully(spirv.c_str());
  2965. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2966. }
  2967. TEST_F(ValidateIdWithMessage, OpCopyMemoryNonPointerTarget) {
  2968. const std::string spirv = kGLSL450MemoryModel + R"(
  2969. %1 = OpTypeVoid
  2970. %2 = OpTypeInt 32 0
  2971. %3 = OpTypePointer Uniform %2
  2972. %4 = OpTypeFunction %1 %2 %3
  2973. %5 = OpFunction %1 None %4
  2974. %6 = OpFunctionParameter %2
  2975. %7 = OpFunctionParameter %3
  2976. %8 = OpLabel
  2977. OpCopyMemory %6 %7
  2978. OpReturn
  2979. OpFunctionEnd
  2980. )";
  2981. CompileSuccessfully(spirv);
  2982. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2983. EXPECT_THAT(getDiagnosticString(),
  2984. HasSubstr("Target operand <id> '6[%6]' is not a pointer."));
  2985. }
  2986. TEST_F(ValidateIdWithMessage, OpCopyMemoryNonPointerSource) {
  2987. const std::string spirv = kGLSL450MemoryModel + R"(
  2988. %1 = OpTypeVoid
  2989. %2 = OpTypeInt 32 0
  2990. %3 = OpTypePointer Uniform %2
  2991. %4 = OpTypeFunction %1 %2 %3
  2992. %5 = OpFunction %1 None %4
  2993. %6 = OpFunctionParameter %2
  2994. %7 = OpFunctionParameter %3
  2995. %8 = OpLabel
  2996. OpCopyMemory %7 %6
  2997. OpReturn
  2998. OpFunctionEnd
  2999. )";
  3000. CompileSuccessfully(spirv);
  3001. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3002. EXPECT_THAT(getDiagnosticString(),
  3003. HasSubstr("Source operand <id> '6[%6]' is not a pointer."));
  3004. }
  3005. TEST_F(ValidateIdWithMessage, OpCopyMemoryBad) {
  3006. std::string spirv = kGLSL450MemoryModel + R"(
  3007. %1 = OpTypeVoid
  3008. %2 = OpTypeInt 32 0
  3009. %3 = OpTypePointer UniformConstant %2
  3010. %4 = OpConstant %2 42
  3011. %5 = OpVariable %3 UniformConstant %4
  3012. %11 = OpTypeFloat 32
  3013. %6 = OpTypePointer Function %11
  3014. %7 = OpTypeFunction %1
  3015. %8 = OpFunction %1 None %7
  3016. %9 = OpLabel
  3017. %10 = OpVariable %6 Function
  3018. OpCopyMemory %10 %5 None
  3019. OpReturn
  3020. OpFunctionEnd
  3021. )";
  3022. CompileSuccessfully(spirv.c_str());
  3023. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3024. EXPECT_THAT(getDiagnosticString(),
  3025. HasSubstr("Target <id> '5[%5]'s type does not match "
  3026. "Source <id> '2[%uint]'s type."));
  3027. }
  3028. TEST_F(ValidateIdWithMessage, OpCopyMemoryVoidTarget) {
  3029. const std::string spirv = kGLSL450MemoryModel + R"(
  3030. %1 = OpTypeVoid
  3031. %2 = OpTypeInt 32 0
  3032. %3 = OpTypePointer Uniform %1
  3033. %4 = OpTypePointer Uniform %2
  3034. %5 = OpTypeFunction %1 %3 %4
  3035. %6 = OpFunction %1 None %5
  3036. %7 = OpFunctionParameter %3
  3037. %8 = OpFunctionParameter %4
  3038. %9 = OpLabel
  3039. OpCopyMemory %7 %8
  3040. OpReturn
  3041. OpFunctionEnd
  3042. )";
  3043. CompileSuccessfully(spirv);
  3044. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3045. EXPECT_THAT(getDiagnosticString(),
  3046. HasSubstr("Target operand <id> '7[%7]' cannot be a void "
  3047. "pointer."));
  3048. }
  3049. TEST_F(ValidateIdWithMessage, OpCopyMemoryVoidSource) {
  3050. const std::string spirv = kGLSL450MemoryModel + R"(
  3051. %1 = OpTypeVoid
  3052. %2 = OpTypeInt 32 0
  3053. %3 = OpTypePointer Uniform %1
  3054. %4 = OpTypePointer Uniform %2
  3055. %5 = OpTypeFunction %1 %3 %4
  3056. %6 = OpFunction %1 None %5
  3057. %7 = OpFunctionParameter %3
  3058. %8 = OpFunctionParameter %4
  3059. %9 = OpLabel
  3060. OpCopyMemory %8 %7
  3061. OpReturn
  3062. OpFunctionEnd
  3063. )";
  3064. CompileSuccessfully(spirv);
  3065. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3066. EXPECT_THAT(getDiagnosticString(),
  3067. HasSubstr("Source operand <id> '7[%7]' cannot be a void "
  3068. "pointer."));
  3069. }
  3070. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedGood) {
  3071. std::string spirv = kGLSL450MemoryModel + R"(
  3072. %1 = OpTypeVoid
  3073. %2 = OpTypeInt 32 0
  3074. %3 = OpTypePointer UniformConstant %2
  3075. %4 = OpTypePointer Function %2
  3076. %5 = OpConstant %2 4
  3077. %6 = OpVariable %3 UniformConstant %5
  3078. %7 = OpTypeFunction %1
  3079. %8 = OpFunction %1 None %7
  3080. %9 = OpLabel
  3081. %10 = OpVariable %4 Function
  3082. OpCopyMemorySized %10 %6 %5 None
  3083. OpReturn
  3084. OpFunctionEnd)";
  3085. CompileSuccessfully(spirv.c_str());
  3086. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3087. }
  3088. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedTargetBad) {
  3089. std::string spirv = kGLSL450MemoryModel + R"(
  3090. %1 = OpTypeVoid
  3091. %2 = OpTypeInt 32 0
  3092. %3 = OpTypePointer UniformConstant %2
  3093. %4 = OpTypePointer Function %2
  3094. %5 = OpConstant %2 4
  3095. %6 = OpVariable %3 UniformConstant %5
  3096. %7 = OpTypeFunction %1
  3097. %8 = OpFunction %1 None %7
  3098. %9 = OpLabel
  3099. OpCopyMemorySized %5 %5 %5 None
  3100. OpReturn
  3101. OpFunctionEnd)";
  3102. CompileSuccessfully(spirv.c_str());
  3103. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3104. EXPECT_THAT(getDiagnosticString(),
  3105. HasSubstr("Target operand <id> '5[%uint_4]' is not a pointer."));
  3106. }
  3107. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSourceBad) {
  3108. std::string spirv = kGLSL450MemoryModel + R"(
  3109. %1 = OpTypeVoid
  3110. %2 = OpTypeInt 32 0
  3111. %3 = OpTypePointer UniformConstant %2
  3112. %4 = OpTypePointer Function %2
  3113. %5 = OpConstant %2 4
  3114. %6 = OpTypeFunction %1
  3115. %7 = OpFunction %1 None %6
  3116. %8 = OpLabel
  3117. %9 = OpVariable %4 Function
  3118. OpCopyMemorySized %9 %5 %5 None
  3119. OpReturn
  3120. OpFunctionEnd)";
  3121. CompileSuccessfully(spirv.c_str());
  3122. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3123. EXPECT_THAT(getDiagnosticString(),
  3124. HasSubstr("Source operand <id> '5[%uint_4]' is not a pointer."));
  3125. }
  3126. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeBad) {
  3127. std::string spirv = kGLSL450MemoryModel + R"(
  3128. %1 = OpTypeVoid
  3129. %2 = OpTypeInt 32 0
  3130. %3 = OpTypePointer UniformConstant %2
  3131. %4 = OpTypePointer Function %2
  3132. %5 = OpConstant %2 4
  3133. %6 = OpVariable %3 UniformConstant %5
  3134. %7 = OpTypeFunction %1
  3135. %8 = OpFunction %1 None %7
  3136. %9 = OpLabel
  3137. %10 = OpVariable %4 Function
  3138. OpCopyMemorySized %10 %6 %6 None
  3139. OpReturn
  3140. OpFunctionEnd)";
  3141. CompileSuccessfully(spirv.c_str());
  3142. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3143. EXPECT_THAT(
  3144. getDiagnosticString(),
  3145. HasSubstr("Size operand <id> '6[%6]' must be a scalar integer type."));
  3146. }
  3147. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeTypeBad) {
  3148. std::string spirv = kGLSL450MemoryModel + R"(
  3149. %1 = OpTypeVoid
  3150. %2 = OpTypeInt 32 0
  3151. %3 = OpTypePointer UniformConstant %2
  3152. %4 = OpTypePointer Function %2
  3153. %5 = OpConstant %2 4
  3154. %6 = OpVariable %3 UniformConstant %5
  3155. %7 = OpTypeFunction %1
  3156. %11 = OpTypeFloat 32
  3157. %12 = OpConstant %11 1.0
  3158. %8 = OpFunction %1 None %7
  3159. %9 = OpLabel
  3160. %10 = OpVariable %4 Function
  3161. OpCopyMemorySized %10 %6 %12 None
  3162. OpReturn
  3163. OpFunctionEnd)";
  3164. CompileSuccessfully(spirv.c_str());
  3165. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3166. EXPECT_THAT(
  3167. getDiagnosticString(),
  3168. HasSubstr("Size operand <id> '9[%float_1]' must be a scalar integer "
  3169. "type."));
  3170. }
  3171. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNull) {
  3172. const std::string spirv = kGLSL450MemoryModel + R"(
  3173. %1 = OpTypeVoid
  3174. %2 = OpTypeInt 32 0
  3175. %3 = OpConstantNull %2
  3176. %4 = OpTypePointer Uniform %2
  3177. %5 = OpTypeFloat 32
  3178. %6 = OpTypePointer UniformConstant %5
  3179. %7 = OpTypeFunction %1 %4 %6
  3180. %8 = OpFunction %1 None %7
  3181. %9 = OpFunctionParameter %4
  3182. %10 = OpFunctionParameter %6
  3183. %11 = OpLabel
  3184. OpCopyMemorySized %9 %10 %3
  3185. OpReturn
  3186. OpFunctionEnd
  3187. )";
  3188. CompileSuccessfully(spirv);
  3189. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3190. EXPECT_THAT(getDiagnosticString(),
  3191. HasSubstr("Size operand <id> '3[%3]' cannot be a constant "
  3192. "zero."));
  3193. }
  3194. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantZero) {
  3195. const std::string spirv = kGLSL450MemoryModel + R"(
  3196. %1 = OpTypeVoid
  3197. %2 = OpTypeInt 32 0
  3198. %3 = OpConstant %2 0
  3199. %4 = OpTypePointer Uniform %2
  3200. %5 = OpTypeFloat 32
  3201. %6 = OpTypePointer UniformConstant %5
  3202. %7 = OpTypeFunction %1 %4 %6
  3203. %8 = OpFunction %1 None %7
  3204. %9 = OpFunctionParameter %4
  3205. %10 = OpFunctionParameter %6
  3206. %11 = OpLabel
  3207. OpCopyMemorySized %9 %10 %3
  3208. OpReturn
  3209. OpFunctionEnd
  3210. )";
  3211. CompileSuccessfully(spirv);
  3212. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3213. EXPECT_THAT(getDiagnosticString(),
  3214. HasSubstr("Size operand <id> '3[%uint_0]' cannot be a constant "
  3215. "zero."));
  3216. }
  3217. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantZero64) {
  3218. const std::string spirv = kGLSL450MemoryModel + R"(
  3219. %1 = OpTypeVoid
  3220. %2 = OpTypeInt 64 0
  3221. %3 = OpConstant %2 0
  3222. %4 = OpTypePointer Uniform %2
  3223. %5 = OpTypeFloat 32
  3224. %6 = OpTypePointer UniformConstant %5
  3225. %7 = OpTypeFunction %1 %4 %6
  3226. %8 = OpFunction %1 None %7
  3227. %9 = OpFunctionParameter %4
  3228. %10 = OpFunctionParameter %6
  3229. %11 = OpLabel
  3230. OpCopyMemorySized %9 %10 %3
  3231. OpReturn
  3232. OpFunctionEnd
  3233. )";
  3234. CompileSuccessfully(spirv);
  3235. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3236. EXPECT_THAT(getDiagnosticString(),
  3237. HasSubstr("Size operand <id> '3[%ulong_0]' cannot be a constant "
  3238. "zero."));
  3239. }
  3240. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNegative) {
  3241. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  3242. %1 = OpTypeVoid
  3243. %2 = OpTypeInt 32 1
  3244. %3 = OpConstant %2 -1
  3245. %4 = OpTypePointer Uniform %2
  3246. %5 = OpTypeFloat 32
  3247. %6 = OpTypePointer UniformConstant %5
  3248. %7 = OpTypeFunction %1 %4 %6
  3249. %8 = OpFunction %1 None %7
  3250. %9 = OpFunctionParameter %4
  3251. %10 = OpFunctionParameter %6
  3252. %11 = OpLabel
  3253. OpCopyMemorySized %9 %10 %3
  3254. OpReturn
  3255. OpFunctionEnd
  3256. )";
  3257. CompileSuccessfully(spirv);
  3258. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3259. EXPECT_THAT(
  3260. getDiagnosticString(),
  3261. HasSubstr("Size operand <id> '3[%int_n1]' cannot have the sign bit set "
  3262. "to 1."));
  3263. }
  3264. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNegative64) {
  3265. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  3266. %1 = OpTypeVoid
  3267. %2 = OpTypeInt 64 1
  3268. %3 = OpConstant %2 -1
  3269. %4 = OpTypePointer Uniform %2
  3270. %5 = OpTypeFloat 32
  3271. %6 = OpTypePointer UniformConstant %5
  3272. %7 = OpTypeFunction %1 %4 %6
  3273. %8 = OpFunction %1 None %7
  3274. %9 = OpFunctionParameter %4
  3275. %10 = OpFunctionParameter %6
  3276. %11 = OpLabel
  3277. OpCopyMemorySized %9 %10 %3
  3278. OpReturn
  3279. OpFunctionEnd
  3280. )";
  3281. CompileSuccessfully(spirv);
  3282. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3283. EXPECT_THAT(
  3284. getDiagnosticString(),
  3285. HasSubstr("Size operand <id> '3[%long_n1]' cannot have the sign bit set "
  3286. "to 1."));
  3287. }
  3288. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeUnsignedNegative) {
  3289. const std::string spirv = kGLSL450MemoryModel + R"(
  3290. %1 = OpTypeVoid
  3291. %2 = OpTypeInt 32 0
  3292. %3 = OpConstant %2 2147483648
  3293. %4 = OpTypePointer Uniform %2
  3294. %5 = OpTypeFloat 32
  3295. %6 = OpTypePointer UniformConstant %5
  3296. %7 = OpTypeFunction %1 %4 %6
  3297. %8 = OpFunction %1 None %7
  3298. %9 = OpFunctionParameter %4
  3299. %10 = OpFunctionParameter %6
  3300. %11 = OpLabel
  3301. OpCopyMemorySized %9 %10 %3
  3302. OpReturn
  3303. OpFunctionEnd
  3304. )";
  3305. CompileSuccessfully(spirv);
  3306. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3307. }
  3308. TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeUnsignedNegative64) {
  3309. const std::string spirv = kGLSL450MemoryModel + R"(
  3310. %1 = OpTypeVoid
  3311. %2 = OpTypeInt 64 0
  3312. %3 = OpConstant %2 9223372036854775808
  3313. %4 = OpTypePointer Uniform %2
  3314. %5 = OpTypeFloat 32
  3315. %6 = OpTypePointer UniformConstant %5
  3316. %7 = OpTypeFunction %1 %4 %6
  3317. %8 = OpFunction %1 None %7
  3318. %9 = OpFunctionParameter %4
  3319. %10 = OpFunctionParameter %6
  3320. %11 = OpLabel
  3321. OpCopyMemorySized %9 %10 %3
  3322. OpReturn
  3323. OpFunctionEnd
  3324. )";
  3325. CompileSuccessfully(spirv);
  3326. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3327. }
  3328. const char kDeeplyNestedStructureSetup[] = R"(
  3329. %void = OpTypeVoid
  3330. %void_f = OpTypeFunction %void
  3331. %int = OpTypeInt 32 0
  3332. %float = OpTypeFloat 32
  3333. %v3float = OpTypeVector %float 3
  3334. %mat4x3 = OpTypeMatrix %v3float 4
  3335. %_ptr_Private_mat4x3 = OpTypePointer Private %mat4x3
  3336. %_ptr_Private_float = OpTypePointer Private %float
  3337. %my_matrix = OpVariable %_ptr_Private_mat4x3 Private
  3338. %my_float_var = OpVariable %_ptr_Private_float Private
  3339. %_ptr_Function_float = OpTypePointer Function %float
  3340. %int_0 = OpConstant %int 0
  3341. %int_1 = OpConstant %int 1
  3342. %int_2 = OpConstant %int 2
  3343. %int_3 = OpConstant %int 3
  3344. %int_5 = OpConstant %int 5
  3345. ; Making the following nested structures.
  3346. ;
  3347. ; struct S {
  3348. ; bool b;
  3349. ; vec4 v[5];
  3350. ; int i;
  3351. ; mat4x3 m[5];
  3352. ; }
  3353. ; uniform blockName {
  3354. ; S s;
  3355. ; bool cond;
  3356. ; RunTimeArray arr;
  3357. ; }
  3358. %f32arr = OpTypeRuntimeArray %float
  3359. %v4float = OpTypeVector %float 4
  3360. %array5_mat4x3 = OpTypeArray %mat4x3 %int_5
  3361. %array5_vec4 = OpTypeArray %v4float %int_5
  3362. %_ptr_Uniform_float = OpTypePointer Uniform %float
  3363. %_ptr_Function_vec4 = OpTypePointer Function %v4float
  3364. %_ptr_Uniform_vec4 = OpTypePointer Uniform %v4float
  3365. %struct_s = OpTypeStruct %int %array5_vec4 %int %array5_mat4x3
  3366. %struct_blockName = OpTypeStruct %struct_s %int %f32arr
  3367. %_ptr_Uniform_blockName = OpTypePointer Uniform %struct_blockName
  3368. %_ptr_Uniform_struct_s = OpTypePointer Uniform %struct_s
  3369. %_ptr_Uniform_array5_mat4x3 = OpTypePointer Uniform %array5_mat4x3
  3370. %_ptr_Uniform_mat4x3 = OpTypePointer Uniform %mat4x3
  3371. %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
  3372. %blockName_var = OpVariable %_ptr_Uniform_blockName Uniform
  3373. %spec_int = OpSpecConstant %int 2
  3374. %float_0 = OpConstant %float 0
  3375. %func = OpFunction %void None %void_f
  3376. %my_label = OpLabel
  3377. )";
  3378. // In what follows, Access Chain Instruction refers to one of the following:
  3379. // OpAccessChain, OpInBoundsAccessChain, OpPtrAccessChain, and
  3380. // OpInBoundsPtrAccessChain
  3381. using AccessChainInstructionTest = spvtest::ValidateBase<std::string>;
  3382. // Determines whether the access chain instruction requires the 'element id'
  3383. // argument.
  3384. bool AccessChainRequiresElemId(const std::string& instr) {
  3385. return (instr == "OpPtrAccessChain" || instr == "OpInBoundsPtrAccessChain");
  3386. }
  3387. // Valid: Access a float in a matrix using an access chain instruction.
  3388. TEST_P(AccessChainInstructionTest, AccessChainGood) {
  3389. const std::string instr = GetParam();
  3390. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3391. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup +
  3392. "%float_entry = " + instr +
  3393. R"( %_ptr_Private_float %my_matrix )" + elem +
  3394. R"(%int_0 %int_1
  3395. OpReturn
  3396. OpFunctionEnd
  3397. )";
  3398. CompileSuccessfully(spirv);
  3399. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3400. }
  3401. // Invalid. The result type of an access chain instruction must be a pointer.
  3402. TEST_P(AccessChainInstructionTest, AccessChainResultTypeBad) {
  3403. const std::string instr = GetParam();
  3404. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3405. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3406. %float_entry = )" +
  3407. instr +
  3408. R"( %float %my_matrix )" + elem +
  3409. R"(%int_0 %int_1
  3410. OpReturn
  3411. OpFunctionEnd
  3412. )";
  3413. const std::string expected_err = "The Result Type of " + instr +
  3414. " <id> '36[%36]' must be "
  3415. "OpTypePointer. Found OpTypeFloat.";
  3416. CompileSuccessfully(spirv);
  3417. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3418. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3419. }
  3420. // Invalid. The base type of an access chain instruction must be a pointer.
  3421. TEST_P(AccessChainInstructionTest, AccessChainBaseTypeVoidBad) {
  3422. const std::string instr = GetParam();
  3423. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3424. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3425. %float_entry = )" +
  3426. instr + " %_ptr_Private_float %void " + elem +
  3427. R"(%int_0 %int_1
  3428. OpReturn
  3429. OpFunctionEnd
  3430. )";
  3431. CompileSuccessfully(spirv);
  3432. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3433. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 1[%void] cannot be a "
  3434. "type"));
  3435. }
  3436. // Invalid. The base type of an access chain instruction must be a pointer.
  3437. TEST_P(AccessChainInstructionTest, AccessChainBaseTypeNonPtrVariableBad) {
  3438. const std::string instr = GetParam();
  3439. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3440. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3441. %entry = )" +
  3442. instr + R"( %_ptr_Private_float %_ptr_Private_float )" +
  3443. elem +
  3444. R"(%int_0 %int_1
  3445. OpReturn
  3446. OpFunctionEnd
  3447. )";
  3448. CompileSuccessfully(spirv);
  3449. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3450. EXPECT_THAT(getDiagnosticString(),
  3451. HasSubstr("Operand 8[%_ptr_Private_float] cannot be a type"));
  3452. }
  3453. // Invalid: The storage class of Base and Result do not match.
  3454. TEST_P(AccessChainInstructionTest,
  3455. AccessChainResultAndBaseStorageClassDoesntMatchBad) {
  3456. const std::string instr = GetParam();
  3457. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3458. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3459. %entry = )" +
  3460. instr + R"( %_ptr_Function_float %my_matrix )" + elem +
  3461. R"(%int_0 %int_1
  3462. OpReturn
  3463. OpFunctionEnd
  3464. )";
  3465. const std::string expected_err =
  3466. "The result pointer storage class and base pointer storage class in " +
  3467. instr + " do not match.";
  3468. CompileSuccessfully(spirv);
  3469. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3470. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3471. }
  3472. // Invalid. The base type of an access chain instruction must point to a
  3473. // composite object.
  3474. TEST_P(AccessChainInstructionTest,
  3475. AccessChainBasePtrNotPointingToCompositeBad) {
  3476. const std::string instr = GetParam();
  3477. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3478. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3479. %entry = )" +
  3480. instr + R"( %_ptr_Private_float %my_float_var )" + elem +
  3481. R"(%int_0
  3482. OpReturn
  3483. OpFunctionEnd
  3484. )";
  3485. const std::string expected_err = instr +
  3486. " reached non-composite type while "
  3487. "indexes still remain to be traversed.";
  3488. CompileSuccessfully(spirv);
  3489. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3490. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3491. }
  3492. // Valid. No Indexes were passed to the access chain instruction. The Result
  3493. // Type is the same as the Base type.
  3494. TEST_P(AccessChainInstructionTest, AccessChainNoIndexesGood) {
  3495. const std::string instr = GetParam();
  3496. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3497. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3498. %entry = )" +
  3499. instr + R"( %_ptr_Private_float %my_float_var )" + elem +
  3500. R"(
  3501. OpReturn
  3502. OpFunctionEnd
  3503. )";
  3504. CompileSuccessfully(spirv);
  3505. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3506. }
  3507. // Invalid. No Indexes were passed to the access chain instruction, but the
  3508. // Result Type is different from the Base type.
  3509. TEST_P(AccessChainInstructionTest, AccessChainNoIndexesBad) {
  3510. const std::string instr = GetParam();
  3511. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3512. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3513. %entry = )" +
  3514. instr + R"( %_ptr_Private_mat4x3 %my_float_var )" + elem +
  3515. R"(
  3516. OpReturn
  3517. OpFunctionEnd
  3518. )";
  3519. CompileSuccessfully(spirv);
  3520. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3521. EXPECT_THAT(
  3522. getDiagnosticString(),
  3523. HasSubstr("result type (OpTypeMatrix) does not match the type that "
  3524. "results from indexing into the base <id> (OpTypeFloat)."));
  3525. }
  3526. // Valid: 255 indexes passed to the access chain instruction. Limit is 255.
  3527. TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesGood) {
  3528. const std::string instr = GetParam();
  3529. const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
  3530. int depth = 255;
  3531. std::string header = kGLSL450MemoryModel + kDeeplyNestedStructureSetup;
  3532. header.erase(header.find("%func"));
  3533. std::ostringstream spirv;
  3534. spirv << header << "\n";
  3535. // Build nested structures. Struct 'i' contains struct 'i-1'
  3536. spirv << "%s_depth_1 = OpTypeStruct %float\n";
  3537. for (int i = 2; i <= depth; ++i) {
  3538. spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n";
  3539. }
  3540. // Define Pointer and Variable to use for the AccessChain instruction.
  3541. spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_"
  3542. << depth << "\n";
  3543. spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n";
  3544. // Function Start
  3545. spirv << R"(
  3546. %func = OpFunction %void None %void_f
  3547. %my_label = OpLabel
  3548. )";
  3549. // AccessChain with 'n' indexes (n = depth)
  3550. spirv << "%entry = " << instr << " %_ptr_Uniform_float %deep_var" << elem;
  3551. for (int i = 0; i < depth; ++i) {
  3552. spirv << " %int_0";
  3553. }
  3554. // Function end
  3555. spirv << R"(
  3556. OpReturn
  3557. OpFunctionEnd
  3558. )";
  3559. CompileSuccessfully(spirv.str());
  3560. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3561. }
  3562. // Invalid: 256 indexes passed to the access chain instruction. Limit is 255.
  3563. TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesBad) {
  3564. const std::string instr = GetParam();
  3565. const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
  3566. std::ostringstream spirv;
  3567. spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup;
  3568. spirv << "%entry = " << instr << " %_ptr_Private_float %my_matrix" << elem;
  3569. for (int i = 0; i < 256; ++i) {
  3570. spirv << " %int_0";
  3571. }
  3572. spirv << R"(
  3573. OpReturn
  3574. OpFunctionEnd
  3575. )";
  3576. const std::string expected_err = "The number of indexes in " + instr +
  3577. " may not exceed 255. Found 256 indexes.";
  3578. CompileSuccessfully(spirv.str());
  3579. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3580. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3581. }
  3582. // Valid: 10 indexes passed to the access chain instruction. (Custom limit: 10)
  3583. TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesGood) {
  3584. const std::string instr = GetParam();
  3585. const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
  3586. int depth = 10;
  3587. std::string header = kGLSL450MemoryModel + kDeeplyNestedStructureSetup;
  3588. header.erase(header.find("%func"));
  3589. std::ostringstream spirv;
  3590. spirv << header << "\n";
  3591. // Build nested structures. Struct 'i' contains struct 'i-1'
  3592. spirv << "%s_depth_1 = OpTypeStruct %float\n";
  3593. for (int i = 2; i <= depth; ++i) {
  3594. spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n";
  3595. }
  3596. // Define Pointer and Variable to use for the AccessChain instruction.
  3597. spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_"
  3598. << depth << "\n";
  3599. spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n";
  3600. // Function Start
  3601. spirv << R"(
  3602. %func = OpFunction %void None %void_f
  3603. %my_label = OpLabel
  3604. )";
  3605. // AccessChain with 'n' indexes (n = depth)
  3606. spirv << "%entry = " << instr << " %_ptr_Uniform_float %deep_var" << elem;
  3607. for (int i = 0; i < depth; ++i) {
  3608. spirv << " %int_0";
  3609. }
  3610. // Function end
  3611. spirv << R"(
  3612. OpReturn
  3613. OpFunctionEnd
  3614. )";
  3615. spvValidatorOptionsSetUniversalLimit(
  3616. options_, spv_validator_limit_max_access_chain_indexes, 10u);
  3617. CompileSuccessfully(spirv.str());
  3618. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3619. }
  3620. // Invalid: 11 indexes passed to the access chain instruction. Custom Limit:10
  3621. TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesBad) {
  3622. const std::string instr = GetParam();
  3623. const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
  3624. std::ostringstream spirv;
  3625. spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup;
  3626. spirv << "%entry = " << instr << " %_ptr_Private_float %my_matrix" << elem;
  3627. for (int i = 0; i < 11; ++i) {
  3628. spirv << " %int_0";
  3629. }
  3630. spirv << R"(
  3631. OpReturn
  3632. OpFunctionEnd
  3633. )";
  3634. const std::string expected_err = "The number of indexes in " + instr +
  3635. " may not exceed 10. Found 11 indexes.";
  3636. spvValidatorOptionsSetUniversalLimit(
  3637. options_, spv_validator_limit_max_access_chain_indexes, 10u);
  3638. CompileSuccessfully(spirv.str());
  3639. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3640. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3641. }
  3642. // Invalid: Index passed to the access chain instruction is float (must be
  3643. // integer).
  3644. TEST_P(AccessChainInstructionTest, AccessChainUndefinedIndexBad) {
  3645. const std::string instr = GetParam();
  3646. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3647. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3648. %entry = )" +
  3649. instr + R"( %_ptr_Private_float %my_matrix )" + elem +
  3650. R"(%float_0 %int_1
  3651. OpReturn
  3652. OpFunctionEnd
  3653. )";
  3654. const std::string expected_err =
  3655. "Indexes passed to " + instr + " must be of type integer.";
  3656. CompileSuccessfully(spirv);
  3657. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3658. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3659. }
  3660. // Invalid: The index argument that indexes into a struct must be of type
  3661. // OpConstant.
  3662. TEST_P(AccessChainInstructionTest, AccessChainStructIndexNotConstantBad) {
  3663. const std::string instr = GetParam();
  3664. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3665. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3666. %f = )" +
  3667. instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
  3668. R"(%int_0 %spec_int %int_2
  3669. OpReturn
  3670. OpFunctionEnd
  3671. )";
  3672. const std::string expected_err =
  3673. "The <id> passed to " + instr +
  3674. " to index into a structure must be an OpConstant.";
  3675. CompileSuccessfully(spirv);
  3676. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3677. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3678. }
  3679. // Invalid: Indexing up to a vec4 granularity, but result type expected float.
  3680. TEST_P(AccessChainInstructionTest,
  3681. AccessChainStructResultTypeDoesntMatchIndexedTypeBad) {
  3682. const std::string instr = GetParam();
  3683. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3684. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3685. %entry = )" +
  3686. instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
  3687. R"(%int_0 %int_1 %int_2
  3688. OpReturn
  3689. OpFunctionEnd
  3690. )";
  3691. const std::string expected_err = instr +
  3692. " result type (OpTypeFloat) does not match "
  3693. "the type that results from indexing into "
  3694. "the base <id> (OpTypeVector).";
  3695. CompileSuccessfully(spirv);
  3696. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3697. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3698. }
  3699. // Invalid: Reach non-composite type (bool) when unused indexes remain.
  3700. TEST_P(AccessChainInstructionTest, AccessChainStructTooManyIndexesBad) {
  3701. const std::string instr = GetParam();
  3702. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3703. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3704. %entry = )" +
  3705. instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
  3706. R"(%int_0 %int_2 %int_2
  3707. OpReturn
  3708. OpFunctionEnd
  3709. )";
  3710. const std::string expected_err = instr +
  3711. " reached non-composite type while "
  3712. "indexes still remain to be traversed.";
  3713. CompileSuccessfully(spirv);
  3714. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3715. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3716. }
  3717. // Invalid: Trying to find index 3 of the struct that has only 3 members.
  3718. TEST_P(AccessChainInstructionTest, AccessChainStructIndexOutOfBoundBad) {
  3719. const std::string instr = GetParam();
  3720. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3721. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3722. %entry = )" +
  3723. instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
  3724. R"(%int_3 %int_2 %int_2
  3725. OpReturn
  3726. OpFunctionEnd
  3727. )";
  3728. const std::string expected_err = "Index is out of bounds: " + instr +
  3729. " can not find index 3 into the structure "
  3730. "<id> '25[%_struct_25]'. This structure "
  3731. "has 3 members. Largest valid index is 2.";
  3732. CompileSuccessfully(spirv);
  3733. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3734. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3735. }
  3736. // Valid: Tests that we can index into Struct, Array, Matrix, and Vector!
  3737. TEST_P(AccessChainInstructionTest, AccessChainIndexIntoAllTypesGood) {
  3738. // indexes that we are passing are: 0, 3, 1, 2, 0
  3739. // 0 will select the struct_s within the base struct (blockName)
  3740. // 3 will select the Array that contains 5 matrices
  3741. // 1 will select the Matrix that is at index 1 of the array
  3742. // 2 will select the column (which is a vector) within the matrix at index 2
  3743. // 0 will select the element at the index 0 of the vector. (which is a float).
  3744. const std::string instr = GetParam();
  3745. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3746. std::ostringstream spirv;
  3747. spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup << std::endl;
  3748. spirv << "%ss = " << instr << " %_ptr_Uniform_struct_s %blockName_var "
  3749. << elem << "%int_0" << std::endl;
  3750. spirv << "%sa = " << instr << " %_ptr_Uniform_array5_mat4x3 %blockName_var "
  3751. << elem << "%int_0 %int_3" << std::endl;
  3752. spirv << "%sm = " << instr << " %_ptr_Uniform_mat4x3 %blockName_var " << elem
  3753. << "%int_0 %int_3 %int_1" << std::endl;
  3754. spirv << "%sc = " << instr << " %_ptr_Uniform_v3float %blockName_var " << elem
  3755. << "%int_0 %int_3 %int_1 %int_2" << std::endl;
  3756. spirv << "%entry = " << instr << " %_ptr_Uniform_float %blockName_var "
  3757. << elem << "%int_0 %int_3 %int_1 %int_2 %int_0" << std::endl;
  3758. spirv << R"(
  3759. OpReturn
  3760. OpFunctionEnd
  3761. )";
  3762. CompileSuccessfully(spirv.str());
  3763. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3764. }
  3765. // Valid: Access an element of OpTypeRuntimeArray.
  3766. TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayGood) {
  3767. const std::string instr = GetParam();
  3768. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3769. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3770. %runtime_arr_entry = )" +
  3771. instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
  3772. R"(%int_2 %int_0
  3773. OpReturn
  3774. OpFunctionEnd
  3775. )";
  3776. CompileSuccessfully(spirv);
  3777. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3778. }
  3779. // Invalid: Unused index when accessing OpTypeRuntimeArray.
  3780. TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayBad) {
  3781. const std::string instr = GetParam();
  3782. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3783. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3784. %runtime_arr_entry = )" +
  3785. instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
  3786. R"(%int_2 %int_0 %int_1
  3787. OpReturn
  3788. OpFunctionEnd
  3789. )";
  3790. const std::string expected_err =
  3791. instr +
  3792. " reached non-composite type while indexes still remain to be traversed.";
  3793. CompileSuccessfully(spirv);
  3794. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3795. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3796. }
  3797. // Invalid: Reached scalar type before arguments to the access chain instruction
  3798. // finished.
  3799. TEST_P(AccessChainInstructionTest, AccessChainMatrixMoreArgsThanNeededBad) {
  3800. const std::string instr = GetParam();
  3801. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3802. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3803. %entry = )" +
  3804. instr + R"( %_ptr_Private_float %my_matrix )" + elem +
  3805. R"(%int_0 %int_1 %int_0
  3806. OpReturn
  3807. OpFunctionEnd
  3808. )";
  3809. const std::string expected_err = instr +
  3810. " reached non-composite type while "
  3811. "indexes still remain to be traversed.";
  3812. CompileSuccessfully(spirv);
  3813. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3814. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3815. }
  3816. // Invalid: The result type and the type indexed into do not match.
  3817. TEST_P(AccessChainInstructionTest,
  3818. AccessChainResultTypeDoesntMatchIndexedTypeBad) {
  3819. const std::string instr = GetParam();
  3820. const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
  3821. std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
  3822. %entry = )" +
  3823. instr + R"( %_ptr_Private_mat4x3 %my_matrix )" + elem +
  3824. R"(%int_0 %int_1
  3825. OpReturn
  3826. OpFunctionEnd
  3827. )";
  3828. const std::string expected_err = instr +
  3829. " result type (OpTypeMatrix) does not match "
  3830. "the type that results from indexing into "
  3831. "the base <id> (OpTypeFloat).";
  3832. CompileSuccessfully(spirv);
  3833. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3834. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
  3835. }
  3836. // Run tests for Access Chain Instructions.
  3837. INSTANTIATE_TEST_SUITE_P(
  3838. CheckAccessChainInstructions, AccessChainInstructionTest,
  3839. ::testing::Values("OpAccessChain", "OpInBoundsAccessChain",
  3840. "OpPtrAccessChain", "OpInBoundsPtrAccessChain"));
  3841. // TODO: OpArrayLength
  3842. // TODO: OpImagePointer
  3843. // TODO: OpGenericPtrMemSemantics
  3844. TEST_F(ValidateIdWithMessage, OpFunctionGood) {
  3845. std::string spirv = kGLSL450MemoryModel + R"(
  3846. %1 = OpTypeVoid
  3847. %2 = OpTypeInt 32 0
  3848. %3 = OpTypeFunction %1 %2 %2
  3849. %4 = OpFunction %1 None %3
  3850. %5 = OpLabel
  3851. OpReturn
  3852. OpFunctionEnd)";
  3853. CompileSuccessfully(spirv.c_str());
  3854. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3855. }
  3856. TEST_F(ValidateIdWithMessage, OpFunctionResultTypeBad) {
  3857. std::string spirv = kGLSL450MemoryModel + R"(
  3858. %1 = OpTypeVoid
  3859. %2 = OpTypeInt 32 0
  3860. %3 = OpConstant %2 42
  3861. %4 = OpTypeFunction %1 %2 %2
  3862. %5 = OpFunction %2 None %4
  3863. %6 = OpLabel
  3864. OpReturnValue %3
  3865. OpFunctionEnd)";
  3866. CompileSuccessfully(spirv.c_str());
  3867. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3868. EXPECT_THAT(getDiagnosticString(),
  3869. HasSubstr("OpFunction Result Type <id> '2[%uint]' does not "
  3870. "match the Function Type's return type <id> "
  3871. "'1[%void]'."));
  3872. }
  3873. TEST_F(ValidateIdWithMessage, OpReturnValueTypeBad) {
  3874. std::string spirv = kGLSL450MemoryModel + R"(
  3875. %1 = OpTypeInt 32 0
  3876. %2 = OpTypeFloat 32
  3877. %3 = OpConstant %2 0
  3878. %4 = OpTypeFunction %1
  3879. %5 = OpFunction %1 None %4
  3880. %6 = OpLabel
  3881. OpReturnValue %3
  3882. OpFunctionEnd)";
  3883. CompileSuccessfully(spirv.c_str());
  3884. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3885. EXPECT_THAT(getDiagnosticString(),
  3886. HasSubstr("OpReturnValue Value <id> '3[%float_0]'s type does "
  3887. "not match OpFunction's return type."));
  3888. }
  3889. TEST_F(ValidateIdWithMessage, OpFunctionFunctionTypeBad) {
  3890. std::string spirv = kGLSL450MemoryModel + R"(
  3891. %1 = OpTypeVoid
  3892. %2 = OpTypeInt 32 0
  3893. %4 = OpFunction %1 None %2
  3894. %5 = OpLabel
  3895. OpReturn
  3896. OpFunctionEnd)";
  3897. CompileSuccessfully(spirv.c_str());
  3898. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3899. EXPECT_THAT(
  3900. getDiagnosticString(),
  3901. HasSubstr("OpFunction Function Type <id> '2[%uint]' is not a function "
  3902. "type."));
  3903. }
  3904. TEST_F(ValidateIdWithMessage, OpFunctionUseBad) {
  3905. const std::string spirv = kGLSL450MemoryModel + R"(
  3906. %1 = OpTypeFloat 32
  3907. %2 = OpTypeFunction %1
  3908. %3 = OpFunction %1 None %2
  3909. %4 = OpLabel
  3910. OpReturnValue %3
  3911. OpFunctionEnd
  3912. )";
  3913. CompileSuccessfully(spirv);
  3914. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3915. EXPECT_THAT(getDiagnosticString(),
  3916. HasSubstr("Invalid use of function result id 3[%3]."));
  3917. }
  3918. TEST_F(ValidateIdWithMessage, OpFunctionParameterGood) {
  3919. std::string spirv = kGLSL450MemoryModel + R"(
  3920. %1 = OpTypeVoid
  3921. %2 = OpTypeInt 32 0
  3922. %3 = OpTypeFunction %1 %2
  3923. %4 = OpFunction %1 None %3
  3924. %5 = OpFunctionParameter %2
  3925. %6 = OpLabel
  3926. OpReturn
  3927. OpFunctionEnd)";
  3928. CompileSuccessfully(spirv.c_str());
  3929. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3930. }
  3931. TEST_F(ValidateIdWithMessage, OpFunctionParameterMultipleGood) {
  3932. std::string spirv = kGLSL450MemoryModel + R"(
  3933. %1 = OpTypeVoid
  3934. %2 = OpTypeInt 32 0
  3935. %3 = OpTypeFunction %1 %2 %2
  3936. %4 = OpFunction %1 None %3
  3937. %5 = OpFunctionParameter %2
  3938. %6 = OpFunctionParameter %2
  3939. %7 = OpLabel
  3940. OpReturn
  3941. OpFunctionEnd)";
  3942. CompileSuccessfully(spirv.c_str());
  3943. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3944. }
  3945. TEST_F(ValidateIdWithMessage, OpFunctionParameterResultTypeBad) {
  3946. std::string spirv = kGLSL450MemoryModel + R"(
  3947. %1 = OpTypeVoid
  3948. %2 = OpTypeInt 32 0
  3949. %3 = OpTypeFunction %1 %2
  3950. %4 = OpFunction %1 None %3
  3951. %5 = OpFunctionParameter %1
  3952. %6 = OpLabel
  3953. OpReturn
  3954. OpFunctionEnd)";
  3955. CompileSuccessfully(spirv.c_str());
  3956. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3957. EXPECT_THAT(
  3958. getDiagnosticString(),
  3959. HasSubstr("OpFunctionParameter Result Type <id> '1[%void]' does not "
  3960. "match the OpTypeFunction parameter type of the same index."));
  3961. }
  3962. TEST_F(ValidateIdWithMessage, OpFunctionCallGood) {
  3963. std::string spirv = kGLSL450MemoryModel + R"(
  3964. %1 = OpTypeVoid
  3965. %2 = OpTypeInt 32 0
  3966. %3 = OpTypeFunction %2 %2
  3967. %4 = OpTypeFunction %1
  3968. %5 = OpConstant %2 42 ;21
  3969. %6 = OpFunction %2 None %3
  3970. %7 = OpFunctionParameter %2
  3971. %8 = OpLabel
  3972. OpReturnValue %7
  3973. OpFunctionEnd
  3974. %10 = OpFunction %1 None %4
  3975. %11 = OpLabel
  3976. %12 = OpFunctionCall %2 %6 %5
  3977. OpReturn
  3978. OpFunctionEnd)";
  3979. CompileSuccessfully(spirv.c_str());
  3980. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3981. }
  3982. TEST_F(ValidateIdWithMessage, OpFunctionCallResultTypeBad) {
  3983. std::string spirv = kGLSL450MemoryModel + R"(
  3984. %1 = OpTypeVoid
  3985. %2 = OpTypeInt 32 0
  3986. %3 = OpTypeFunction %2 %2
  3987. %4 = OpTypeFunction %1
  3988. %5 = OpConstant %2 42 ;21
  3989. %6 = OpFunction %2 None %3
  3990. %7 = OpFunctionParameter %2
  3991. %8 = OpLabel
  3992. %9 = OpIAdd %2 %7 %7
  3993. OpReturnValue %9
  3994. OpFunctionEnd
  3995. %10 = OpFunction %1 None %4
  3996. %11 = OpLabel
  3997. %12 = OpFunctionCall %1 %6 %5
  3998. OpReturn
  3999. OpFunctionEnd)";
  4000. CompileSuccessfully(spirv.c_str());
  4001. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4002. EXPECT_THAT(getDiagnosticString(),
  4003. HasSubstr("OpFunctionCall Result Type <id> '1[%void]'s type "
  4004. "does not match Function <id> '2[%uint]'s return "
  4005. "type."));
  4006. }
  4007. TEST_F(ValidateIdWithMessage, OpFunctionCallFunctionBad) {
  4008. std::string spirv = kGLSL450MemoryModel + R"(
  4009. %1 = OpTypeVoid
  4010. %2 = OpTypeInt 32 0
  4011. %3 = OpTypeFunction %2 %2
  4012. %4 = OpTypeFunction %1
  4013. %5 = OpConstant %2 42 ;21
  4014. %10 = OpFunction %1 None %4
  4015. %11 = OpLabel
  4016. %12 = OpFunctionCall %2 %5 %5
  4017. OpReturn
  4018. OpFunctionEnd)";
  4019. CompileSuccessfully(spirv.c_str());
  4020. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4021. EXPECT_THAT(getDiagnosticString(),
  4022. HasSubstr("OpFunctionCall Function <id> '5[%uint_42]' is not a "
  4023. "function."));
  4024. }
  4025. TEST_F(ValidateIdWithMessage, OpFunctionCallArgumentTypeBad) {
  4026. std::string spirv = kGLSL450MemoryModel + R"(
  4027. %1 = OpTypeVoid
  4028. %2 = OpTypeInt 32 0
  4029. %3 = OpTypeFunction %2 %2
  4030. %4 = OpTypeFunction %1
  4031. %5 = OpConstant %2 42
  4032. %13 = OpTypeFloat 32
  4033. %14 = OpConstant %13 3.14
  4034. %6 = OpFunction %2 None %3
  4035. %7 = OpFunctionParameter %2
  4036. %8 = OpLabel
  4037. %9 = OpIAdd %2 %7 %7
  4038. OpReturnValue %9
  4039. OpFunctionEnd
  4040. %10 = OpFunction %1 None %4
  4041. %11 = OpLabel
  4042. %12 = OpFunctionCall %2 %6 %14
  4043. OpReturn
  4044. OpFunctionEnd)";
  4045. CompileSuccessfully(spirv.c_str());
  4046. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4047. EXPECT_THAT(getDiagnosticString(),
  4048. HasSubstr("OpFunctionCall Argument <id> '7[%float_3_1400001]'s "
  4049. "type does not match Function <id> '2[%uint]'s "
  4050. "parameter type."));
  4051. }
  4052. // Valid: OpSampledImage result <id> is used in the same block by
  4053. // OpImageSampleImplictLod
  4054. TEST_F(ValidateIdWithMessage, OpSampledImageGood) {
  4055. std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
  4056. %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
  4057. %si_lod = OpImageSampleImplicitLod %v4float %smpld_img %const_vec_1_1
  4058. OpReturn
  4059. OpFunctionEnd)";
  4060. CompileSuccessfully(spirv.c_str());
  4061. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4062. }
  4063. // Invalid: OpSampledImage result <id> is defined in one block and used in a
  4064. // different block.
  4065. TEST_F(ValidateIdWithMessage, OpSampledImageUsedInDifferentBlockBad) {
  4066. std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
  4067. %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
  4068. OpBranch %label_2
  4069. %label_2 = OpLabel
  4070. %si_lod = OpImageSampleImplicitLod %v4float %smpld_img %const_vec_1_1
  4071. OpReturn
  4072. OpFunctionEnd)";
  4073. CompileSuccessfully(spirv.c_str());
  4074. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4075. EXPECT_THAT(
  4076. getDiagnosticString(),
  4077. HasSubstr("All OpSampledImage instructions must be in the same block in "
  4078. "which their Result <id> are consumed. OpSampledImage Result "
  4079. "Type <id> '23[%23]' has a consumer in a different basic "
  4080. "block. The consumer instruction <id> is '25[%25]'."));
  4081. }
  4082. // Invalid: OpSampledImage result <id> is used by OpSelect
  4083. // Note: According to the Spec, OpSelect parameters must be either a scalar or a
  4084. // vector. Therefore, OpTypeSampledImage is an illegal parameter for OpSelect.
  4085. // However, the OpSelect validation does not catch this today. Therefore, it is
  4086. // caught by the OpSampledImage validation. If the OpSelect validation code is
  4087. // updated, the error message for this test may change.
  4088. //
  4089. // Disabled since OpSelect catches this now.
  4090. TEST_F(ValidateIdWithMessage, DISABLED_OpSampledImageUsedInOpSelectBad) {
  4091. std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
  4092. %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
  4093. %select_img = OpSelect %sampled_image_type %spec_true %smpld_img %smpld_img
  4094. OpReturn
  4095. OpFunctionEnd)";
  4096. CompileSuccessfully(spirv.c_str());
  4097. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4098. EXPECT_THAT(getDiagnosticString(),
  4099. HasSubstr("Result <id> from OpSampledImage instruction must not "
  4100. "appear as operands of OpSelect. Found result <id> "
  4101. "'23' as an operand of <id> '24'."));
  4102. }
  4103. TEST_F(ValidateIdWithMessage, OpCopyObjectSampledImageGood) {
  4104. std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
  4105. %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
  4106. %smpld_img2 = OpCopyObject %sampled_image_type %smpld_img
  4107. %image_inst2 = OpCopyObject %image_type %image_inst
  4108. OpReturn
  4109. OpFunctionEnd)";
  4110. CompileSuccessfully(spirv.c_str());
  4111. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4112. }
  4113. // Valid: Get a float in a matrix using CompositeExtract.
  4114. // Valid: Insert float into a matrix using CompositeInsert.
  4115. TEST_F(ValidateIdWithMessage, CompositeExtractInsertGood) {
  4116. std::ostringstream spirv;
  4117. spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup << std::endl;
  4118. spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl;
  4119. spirv << "%float_entry = OpCompositeExtract %float %matrix 0 1" << std::endl;
  4120. // To test CompositeInsert, insert the object back in after extraction.
  4121. spirv << "%new_composite = OpCompositeInsert %mat4x3 %float_entry %matrix 0 1"
  4122. << std::endl;
  4123. spirv << R"(OpReturn
  4124. OpFunctionEnd)";
  4125. CompileSuccessfully(spirv.str());
  4126. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4127. }
  4128. #if 0
  4129. TEST_F(ValidateIdWithMessage, OpFunctionCallArgumentCountBar) {
  4130. const char *spirv = R"(
  4131. %1 = OpTypeVoid
  4132. %2 = OpTypeInt 32 0
  4133. %3 = OpTypeFunction %2 %2
  4134. %4 = OpTypeFunction %1
  4135. %5 = OpConstant %2 42 ;21
  4136. %6 = OpFunction %2 None %3
  4137. %7 = OpFunctionParameter %2
  4138. %8 = OpLabel
  4139. %9 = OpLoad %2 %7
  4140. OpReturnValue %9
  4141. OpFunctionEnd
  4142. %10 = OpFunction %1 None %4
  4143. %11 = OpLabel
  4144. OpReturn
  4145. %12 = OpFunctionCall %2 %6 %5
  4146. OpFunctionEnd)";
  4147. CHECK(spirv, SPV_ERROR_INVALID_ID);
  4148. }
  4149. #endif
  4150. // TODO: The many things that changed with how images are used.
  4151. // TODO: OpTextureSample
  4152. // TODO: OpTextureSampleDref
  4153. // TODO: OpTextureSampleLod
  4154. // TODO: OpTextureSampleProj
  4155. // TODO: OpTextureSampleGrad
  4156. // TODO: OpTextureSampleOffset
  4157. // TODO: OpTextureSampleProjLod
  4158. // TODO: OpTextureSampleProjGrad
  4159. // TODO: OpTextureSampleLodOffset
  4160. // TODO: OpTextureSampleProjOffset
  4161. // TODO: OpTextureSampleGradOffset
  4162. // TODO: OpTextureSampleProjLodOffset
  4163. // TODO: OpTextureSampleProjGradOffset
  4164. // TODO: OpTextureFetchTexelLod
  4165. // TODO: OpTextureFetchTexelOffset
  4166. // TODO: OpTextureFetchSample
  4167. // TODO: OpTextureFetchTexel
  4168. // TODO: OpTextureGather
  4169. // TODO: OpTextureGatherOffset
  4170. // TODO: OpTextureGatherOffsets
  4171. // TODO: OpTextureQuerySizeLod
  4172. // TODO: OpTextureQuerySize
  4173. // TODO: OpTextureQueryLevels
  4174. // TODO: OpTextureQuerySamples
  4175. // TODO: OpConvertUToF
  4176. // TODO: OpConvertFToS
  4177. // TODO: OpConvertSToF
  4178. // TODO: OpConvertUToF
  4179. // TODO: OpUConvert
  4180. // TODO: OpSConvert
  4181. // TODO: OpFConvert
  4182. // TODO: OpConvertPtrToU
  4183. // TODO: OpConvertUToPtr
  4184. // TODO: OpPtrCastToGeneric
  4185. // TODO: OpGenericCastToPtr
  4186. // TODO: OpBitcast
  4187. // TODO: OpGenericCastToPtrExplicit
  4188. // TODO: OpSatConvertSToU
  4189. // TODO: OpSatConvertUToS
  4190. // TODO: OpVectorExtractDynamic
  4191. // TODO: OpVectorInsertDynamic
  4192. TEST_F(ValidateIdWithMessage, OpVectorShuffleIntGood) {
  4193. std::string spirv = kGLSL450MemoryModel + R"(
  4194. %int = OpTypeInt 32 0
  4195. %ivec3 = OpTypeVector %int 3
  4196. %ivec4 = OpTypeVector %int 4
  4197. %ptr_ivec3 = OpTypePointer Function %ivec3
  4198. %undef = OpUndef %ivec4
  4199. %int_42 = OpConstant %int 42
  4200. %int_0 = OpConstant %int 0
  4201. %int_2 = OpConstant %int 2
  4202. %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
  4203. %2 = OpTypeFunction %ivec3
  4204. %3 = OpFunction %ivec3 None %2
  4205. %4 = OpLabel
  4206. %var = OpVariable %ptr_ivec3 Function %1
  4207. %5 = OpLoad %ivec3 %var
  4208. %6 = OpVectorShuffle %ivec3 %5 %undef 2 1 0
  4209. OpReturnValue %6
  4210. OpFunctionEnd)";
  4211. CompileSuccessfully(spirv.c_str());
  4212. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4213. }
  4214. TEST_F(ValidateIdWithMessage, OpVectorShuffleFloatGood) {
  4215. std::string spirv = kGLSL450MemoryModel + R"(
  4216. %float = OpTypeFloat 32
  4217. %vec2 = OpTypeVector %float 2
  4218. %vec3 = OpTypeVector %float 3
  4219. %vec4 = OpTypeVector %float 4
  4220. %ptr_vec2 = OpTypePointer Function %vec2
  4221. %ptr_vec3 = OpTypePointer Function %vec3
  4222. %float_1 = OpConstant %float 1
  4223. %float_2 = OpConstant %float 2
  4224. %1 = OpConstantComposite %vec2 %float_2 %float_1
  4225. %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
  4226. %3 = OpTypeFunction %vec4
  4227. %4 = OpFunction %vec4 None %3
  4228. %5 = OpLabel
  4229. %var = OpVariable %ptr_vec2 Function %1
  4230. %var2 = OpVariable %ptr_vec3 Function %2
  4231. %6 = OpLoad %vec2 %var
  4232. %7 = OpLoad %vec3 %var2
  4233. %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0xffffffff
  4234. OpReturnValue %8
  4235. OpFunctionEnd)";
  4236. CompileSuccessfully(spirv.c_str());
  4237. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4238. }
  4239. TEST_F(ValidateIdWithMessage, OpVectorShuffleScalarResultType) {
  4240. std::string spirv = kGLSL450MemoryModel + R"(
  4241. %float = OpTypeFloat 32
  4242. %vec2 = OpTypeVector %float 2
  4243. %ptr_vec2 = OpTypePointer Function %vec2
  4244. %float_1 = OpConstant %float 1
  4245. %float_2 = OpConstant %float 2
  4246. %1 = OpConstantComposite %vec2 %float_2 %float_1
  4247. %2 = OpTypeFunction %float
  4248. %3 = OpFunction %float None %2
  4249. %4 = OpLabel
  4250. %var = OpVariable %ptr_vec2 Function %1
  4251. %5 = OpLoad %vec2 %var
  4252. %6 = OpVectorShuffle %float %5 %5 0
  4253. OpReturnValue %6
  4254. OpFunctionEnd)";
  4255. CompileSuccessfully(spirv.c_str());
  4256. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4257. EXPECT_THAT(
  4258. getDiagnosticString(),
  4259. HasSubstr("Result Type of OpVectorShuffle must be OpTypeVector."));
  4260. }
  4261. TEST_F(ValidateIdWithMessage, OpVectorShuffleComponentCount) {
  4262. std::string spirv = kGLSL450MemoryModel + R"(
  4263. %int = OpTypeInt 32 0
  4264. %ivec3 = OpTypeVector %int 3
  4265. %ptr_ivec3 = OpTypePointer Function %ivec3
  4266. %int_42 = OpConstant %int 42
  4267. %int_0 = OpConstant %int 0
  4268. %int_2 = OpConstant %int 2
  4269. %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
  4270. %2 = OpTypeFunction %ivec3
  4271. %3 = OpFunction %ivec3 None %2
  4272. %4 = OpLabel
  4273. %var = OpVariable %ptr_ivec3 Function %1
  4274. %5 = OpLoad %ivec3 %var
  4275. %6 = OpVectorShuffle %ivec3 %5 %5 0 1
  4276. OpReturnValue %6
  4277. OpFunctionEnd)";
  4278. CompileSuccessfully(spirv.c_str());
  4279. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4280. EXPECT_THAT(
  4281. getDiagnosticString(),
  4282. HasSubstr("OpVectorShuffle component literals count does not match "
  4283. "Result Type <id> '2[%v3uint]'s vector component count."));
  4284. }
  4285. TEST_F(ValidateIdWithMessage, OpVectorShuffleVector1Type) {
  4286. std::string spirv = kGLSL450MemoryModel + R"(
  4287. %int = OpTypeInt 32 0
  4288. %ivec2 = OpTypeVector %int 2
  4289. %ptr_int = OpTypePointer Function %int
  4290. %undef = OpUndef %ivec2
  4291. %int_42 = OpConstant %int 42
  4292. %2 = OpTypeFunction %ivec2
  4293. %3 = OpFunction %ivec2 None %2
  4294. %4 = OpLabel
  4295. %var = OpVariable %ptr_int Function %int_42
  4296. %5 = OpLoad %int %var
  4297. %6 = OpVectorShuffle %ivec2 %5 %undef 0 0
  4298. OpReturnValue %6
  4299. OpFunctionEnd)";
  4300. CompileSuccessfully(spirv.c_str());
  4301. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4302. EXPECT_THAT(getDiagnosticString(),
  4303. HasSubstr("The type of Vector 1 must be OpTypeVector."));
  4304. }
  4305. TEST_F(ValidateIdWithMessage, OpVectorShuffleVector2Type) {
  4306. std::string spirv = kGLSL450MemoryModel + R"(
  4307. %int = OpTypeInt 32 0
  4308. %ivec2 = OpTypeVector %int 2
  4309. %ptr_ivec2 = OpTypePointer Function %ivec2
  4310. %undef = OpUndef %int
  4311. %int_42 = OpConstant %int 42
  4312. %1 = OpConstantComposite %ivec2 %int_42 %int_42
  4313. %2 = OpTypeFunction %ivec2
  4314. %3 = OpFunction %ivec2 None %2
  4315. %4 = OpLabel
  4316. %var = OpVariable %ptr_ivec2 Function %1
  4317. %5 = OpLoad %ivec2 %var
  4318. %6 = OpVectorShuffle %ivec2 %5 %undef 0 1
  4319. OpReturnValue %6
  4320. OpFunctionEnd)";
  4321. CompileSuccessfully(spirv.c_str());
  4322. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4323. EXPECT_THAT(getDiagnosticString(),
  4324. HasSubstr("The type of Vector 2 must be OpTypeVector."));
  4325. }
  4326. TEST_F(ValidateIdWithMessage, OpVectorShuffleVector1ComponentType) {
  4327. std::string spirv = kGLSL450MemoryModel + R"(
  4328. %int = OpTypeInt 32 0
  4329. %ivec3 = OpTypeVector %int 3
  4330. %ptr_ivec3 = OpTypePointer Function %ivec3
  4331. %int_42 = OpConstant %int 42
  4332. %int_0 = OpConstant %int 0
  4333. %int_2 = OpConstant %int 2
  4334. %float = OpTypeFloat 32
  4335. %vec3 = OpTypeVector %float 3
  4336. %vec4 = OpTypeVector %float 4
  4337. %ptr_vec3 = OpTypePointer Function %vec3
  4338. %float_1 = OpConstant %float 1
  4339. %float_2 = OpConstant %float 2
  4340. %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
  4341. %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
  4342. %3 = OpTypeFunction %vec4
  4343. %4 = OpFunction %vec4 None %3
  4344. %5 = OpLabel
  4345. %var = OpVariable %ptr_ivec3 Function %1
  4346. %var2 = OpVariable %ptr_vec3 Function %2
  4347. %6 = OpLoad %ivec3 %var
  4348. %7 = OpLoad %vec3 %var2
  4349. %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0
  4350. OpReturnValue %8
  4351. OpFunctionEnd)";
  4352. CompileSuccessfully(spirv.c_str());
  4353. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4354. EXPECT_THAT(getDiagnosticString(),
  4355. HasSubstr("The Component Type of Vector 1 must be the same as "
  4356. "ResultType."));
  4357. }
  4358. TEST_F(ValidateIdWithMessage, OpVectorShuffleVector2ComponentType) {
  4359. std::string spirv = kGLSL450MemoryModel + R"(
  4360. %int = OpTypeInt 32 0
  4361. %ivec3 = OpTypeVector %int 3
  4362. %ptr_ivec3 = OpTypePointer Function %ivec3
  4363. %int_42 = OpConstant %int 42
  4364. %int_0 = OpConstant %int 0
  4365. %int_2 = OpConstant %int 2
  4366. %float = OpTypeFloat 32
  4367. %vec3 = OpTypeVector %float 3
  4368. %vec4 = OpTypeVector %float 4
  4369. %ptr_vec3 = OpTypePointer Function %vec3
  4370. %float_1 = OpConstant %float 1
  4371. %float_2 = OpConstant %float 2
  4372. %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
  4373. %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
  4374. %3 = OpTypeFunction %vec4
  4375. %4 = OpFunction %vec4 None %3
  4376. %5 = OpLabel
  4377. %var = OpVariable %ptr_ivec3 Function %1
  4378. %var2 = OpVariable %ptr_vec3 Function %2
  4379. %6 = OpLoad %vec3 %var2
  4380. %7 = OpLoad %ivec3 %var
  4381. %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0
  4382. OpReturnValue %8
  4383. OpFunctionEnd)";
  4384. CompileSuccessfully(spirv.c_str());
  4385. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4386. EXPECT_THAT(getDiagnosticString(),
  4387. HasSubstr("The Component Type of Vector 2 must be the same as "
  4388. "ResultType."));
  4389. }
  4390. TEST_F(ValidateIdWithMessage, OpVectorShuffleLiterals) {
  4391. std::string spirv = kGLSL450MemoryModel + R"(
  4392. %float = OpTypeFloat 32
  4393. %vec2 = OpTypeVector %float 2
  4394. %vec3 = OpTypeVector %float 3
  4395. %vec4 = OpTypeVector %float 4
  4396. %ptr_vec2 = OpTypePointer Function %vec2
  4397. %ptr_vec3 = OpTypePointer Function %vec3
  4398. %float_1 = OpConstant %float 1
  4399. %float_2 = OpConstant %float 2
  4400. %1 = OpConstantComposite %vec2 %float_2 %float_1
  4401. %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
  4402. %3 = OpTypeFunction %vec4
  4403. %4 = OpFunction %vec4 None %3
  4404. %5 = OpLabel
  4405. %var = OpVariable %ptr_vec2 Function %1
  4406. %var2 = OpVariable %ptr_vec3 Function %2
  4407. %6 = OpLoad %vec2 %var
  4408. %7 = OpLoad %vec3 %var2
  4409. %8 = OpVectorShuffle %vec4 %6 %7 0 8 2 6
  4410. OpReturnValue %8
  4411. OpFunctionEnd)";
  4412. CompileSuccessfully(spirv.c_str());
  4413. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4414. EXPECT_THAT(
  4415. getDiagnosticString(),
  4416. HasSubstr(
  4417. "Component index 8 is out of bounds for combined (Vector1 + Vector2) "
  4418. "size of 5."));
  4419. }
  4420. // TODO: OpCompositeConstruct
  4421. // TODO: OpCompositeExtract
  4422. // TODO: OpCompositeInsert
  4423. // TODO: OpCopyObject
  4424. // TODO: OpTranspose
  4425. // TODO: OpSNegate
  4426. // TODO: OpFNegate
  4427. // TODO: OpNot
  4428. // TODO: OpIAdd
  4429. // TODO: OpFAdd
  4430. // TODO: OpISub
  4431. // TODO: OpFSub
  4432. // TODO: OpIMul
  4433. // TODO: OpFMul
  4434. // TODO: OpUDiv
  4435. // TODO: OpSDiv
  4436. // TODO: OpFDiv
  4437. // TODO: OpUMod
  4438. // TODO: OpSRem
  4439. // TODO: OpSMod
  4440. // TODO: OpFRem
  4441. // TODO: OpFMod
  4442. // TODO: OpVectorTimesScalar
  4443. // TODO: OpMatrixTimesScalar
  4444. // TODO: OpVectorTimesMatrix
  4445. // TODO: OpMatrixTimesVector
  4446. // TODO: OpMatrixTimesMatrix
  4447. // TODO: OpOuterProduct
  4448. // TODO: OpDot
  4449. // TODO: OpShiftRightLogical
  4450. // TODO: OpShiftRightArithmetic
  4451. // TODO: OpShiftLeftLogical
  4452. // TODO: OpBitwiseOr
  4453. // TODO: OpBitwiseXor
  4454. // TODO: OpBitwiseAnd
  4455. // TODO: OpAny
  4456. // TODO: OpAll
  4457. // TODO: OpIsNan
  4458. // TODO: OpIsInf
  4459. // TODO: OpIsFinite
  4460. // TODO: OpIsNormal
  4461. // TODO: OpSignBitSet
  4462. // TODO: OpLessOrGreater
  4463. // TODO: OpOrdered
  4464. // TODO: OpUnordered
  4465. // TODO: OpLogicalOr
  4466. // TODO: OpLogicalXor
  4467. // TODO: OpLogicalAnd
  4468. // TODO: OpSelect
  4469. // TODO: OpIEqual
  4470. // TODO: OpFOrdEqual
  4471. // TODO: OpFUnordEqual
  4472. // TODO: OpINotEqual
  4473. // TODO: OpFOrdNotEqual
  4474. // TODO: OpFUnordNotEqual
  4475. // TODO: OpULessThan
  4476. // TODO: OpSLessThan
  4477. // TODO: OpFOrdLessThan
  4478. // TODO: OpFUnordLessThan
  4479. // TODO: OpUGreaterThan
  4480. // TODO: OpSGreaterThan
  4481. // TODO: OpFOrdGreaterThan
  4482. // TODO: OpFUnordGreaterThan
  4483. // TODO: OpULessThanEqual
  4484. // TODO: OpSLessThanEqual
  4485. // TODO: OpFOrdLessThanEqual
  4486. // TODO: OpFUnordLessThanEqual
  4487. // TODO: OpUGreaterThanEqual
  4488. // TODO: OpSGreaterThanEqual
  4489. // TODO: OpFOrdGreaterThanEqual
  4490. // TODO: OpFUnordGreaterThanEqual
  4491. // TODO: OpDPdx
  4492. // TODO: OpDPdy
  4493. // TODO: OpFWidth
  4494. // TODO: OpDPdxFine
  4495. // TODO: OpDPdyFine
  4496. // TODO: OpFwidthFine
  4497. // TODO: OpDPdxCoarse
  4498. // TODO: OpDPdyCoarse
  4499. // TODO: OpFwidthCoarse
  4500. // TODO: OpLoopMerge
  4501. // TODO: OpSelectionMerge
  4502. // TODO: OpBranch
  4503. TEST_F(ValidateIdWithMessage, OpPhiNotAType) {
  4504. std::string spirv = kOpenCLMemoryModel32 + R"(
  4505. %2 = OpTypeBool
  4506. %3 = OpConstantTrue %2
  4507. %4 = OpTypeVoid
  4508. %5 = OpTypeFunction %4
  4509. %6 = OpFunction %4 None %5
  4510. %7 = OpLabel
  4511. OpBranch %8
  4512. %8 = OpLabel
  4513. %9 = OpPhi %3 %3 %7
  4514. OpReturn
  4515. OpFunctionEnd
  4516. )";
  4517. CompileSuccessfully(spirv.c_str());
  4518. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4519. EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 3[%true] is not a type "
  4520. "id"));
  4521. }
  4522. TEST_F(ValidateIdWithMessage, OpPhiSamePredecessor) {
  4523. std::string spirv = kOpenCLMemoryModel32 + R"(
  4524. %2 = OpTypeBool
  4525. %3 = OpConstantTrue %2
  4526. %4 = OpTypeVoid
  4527. %5 = OpTypeFunction %4
  4528. %6 = OpFunction %4 None %5
  4529. %7 = OpLabel
  4530. OpBranchConditional %3 %8 %8
  4531. %8 = OpLabel
  4532. %9 = OpPhi %2 %3 %7
  4533. OpReturn
  4534. OpFunctionEnd
  4535. )";
  4536. CompileSuccessfully(spirv.c_str());
  4537. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4538. }
  4539. TEST_F(ValidateIdWithMessage, OpPhiOddArgumentNumber) {
  4540. std::string spirv = kOpenCLMemoryModel32 + R"(
  4541. %2 = OpTypeBool
  4542. %3 = OpConstantTrue %2
  4543. %4 = OpTypeVoid
  4544. %5 = OpTypeFunction %4
  4545. %6 = OpFunction %4 None %5
  4546. %7 = OpLabel
  4547. OpBranch %8
  4548. %8 = OpLabel
  4549. %9 = OpPhi %2 %3
  4550. OpReturn
  4551. OpFunctionEnd
  4552. )";
  4553. CompileSuccessfully(spirv.c_str());
  4554. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4555. EXPECT_THAT(getDiagnosticString(),
  4556. HasSubstr("OpPhi does not have an equal number of incoming "
  4557. "values and basic blocks."));
  4558. }
  4559. TEST_F(ValidateIdWithMessage, OpPhiTooFewPredecessors) {
  4560. std::string spirv = kOpenCLMemoryModel32 + R"(
  4561. %2 = OpTypeBool
  4562. %3 = OpConstantTrue %2
  4563. %4 = OpTypeVoid
  4564. %5 = OpTypeFunction %4
  4565. %6 = OpFunction %4 None %5
  4566. %7 = OpLabel
  4567. OpBranch %8
  4568. %8 = OpLabel
  4569. %9 = OpPhi %2
  4570. OpReturn
  4571. OpFunctionEnd
  4572. )";
  4573. CompileSuccessfully(spirv.c_str());
  4574. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4575. EXPECT_THAT(getDiagnosticString(),
  4576. HasSubstr("OpPhi's number of incoming blocks (0) does not match "
  4577. "block's predecessor count (1)."));
  4578. }
  4579. TEST_F(ValidateIdWithMessage, OpPhiTooManyPredecessors) {
  4580. std::string spirv = kOpenCLMemoryModel32 + R"(
  4581. %2 = OpTypeBool
  4582. %3 = OpConstantTrue %2
  4583. %4 = OpTypeVoid
  4584. %5 = OpTypeFunction %4
  4585. %6 = OpFunction %4 None %5
  4586. %7 = OpLabel
  4587. OpBranch %8
  4588. %9 = OpLabel
  4589. OpReturn
  4590. %8 = OpLabel
  4591. %10 = OpPhi %2 %3 %7 %3 %9
  4592. OpReturn
  4593. OpFunctionEnd
  4594. )";
  4595. CompileSuccessfully(spirv.c_str());
  4596. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4597. EXPECT_THAT(getDiagnosticString(),
  4598. HasSubstr("OpPhi's number of incoming blocks (2) does not match "
  4599. "block's predecessor count (1)."));
  4600. }
  4601. TEST_F(ValidateIdWithMessage, OpPhiMismatchedTypes) {
  4602. std::string spirv = kOpenCLMemoryModel32 + R"(
  4603. %2 = OpTypeBool
  4604. %3 = OpConstantTrue %2
  4605. %4 = OpTypeVoid
  4606. %5 = OpTypeInt 32 0
  4607. %6 = OpConstant %5 0
  4608. %7 = OpTypeFunction %4
  4609. %8 = OpFunction %4 None %7
  4610. %9 = OpLabel
  4611. OpBranchConditional %3 %10 %11
  4612. %11 = OpLabel
  4613. OpBranch %10
  4614. %10 = OpLabel
  4615. %12 = OpPhi %2 %3 %9 %6 %11
  4616. OpReturn
  4617. OpFunctionEnd
  4618. )";
  4619. CompileSuccessfully(spirv.c_str());
  4620. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4621. EXPECT_THAT(getDiagnosticString(),
  4622. HasSubstr("OpPhi's result type <id> 2[%bool] does not match "
  4623. "incoming value <id> 6[%uint_0] type <id> "
  4624. "5[%uint]."));
  4625. }
  4626. TEST_F(ValidateIdWithMessage, OpPhiPredecessorNotABlock) {
  4627. std::string spirv = kOpenCLMemoryModel32 + R"(
  4628. %2 = OpTypeBool
  4629. %3 = OpConstantTrue %2
  4630. %4 = OpTypeVoid
  4631. %5 = OpTypeFunction %4
  4632. %6 = OpFunction %4 None %5
  4633. %7 = OpLabel
  4634. OpBranchConditional %3 %8 %9
  4635. %9 = OpLabel
  4636. OpBranch %11
  4637. %11 = OpLabel
  4638. OpBranch %8
  4639. %8 = OpLabel
  4640. %10 = OpPhi %2 %3 %7 %3 %3
  4641. OpReturn
  4642. OpFunctionEnd
  4643. )";
  4644. CompileSuccessfully(spirv.c_str());
  4645. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4646. EXPECT_THAT(getDiagnosticString(),
  4647. HasSubstr("OpPhi's incoming basic block <id> 3[%true] is not an "
  4648. "OpLabel."));
  4649. }
  4650. TEST_F(ValidateIdWithMessage, OpPhiNotAPredecessor) {
  4651. std::string spirv = kOpenCLMemoryModel32 + R"(
  4652. %2 = OpTypeBool
  4653. %3 = OpConstantTrue %2
  4654. %4 = OpTypeVoid
  4655. %5 = OpTypeFunction %4
  4656. %6 = OpFunction %4 None %5
  4657. %7 = OpLabel
  4658. OpBranchConditional %3 %8 %9
  4659. %9 = OpLabel
  4660. OpBranch %11
  4661. %11 = OpLabel
  4662. OpBranch %8
  4663. %8 = OpLabel
  4664. %10 = OpPhi %2 %3 %7 %3 %9
  4665. OpReturn
  4666. OpFunctionEnd
  4667. )";
  4668. CompileSuccessfully(spirv.c_str());
  4669. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4670. EXPECT_THAT(getDiagnosticString(),
  4671. HasSubstr("OpPhi's incoming basic block <id> 9[%9] is not a "
  4672. "predecessor of <id> 8[%8]."));
  4673. }
  4674. TEST_F(ValidateIdWithMessage, OpBranchConditionalGood) {
  4675. std::string spirv = BranchConditionalSetup + R"(
  4676. %branch_cond = OpINotEqual %bool %i0 %i1
  4677. OpSelectionMerge %end None
  4678. OpBranchConditional %branch_cond %target_t %target_f
  4679. )" + BranchConditionalTail;
  4680. CompileSuccessfully(spirv.c_str());
  4681. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4682. }
  4683. TEST_F(ValidateIdWithMessage, OpBranchConditionalWithWeightsGood) {
  4684. std::string spirv = BranchConditionalSetup + R"(
  4685. %branch_cond = OpINotEqual %bool %i0 %i1
  4686. OpSelectionMerge %end None
  4687. OpBranchConditional %branch_cond %target_t %target_f 1 1
  4688. )" + BranchConditionalTail;
  4689. CompileSuccessfully(spirv.c_str());
  4690. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  4691. }
  4692. TEST_F(ValidateIdWithMessage, OpBranchConditional_CondIsScalarInt) {
  4693. std::string spirv = BranchConditionalSetup + R"(
  4694. OpSelectionMerge %end None
  4695. OpBranchConditional %i0 %target_t %target_f
  4696. )" + BranchConditionalTail;
  4697. CompileSuccessfully(spirv.c_str());
  4698. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4699. EXPECT_THAT(
  4700. getDiagnosticString(),
  4701. HasSubstr(
  4702. "Condition operand for OpBranchConditional must be of boolean type"));
  4703. }
  4704. TEST_F(ValidateIdWithMessage, OpBranchConditional_TrueTargetIsNotLabel) {
  4705. std::string spirv = BranchConditionalSetup + R"(
  4706. OpSelectionMerge %end None
  4707. OpBranchConditional %true %i0 %target_f
  4708. )" + BranchConditionalTail;
  4709. CompileSuccessfully(spirv.c_str());
  4710. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4711. EXPECT_THAT(getDiagnosticString(),
  4712. HasSubstr("The 'True Label' operand for OpBranchConditional must "
  4713. "be the ID of an OpLabel instruction"));
  4714. }
  4715. TEST_F(ValidateIdWithMessage, OpBranchConditional_FalseTargetIsNotLabel) {
  4716. std::string spirv = BranchConditionalSetup + R"(
  4717. OpSelectionMerge %end None
  4718. OpBranchConditional %true %target_t %i0
  4719. )" + BranchConditionalTail;
  4720. CompileSuccessfully(spirv.c_str());
  4721. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4722. EXPECT_THAT(getDiagnosticString(),
  4723. HasSubstr("The 'False Label' operand for OpBranchConditional "
  4724. "must be the ID of an OpLabel instruction"));
  4725. }
  4726. TEST_F(ValidateIdWithMessage, OpBranchConditional_NotEnoughWeights) {
  4727. std::string spirv = BranchConditionalSetup + R"(
  4728. %branch_cond = OpINotEqual %bool %i0 %i1
  4729. OpSelectionMerge %end None
  4730. OpBranchConditional %branch_cond %target_t %target_f 1
  4731. )" + BranchConditionalTail;
  4732. CompileSuccessfully(spirv.c_str());
  4733. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4734. EXPECT_THAT(
  4735. getDiagnosticString(),
  4736. HasSubstr("OpBranchConditional requires either 3 or 5 parameters"));
  4737. }
  4738. TEST_F(ValidateIdWithMessage, OpBranchConditional_TooManyWeights) {
  4739. std::string spirv = BranchConditionalSetup + R"(
  4740. %branch_cond = OpINotEqual %bool %i0 %i1
  4741. OpSelectionMerge %end None
  4742. OpBranchConditional %branch_cond %target_t %target_f 1 2 3
  4743. )" + BranchConditionalTail;
  4744. CompileSuccessfully(spirv.c_str());
  4745. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4746. EXPECT_THAT(
  4747. getDiagnosticString(),
  4748. HasSubstr("OpBranchConditional requires either 3 or 5 parameters"));
  4749. }
  4750. TEST_F(ValidateIdWithMessage, OpBranchConditional_ConditionIsAType) {
  4751. std::string spirv = BranchConditionalSetup + R"(
  4752. OpBranchConditional %bool %target_t %target_f
  4753. )" + BranchConditionalTail;
  4754. CompileSuccessfully(spirv.c_str());
  4755. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4756. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 3[%bool] cannot be a "
  4757. "type"));
  4758. }
  4759. // TODO: OpSwitch
  4760. TEST_F(ValidateIdWithMessage, OpReturnValueConstantGood) {
  4761. std::string spirv = kGLSL450MemoryModel + R"(
  4762. %1 = OpTypeVoid
  4763. %2 = OpTypeInt 32 0
  4764. %3 = OpTypeFunction %2
  4765. %4 = OpConstant %2 42
  4766. %5 = OpFunction %2 None %3
  4767. %6 = OpLabel
  4768. OpReturnValue %4
  4769. OpFunctionEnd)";
  4770. CompileSuccessfully(spirv.c_str());
  4771. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4772. }
  4773. TEST_F(ValidateIdWithMessage, OpReturnValueVariableGood) {
  4774. std::string spirv = kGLSL450MemoryModel + R"(
  4775. %1 = OpTypeVoid
  4776. %2 = OpTypeInt 32 0 ;10
  4777. %3 = OpTypeFunction %2
  4778. %8 = OpTypePointer Function %2 ;18
  4779. %4 = OpConstant %2 42 ;22
  4780. %5 = OpFunction %2 None %3 ;27
  4781. %6 = OpLabel ;29
  4782. %7 = OpVariable %8 Function %4 ;34
  4783. %9 = OpLoad %2 %7
  4784. OpReturnValue %9 ;36
  4785. OpFunctionEnd)";
  4786. CompileSuccessfully(spirv.c_str());
  4787. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4788. }
  4789. TEST_F(ValidateIdWithMessage, OpReturnValueExpressionGood) {
  4790. std::string spirv = kGLSL450MemoryModel + R"(
  4791. %1 = OpTypeVoid
  4792. %2 = OpTypeInt 32 0
  4793. %3 = OpTypeFunction %2
  4794. %4 = OpConstant %2 42
  4795. %5 = OpFunction %2 None %3
  4796. %6 = OpLabel
  4797. %7 = OpIAdd %2 %4 %4
  4798. OpReturnValue %7
  4799. OpFunctionEnd)";
  4800. CompileSuccessfully(spirv.c_str());
  4801. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4802. }
  4803. TEST_F(ValidateIdWithMessage, OpReturnValueIsType) {
  4804. std::string spirv = kGLSL450MemoryModel + R"(
  4805. %1 = OpTypeVoid
  4806. %2 = OpTypeInt 32 0
  4807. %3 = OpTypeFunction %2
  4808. %5 = OpFunction %2 None %3
  4809. %6 = OpLabel
  4810. OpReturnValue %1
  4811. OpFunctionEnd)";
  4812. CompileSuccessfully(spirv.c_str());
  4813. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4814. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 1[%void] cannot be a "
  4815. "type"));
  4816. }
  4817. TEST_F(ValidateIdWithMessage, OpReturnValueIsLabel) {
  4818. std::string spirv = kGLSL450MemoryModel + R"(
  4819. %1 = OpTypeVoid
  4820. %2 = OpTypeInt 32 0
  4821. %3 = OpTypeFunction %2
  4822. %5 = OpFunction %2 None %3
  4823. %6 = OpLabel
  4824. OpReturnValue %6
  4825. OpFunctionEnd)";
  4826. CompileSuccessfully(spirv.c_str());
  4827. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4828. EXPECT_THAT(getDiagnosticString(),
  4829. HasSubstr("Operand 5[%5] requires a type"));
  4830. }
  4831. TEST_F(ValidateIdWithMessage, OpReturnValueIsVoid) {
  4832. std::string spirv = kGLSL450MemoryModel + R"(
  4833. %1 = OpTypeVoid
  4834. %2 = OpTypeInt 32 0
  4835. %3 = OpTypeFunction %1
  4836. %5 = OpFunction %1 None %3
  4837. %6 = OpLabel
  4838. %7 = OpFunctionCall %1 %5
  4839. OpReturnValue %7
  4840. OpFunctionEnd)";
  4841. CompileSuccessfully(spirv.c_str());
  4842. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4843. EXPECT_THAT(
  4844. getDiagnosticString(),
  4845. HasSubstr("OpReturnValue value's type <id> '1[%void]' is missing or "
  4846. "void."));
  4847. }
  4848. TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInPhysical) {
  4849. // It's valid to return a pointer in a physical addressing model.
  4850. std::string spirv = kOpCapabilitySetup + R"(
  4851. OpMemoryModel Physical32 OpenCL
  4852. %1 = OpTypeVoid
  4853. %2 = OpTypeInt 32 0
  4854. %3 = OpTypePointer Function %2
  4855. %4 = OpTypeFunction %3
  4856. %5 = OpFunction %3 None %4
  4857. %6 = OpLabel
  4858. %7 = OpVariable %3 Function
  4859. OpReturnValue %7
  4860. OpFunctionEnd)";
  4861. CompileSuccessfully(spirv.c_str());
  4862. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4863. }
  4864. TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInLogical) {
  4865. // It's invalid to return a pointer in a physical addressing model.
  4866. std::string spirv = kOpCapabilitySetup + R"(
  4867. OpMemoryModel Logical GLSL450
  4868. %1 = OpTypeVoid
  4869. %2 = OpTypeInt 32 0
  4870. %3 = OpTypePointer Function %2
  4871. %4 = OpTypeFunction %3
  4872. %5 = OpFunction %3 None %4
  4873. %6 = OpLabel
  4874. %7 = OpVariable %3 Function
  4875. OpReturnValue %7
  4876. OpFunctionEnd)";
  4877. CompileSuccessfully(spirv.c_str());
  4878. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4879. EXPECT_THAT(getDiagnosticString(),
  4880. HasSubstr("OpReturnValue value's type <id> "
  4881. "'3[%_ptr_Function_uint]' is a pointer, which is "
  4882. "invalid in the Logical addressing model."));
  4883. }
  4884. // With the VariablePointer Capability, the return value of a function is
  4885. // allowed to be a pointer.
  4886. TEST_F(ValidateIdWithMessage, OpReturnValueVarPtrGood) {
  4887. std::ostringstream spirv;
  4888. createVariablePointerSpirvProgram(&spirv,
  4889. "" /* Instructions to add to "main" */,
  4890. true /* Add VariablePointers Capability?*/,
  4891. true /* Use Helper Function? */);
  4892. CompileSuccessfully(spirv.str());
  4893. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4894. }
  4895. // Without the VariablePointer Capability, the return value of a function is
  4896. // *not* allowed to be a pointer.
  4897. // Disabled since using OpSelect with pointers without VariablePointers will
  4898. // fail LogicalsPass.
  4899. TEST_F(ValidateIdWithMessage, DISABLED_OpReturnValueVarPtrBad) {
  4900. std::ostringstream spirv;
  4901. createVariablePointerSpirvProgram(&spirv,
  4902. "" /* Instructions to add to "main" */,
  4903. false /* Add VariablePointers Capability?*/,
  4904. true /* Use Helper Function? */);
  4905. CompileSuccessfully(spirv.str());
  4906. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4907. EXPECT_THAT(getDiagnosticString(),
  4908. HasSubstr("OpReturnValue value's type <id> '7' is a pointer, "
  4909. "which is invalid in the Logical addressing model."));
  4910. }
  4911. // TODO: enable when this bug is fixed:
  4912. // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
  4913. TEST_F(ValidateIdWithMessage, DISABLED_OpReturnValueIsFunction) {
  4914. std::string spirv = kGLSL450MemoryModel + R"(
  4915. %1 = OpTypeVoid
  4916. %2 = OpTypeInt 32 0
  4917. %3 = OpTypeFunction %2
  4918. %5 = OpFunction %2 None %3
  4919. %6 = OpLabel
  4920. OpReturnValue %5
  4921. OpFunctionEnd)";
  4922. CompileSuccessfully(spirv.c_str());
  4923. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4924. }
  4925. TEST_F(ValidateIdWithMessage, UndefinedTypeId) {
  4926. std::string spirv = kGLSL450MemoryModel + R"(
  4927. %s = OpTypeStruct %i32
  4928. )";
  4929. CompileSuccessfully(spirv.c_str());
  4930. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4931. EXPECT_THAT(getDiagnosticString(),
  4932. HasSubstr("Operand 2[%2] requires a previous definition"));
  4933. }
  4934. TEST_F(ValidateIdWithMessage, UndefinedIdScope) {
  4935. std::string spirv = kGLSL450MemoryModel + R"(
  4936. %u32 = OpTypeInt 32 0
  4937. %memsem = OpConstant %u32 0
  4938. %void = OpTypeVoid
  4939. %void_f = OpTypeFunction %void
  4940. %f = OpFunction %void None %void_f
  4941. %l = OpLabel
  4942. OpMemoryBarrier %undef %memsem
  4943. OpReturn
  4944. OpFunctionEnd
  4945. )";
  4946. CompileSuccessfully(spirv.c_str());
  4947. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4948. EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7[%7] has not been "
  4949. "defined"));
  4950. }
  4951. TEST_F(ValidateIdWithMessage, UndefinedIdMemSem) {
  4952. std::string spirv = kGLSL450MemoryModel + R"(
  4953. %u32 = OpTypeInt 32 0
  4954. %scope = OpConstant %u32 0
  4955. %void = OpTypeVoid
  4956. %void_f = OpTypeFunction %void
  4957. %f = OpFunction %void None %void_f
  4958. %l = OpLabel
  4959. OpMemoryBarrier %scope %undef
  4960. OpReturn
  4961. OpFunctionEnd
  4962. )";
  4963. CompileSuccessfully(spirv.c_str());
  4964. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4965. EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7[%7] has not been "
  4966. "defined"));
  4967. }
  4968. TEST_F(ValidateIdWithMessage,
  4969. KernelOpEntryPointAndOpInBoundsPtrAccessChainGood) {
  4970. std::string spirv = kOpenCLMemoryModel32 + R"(
  4971. OpEntryPoint Kernel %2 "simple_kernel"
  4972. OpSource OpenCL_C 200000
  4973. OpDecorate %3 BuiltIn GlobalInvocationId
  4974. OpDecorate %3 Constant
  4975. OpDecorate %4 FuncParamAttr NoCapture
  4976. OpDecorate %3 LinkageAttributes "__spirv_GlobalInvocationId" Import
  4977. %5 = OpTypeInt 32 0
  4978. %6 = OpTypeVector %5 3
  4979. %7 = OpTypePointer UniformConstant %6
  4980. %3 = OpVariable %7 UniformConstant
  4981. %8 = OpTypeVoid
  4982. %9 = OpTypeStruct %5
  4983. %10 = OpTypePointer CrossWorkgroup %9
  4984. %11 = OpTypeFunction %8 %10
  4985. %12 = OpConstant %5 0
  4986. %13 = OpTypePointer CrossWorkgroup %5
  4987. %14 = OpConstant %5 42
  4988. %2 = OpFunction %8 None %11
  4989. %4 = OpFunctionParameter %10
  4990. %15 = OpLabel
  4991. %16 = OpLoad %6 %3 Aligned 0
  4992. %17 = OpCompositeExtract %5 %16 0
  4993. %18 = OpInBoundsPtrAccessChain %13 %4 %17 %12
  4994. OpStore %18 %14 Aligned 4
  4995. OpReturn
  4996. OpFunctionEnd)";
  4997. CompileSuccessfully(spirv.c_str());
  4998. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4999. }
  5000. TEST_F(ValidateIdWithMessage, OpPtrAccessChainGood) {
  5001. std::string spirv = kOpenCLMemoryModel64 + R"(
  5002. OpEntryPoint Kernel %2 "another_kernel"
  5003. OpSource OpenCL_C 200000
  5004. OpDecorate %3 BuiltIn GlobalInvocationId
  5005. OpDecorate %3 Constant
  5006. OpDecorate %4 FuncParamAttr NoCapture
  5007. OpDecorate %3 LinkageAttributes "__spirv_GlobalInvocationId" Import
  5008. %5 = OpTypeInt 64 0
  5009. %6 = OpTypeVector %5 3
  5010. %7 = OpTypePointer UniformConstant %6
  5011. %3 = OpVariable %7 UniformConstant
  5012. %8 = OpTypeVoid
  5013. %9 = OpTypeInt 32 0
  5014. %10 = OpTypeStruct %9
  5015. %11 = OpTypePointer CrossWorkgroup %10
  5016. %12 = OpTypeFunction %8 %11
  5017. %13 = OpConstant %5 4294967295
  5018. %14 = OpConstant %9 0
  5019. %15 = OpTypePointer CrossWorkgroup %9
  5020. %16 = OpConstant %9 42
  5021. %2 = OpFunction %8 None %12
  5022. %4 = OpFunctionParameter %11
  5023. %17 = OpLabel
  5024. %18 = OpLoad %6 %3 Aligned 0
  5025. %19 = OpCompositeExtract %5 %18 0
  5026. %20 = OpBitwiseAnd %5 %19 %13
  5027. %21 = OpPtrAccessChain %15 %4 %20 %14
  5028. OpStore %21 %16 Aligned 4
  5029. OpReturn
  5030. OpFunctionEnd)";
  5031. CompileSuccessfully(spirv.c_str());
  5032. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5033. }
  5034. TEST_F(ValidateIdWithMessage, StgBufOpPtrAccessChainGood) {
  5035. std::string spirv = R"(
  5036. OpCapability Shader
  5037. OpCapability Linkage
  5038. OpCapability VariablePointersStorageBuffer
  5039. OpExtension "SPV_KHR_variable_pointers"
  5040. OpMemoryModel Logical GLSL450
  5041. OpEntryPoint GLCompute %3 ""
  5042. %int = OpTypeInt 32 0
  5043. %int_2 = OpConstant %int 2
  5044. %int_4 = OpConstant %int 4
  5045. %struct = OpTypeStruct %int
  5046. %array = OpTypeArray %struct %int_4
  5047. %ptr = OpTypePointer StorageBuffer %array
  5048. %var = OpVariable %ptr StorageBuffer
  5049. %1 = OpTypeVoid
  5050. %2 = OpTypeFunction %1
  5051. %3 = OpFunction %1 None %2
  5052. %4 = OpLabel
  5053. %5 = OpPtrAccessChain %ptr %var %int_2
  5054. OpReturn
  5055. OpFunctionEnd
  5056. )";
  5057. CompileSuccessfully(spirv.c_str());
  5058. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5059. }
  5060. TEST_F(ValidateIdWithMessage, OpLoadBitcastPointerGood) {
  5061. std::string spirv = kOpenCLMemoryModel64 + R"(
  5062. %2 = OpTypeVoid
  5063. %3 = OpTypeInt 32 0
  5064. %4 = OpTypeFloat 32
  5065. %5 = OpTypePointer UniformConstant %3
  5066. %6 = OpTypePointer UniformConstant %4
  5067. %7 = OpVariable %5 UniformConstant
  5068. %8 = OpTypeFunction %2
  5069. %9 = OpFunction %2 None %8
  5070. %10 = OpLabel
  5071. %11 = OpBitcast %6 %7
  5072. %12 = OpLoad %4 %11
  5073. OpReturn
  5074. OpFunctionEnd)";
  5075. CompileSuccessfully(spirv.c_str());
  5076. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5077. }
  5078. TEST_F(ValidateIdWithMessage, OpLoadBitcastNonPointerBad) {
  5079. std::string spirv = kOpenCLMemoryModel64 + R"(
  5080. %2 = OpTypeVoid
  5081. %3 = OpTypeInt 32 0
  5082. %4 = OpTypeFloat 32
  5083. %5 = OpTypePointer UniformConstant %3
  5084. %6 = OpTypeFunction %2
  5085. %7 = OpVariable %5 UniformConstant
  5086. %8 = OpFunction %2 None %6
  5087. %9 = OpLabel
  5088. %10 = OpLoad %3 %7
  5089. %11 = OpBitcast %4 %10
  5090. %12 = OpLoad %3 %11
  5091. OpReturn
  5092. OpFunctionEnd)";
  5093. CompileSuccessfully(spirv.c_str());
  5094. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5095. EXPECT_THAT(
  5096. getDiagnosticString(),
  5097. HasSubstr("OpLoad type for pointer <id> '11[%11]' is not a pointer "
  5098. "type."));
  5099. }
  5100. TEST_F(ValidateIdWithMessage, OpStoreBitcastPointerGood) {
  5101. std::string spirv = kOpenCLMemoryModel64 + R"(
  5102. %2 = OpTypeVoid
  5103. %3 = OpTypeInt 32 0
  5104. %4 = OpTypeFloat 32
  5105. %5 = OpTypePointer Function %3
  5106. %6 = OpTypePointer Function %4
  5107. %7 = OpTypeFunction %2
  5108. %8 = OpConstant %3 42
  5109. %9 = OpFunction %2 None %7
  5110. %10 = OpLabel
  5111. %11 = OpVariable %6 Function
  5112. %12 = OpBitcast %5 %11
  5113. OpStore %12 %8
  5114. OpReturn
  5115. OpFunctionEnd)";
  5116. CompileSuccessfully(spirv.c_str());
  5117. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5118. }
  5119. TEST_F(ValidateIdWithMessage, OpStoreBitcastNonPointerBad) {
  5120. std::string spirv = kOpenCLMemoryModel64 + R"(
  5121. %2 = OpTypeVoid
  5122. %3 = OpTypeInt 32 0
  5123. %4 = OpTypeFloat 32
  5124. %5 = OpTypePointer Function %4
  5125. %6 = OpTypeFunction %2
  5126. %7 = OpConstant %4 42
  5127. %8 = OpFunction %2 None %6
  5128. %9 = OpLabel
  5129. %10 = OpVariable %5 Function
  5130. %11 = OpBitcast %3 %7
  5131. OpStore %11 %7
  5132. OpReturn
  5133. OpFunctionEnd)";
  5134. CompileSuccessfully(spirv.c_str());
  5135. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5136. EXPECT_THAT(
  5137. getDiagnosticString(),
  5138. HasSubstr("OpStore type for pointer <id> '11[%11]' is not a pointer "
  5139. "type."));
  5140. }
  5141. // Result <id> resulting from an instruction within a function may not be used
  5142. // outside that function.
  5143. TEST_F(ValidateIdWithMessage, ResultIdUsedOutsideOfFunctionBad) {
  5144. std::string spirv = kGLSL450MemoryModel + R"(
  5145. %1 = OpTypeVoid
  5146. %2 = OpTypeFunction %1
  5147. %3 = OpTypeInt 32 0
  5148. %4 = OpTypePointer Function %3
  5149. %5 = OpFunction %1 None %2
  5150. %6 = OpLabel
  5151. %7 = OpVariable %4 Function
  5152. OpReturn
  5153. OpFunctionEnd
  5154. %8 = OpFunction %1 None %2
  5155. %9 = OpLabel
  5156. %10 = OpLoad %3 %7
  5157. OpReturn
  5158. OpFunctionEnd
  5159. )";
  5160. CompileSuccessfully(spirv.c_str());
  5161. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5162. EXPECT_THAT(
  5163. getDiagnosticString(),
  5164. HasSubstr(
  5165. "ID 7[%7] defined in block 6[%6] does not dominate its use in block "
  5166. "9[%9]"));
  5167. }
  5168. TEST_F(ValidateIdWithMessage, SpecIdTargetNotSpecializationConstant) {
  5169. std::string spirv = kGLSL450MemoryModel + R"(
  5170. OpDecorate %1 SpecId 200
  5171. %void = OpTypeVoid
  5172. %2 = OpTypeFunction %void
  5173. %int = OpTypeInt 32 0
  5174. %1 = OpConstant %int 3
  5175. %main = OpFunction %void None %2
  5176. %4 = OpLabel
  5177. OpReturnValue %1
  5178. OpFunctionEnd
  5179. )";
  5180. CompileSuccessfully(spirv.c_str());
  5181. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5182. EXPECT_THAT(getDiagnosticString(),
  5183. HasSubstr("OpDecorate SpecId decoration target <id> "
  5184. "'1[%uint_3]' is not a scalar specialization "
  5185. "constant."));
  5186. }
  5187. TEST_F(ValidateIdWithMessage, SpecIdTargetOpSpecConstantOpBad) {
  5188. std::string spirv = kGLSL450MemoryModel + R"(
  5189. OpDecorate %1 SpecId 200
  5190. %void = OpTypeVoid
  5191. %2 = OpTypeFunction %void
  5192. %int = OpTypeInt 32 0
  5193. %3 = OpConstant %int 1
  5194. %4 = OpConstant %int 2
  5195. %1 = OpSpecConstantOp %int IAdd %3 %4
  5196. %main = OpFunction %void None %2
  5197. %6 = OpLabel
  5198. OpReturnValue %3
  5199. OpFunctionEnd
  5200. )";
  5201. CompileSuccessfully(spirv.c_str());
  5202. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5203. EXPECT_THAT(getDiagnosticString(),
  5204. HasSubstr("OpDecorate SpecId decoration target <id> '1[%1]' is "
  5205. "not a scalar specialization constant."));
  5206. }
  5207. TEST_F(ValidateIdWithMessage, SpecIdTargetOpSpecConstantCompositeBad) {
  5208. std::string spirv = kGLSL450MemoryModel + R"(
  5209. OpDecorate %1 SpecId 200
  5210. %void = OpTypeVoid
  5211. %2 = OpTypeFunction %void
  5212. %int = OpTypeInt 32 0
  5213. %3 = OpConstant %int 1
  5214. %1 = OpSpecConstantComposite %int
  5215. %main = OpFunction %void None %2
  5216. %4 = OpLabel
  5217. OpReturnValue %3
  5218. OpFunctionEnd
  5219. )";
  5220. CompileSuccessfully(spirv.c_str());
  5221. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5222. EXPECT_THAT(getDiagnosticString(),
  5223. HasSubstr("OpDecorate SpecId decoration target <id> '1[%1]' is "
  5224. "not a scalar specialization constant."));
  5225. }
  5226. TEST_F(ValidateIdWithMessage, SpecIdTargetGood) {
  5227. std::string spirv = kGLSL450MemoryModel + R"(
  5228. OpDecorate %3 SpecId 200
  5229. OpDecorate %4 SpecId 201
  5230. OpDecorate %5 SpecId 202
  5231. %1 = OpTypeVoid
  5232. %2 = OpTypeFunction %1
  5233. %int = OpTypeInt 32 0
  5234. %bool = OpTypeBool
  5235. %3 = OpSpecConstant %int 3
  5236. %4 = OpSpecConstantTrue %bool
  5237. %5 = OpSpecConstantFalse %bool
  5238. %main = OpFunction %1 None %2
  5239. %6 = OpLabel
  5240. OpReturn
  5241. OpFunctionEnd
  5242. )";
  5243. CompileSuccessfully(spirv.c_str());
  5244. EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
  5245. }
  5246. TEST_F(ValidateIdWithMessage, CorrectErrorForShuffle) {
  5247. std::string spirv = kGLSL450MemoryModel + R"(
  5248. %uint = OpTypeInt 32 0
  5249. %float = OpTypeFloat 32
  5250. %v4float = OpTypeVector %float 4
  5251. %v2float = OpTypeVector %float 2
  5252. %void = OpTypeVoid
  5253. %548 = OpTypeFunction %void
  5254. %CS = OpFunction %void None %548
  5255. %550 = OpLabel
  5256. %6275 = OpUndef %v2float
  5257. %6280 = OpUndef %v2float
  5258. %6282 = OpVectorShuffle %v4float %6275 %6280 0 1 4 5
  5259. OpReturn
  5260. OpFunctionEnd
  5261. )";
  5262. CompileSuccessfully(spirv.c_str());
  5263. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5264. EXPECT_THAT(
  5265. getDiagnosticString(),
  5266. HasSubstr(
  5267. "Component index 4 is out of bounds for combined (Vector1 + Vector2) "
  5268. "size of 4."));
  5269. EXPECT_EQ(25, getErrorPosition().index);
  5270. }
  5271. TEST_F(ValidateIdWithMessage, VoidStructMember) {
  5272. const std::string spirv = kGLSL450MemoryModel + R"(
  5273. %void = OpTypeVoid
  5274. %struct = OpTypeStruct %void
  5275. )";
  5276. CompileSuccessfully(spirv);
  5277. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5278. EXPECT_THAT(getDiagnosticString(),
  5279. HasSubstr("Structures cannot contain a void type."));
  5280. }
  5281. TEST_F(ValidateIdWithMessage, TypeFunctionBadUse) {
  5282. std::string spirv = kGLSL450MemoryModel + R"(
  5283. %1 = OpTypeVoid
  5284. %2 = OpTypeFunction %1
  5285. %3 = OpTypePointer Function %2
  5286. %4 = OpFunction %1 None %2
  5287. %5 = OpLabel
  5288. OpReturn
  5289. OpFunctionEnd)";
  5290. CompileSuccessfully(spirv);
  5291. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5292. EXPECT_THAT(getDiagnosticString(),
  5293. HasSubstr("Invalid use of function type result id 2[%2]."));
  5294. }
  5295. TEST_F(ValidateIdWithMessage, BadTypeId) {
  5296. std::string spirv = kGLSL450MemoryModel + R"(
  5297. %1 = OpTypeVoid
  5298. %2 = OpTypeFunction %1
  5299. %3 = OpTypeFloat 32
  5300. %4 = OpConstant %3 0
  5301. %5 = OpFunction %1 None %2
  5302. %6 = OpLabel
  5303. %7 = OpUndef %4
  5304. OpReturn
  5305. OpFunctionEnd
  5306. )";
  5307. CompileSuccessfully(spirv);
  5308. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5309. EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 4[%float_0] is not a type "
  5310. "id"));
  5311. }
  5312. TEST_F(ValidateIdWithMessage, VulkanMemoryModelLoadMakePointerVisibleGood) {
  5313. std::string spirv = R"(
  5314. OpCapability Shader
  5315. OpCapability VulkanMemoryModelKHR
  5316. OpCapability Linkage
  5317. OpExtension "SPV_KHR_vulkan_memory_model"
  5318. OpMemoryModel Logical VulkanKHR
  5319. %1 = OpTypeVoid
  5320. %2 = OpTypeInt 32 0
  5321. %3 = OpTypePointer Workgroup %2
  5322. %4 = OpVariable %3 Workgroup
  5323. %5 = OpTypeFunction %1
  5324. %6 = OpConstant %2 2
  5325. %7 = OpFunction %1 None %5
  5326. %8 = OpLabel
  5327. %9 = OpLoad %2 %4 NonPrivatePointerKHR|MakePointerVisibleKHR %6
  5328. OpReturn
  5329. OpFunctionEnd
  5330. )";
  5331. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5332. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5333. }
  5334. TEST_F(ValidateIdWithMessage,
  5335. VulkanMemoryModelLoadMakePointerVisibleMissingNonPrivatePointer) {
  5336. std::string spirv = R"(
  5337. OpCapability Shader
  5338. OpCapability VulkanMemoryModelKHR
  5339. OpCapability Linkage
  5340. OpExtension "SPV_KHR_vulkan_memory_model"
  5341. OpMemoryModel Logical VulkanKHR
  5342. %1 = OpTypeVoid
  5343. %2 = OpTypeInt 32 0
  5344. %3 = OpTypePointer Workgroup %2
  5345. %4 = OpVariable %3 Workgroup
  5346. %5 = OpTypeFunction %1
  5347. %6 = OpConstant %2 2
  5348. %7 = OpFunction %1 None %5
  5349. %8 = OpLabel
  5350. %9 = OpLoad %2 %4 MakePointerVisibleKHR %6
  5351. OpReturn
  5352. OpFunctionEnd
  5353. )";
  5354. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5355. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5356. EXPECT_THAT(getDiagnosticString(),
  5357. HasSubstr("NonPrivatePointerKHR must be specified if "
  5358. "MakePointerVisibleKHR is specified."));
  5359. }
  5360. TEST_F(ValidateIdWithMessage,
  5361. VulkanMemoryModelLoadNonPrivatePointerBadStorageClass) {
  5362. std::string spirv = R"(
  5363. OpCapability Shader
  5364. OpCapability VulkanMemoryModelKHR
  5365. OpCapability Linkage
  5366. OpExtension "SPV_KHR_vulkan_memory_model"
  5367. OpMemoryModel Logical VulkanKHR
  5368. %1 = OpTypeVoid
  5369. %2 = OpTypeInt 32 0
  5370. %3 = OpTypePointer Private %2
  5371. %4 = OpVariable %3 Private
  5372. %5 = OpTypeFunction %1
  5373. %6 = OpConstant %2 2
  5374. %7 = OpFunction %1 None %5
  5375. %8 = OpLabel
  5376. %9 = OpLoad %2 %4 NonPrivatePointerKHR
  5377. OpReturn
  5378. OpFunctionEnd
  5379. )";
  5380. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5381. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5382. EXPECT_THAT(getDiagnosticString(),
  5383. HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
  5384. "Workgroup, CrossWorkgroup, Generic, Image or "
  5385. "StorageBuffer storage classes."));
  5386. }
  5387. TEST_F(ValidateIdWithMessage,
  5388. VulkanMemoryModelLoadMakePointerAvailableCannotBeUsed) {
  5389. std::string spirv = R"(
  5390. OpCapability Shader
  5391. OpCapability VulkanMemoryModelKHR
  5392. OpCapability Linkage
  5393. OpExtension "SPV_KHR_vulkan_memory_model"
  5394. OpMemoryModel Logical VulkanKHR
  5395. %1 = OpTypeVoid
  5396. %2 = OpTypeInt 32 0
  5397. %3 = OpTypePointer Workgroup %2
  5398. %4 = OpVariable %3 Workgroup
  5399. %5 = OpTypeFunction %1
  5400. %6 = OpConstant %2 2
  5401. %7 = OpFunction %1 None %5
  5402. %8 = OpLabel
  5403. %9 = OpLoad %2 %4 NonPrivatePointerKHR|MakePointerAvailableKHR %6
  5404. OpReturn
  5405. OpFunctionEnd
  5406. )";
  5407. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5408. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5409. EXPECT_THAT(getDiagnosticString(),
  5410. HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
  5411. }
  5412. TEST_F(ValidateIdWithMessage, VulkanMemoryModelStoreMakePointerAvailableGood) {
  5413. std::string spirv = R"(
  5414. OpCapability Shader
  5415. OpCapability VulkanMemoryModelKHR
  5416. OpCapability Linkage
  5417. OpExtension "SPV_KHR_vulkan_memory_model"
  5418. OpMemoryModel Logical VulkanKHR
  5419. %1 = OpTypeVoid
  5420. %2 = OpTypeInt 32 0
  5421. %3 = OpTypePointer Uniform %2
  5422. %4 = OpVariable %3 Uniform
  5423. %5 = OpTypeFunction %1
  5424. %6 = OpConstant %2 5
  5425. %7 = OpFunction %1 None %5
  5426. %8 = OpLabel
  5427. OpStore %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR %6
  5428. OpReturn
  5429. OpFunctionEnd
  5430. )";
  5431. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5432. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5433. }
  5434. TEST_F(ValidateIdWithMessage,
  5435. VulkanMemoryModelStoreMakePointerAvailableMissingNonPrivatePointer) {
  5436. std::string spirv = R"(
  5437. OpCapability Shader
  5438. OpCapability VulkanMemoryModelKHR
  5439. OpCapability Linkage
  5440. OpExtension "SPV_KHR_vulkan_memory_model"
  5441. OpMemoryModel Logical VulkanKHR
  5442. %1 = OpTypeVoid
  5443. %2 = OpTypeInt 32 0
  5444. %3 = OpTypePointer Uniform %2
  5445. %4 = OpVariable %3 Uniform
  5446. %5 = OpTypeFunction %1
  5447. %6 = OpConstant %2 5
  5448. %7 = OpFunction %1 None %5
  5449. %8 = OpLabel
  5450. OpStore %4 %6 MakePointerAvailableKHR %6
  5451. OpReturn
  5452. OpFunctionEnd
  5453. )";
  5454. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5455. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5456. EXPECT_THAT(getDiagnosticString(),
  5457. HasSubstr("NonPrivatePointerKHR must be specified if "
  5458. "MakePointerAvailableKHR is specified."));
  5459. }
  5460. TEST_F(ValidateIdWithMessage,
  5461. VulkanMemoryModelStoreNonPrivatePointerBadStorageClass) {
  5462. std::string spirv = R"(
  5463. OpCapability Shader
  5464. OpCapability VulkanMemoryModelKHR
  5465. OpCapability Linkage
  5466. OpExtension "SPV_KHR_vulkan_memory_model"
  5467. OpMemoryModel Logical VulkanKHR
  5468. %1 = OpTypeVoid
  5469. %2 = OpTypeInt 32 0
  5470. %3 = OpTypePointer Output %2
  5471. %4 = OpVariable %3 Output
  5472. %5 = OpTypeFunction %1
  5473. %6 = OpConstant %2 5
  5474. %7 = OpFunction %1 None %5
  5475. %8 = OpLabel
  5476. OpStore %4 %6 NonPrivatePointerKHR
  5477. OpReturn
  5478. OpFunctionEnd
  5479. )";
  5480. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5481. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5482. EXPECT_THAT(getDiagnosticString(),
  5483. HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
  5484. "Workgroup, CrossWorkgroup, Generic, Image or "
  5485. "StorageBuffer storage classes."));
  5486. }
  5487. TEST_F(ValidateIdWithMessage,
  5488. VulkanMemoryModelStoreMakePointerVisibleCannotBeUsed) {
  5489. std::string spirv = R"(
  5490. OpCapability Shader
  5491. OpCapability VulkanMemoryModelKHR
  5492. OpCapability Linkage
  5493. OpExtension "SPV_KHR_vulkan_memory_model"
  5494. OpMemoryModel Logical VulkanKHR
  5495. %1 = OpTypeVoid
  5496. %2 = OpTypeInt 32 0
  5497. %3 = OpTypePointer Uniform %2
  5498. %4 = OpVariable %3 Uniform
  5499. %5 = OpTypeFunction %1
  5500. %6 = OpConstant %2 5
  5501. %7 = OpFunction %1 None %5
  5502. %8 = OpLabel
  5503. OpStore %4 %6 NonPrivatePointerKHR|MakePointerVisibleKHR %6
  5504. OpReturn
  5505. OpFunctionEnd
  5506. )";
  5507. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5508. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5509. EXPECT_THAT(getDiagnosticString(),
  5510. HasSubstr("MakePointerVisibleKHR cannot be used with OpStore."));
  5511. }
  5512. TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryAvailable) {
  5513. std::string spirv = R"(
  5514. OpCapability Shader
  5515. OpCapability Linkage
  5516. OpCapability VulkanMemoryModelKHR
  5517. OpExtension "SPV_KHR_vulkan_memory_model"
  5518. OpMemoryModel Logical VulkanKHR
  5519. %1 = OpTypeVoid
  5520. %2 = OpTypeInt 32 0
  5521. %3 = OpTypePointer Workgroup %2
  5522. %4 = OpVariable %3 Workgroup
  5523. %5 = OpTypePointer Uniform %2
  5524. %6 = OpVariable %5 Uniform
  5525. %7 = OpConstant %2 2
  5526. %8 = OpConstant %2 5
  5527. %9 = OpTypeFunction %1
  5528. %10 = OpFunction %1 None %9
  5529. %11 = OpLabel
  5530. OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR %7
  5531. OpReturn
  5532. OpFunctionEnd
  5533. )";
  5534. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5535. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5536. }
  5537. TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryVisible) {
  5538. std::string spirv = R"(
  5539. OpCapability Shader
  5540. OpCapability Linkage
  5541. OpCapability VulkanMemoryModelKHR
  5542. OpExtension "SPV_KHR_vulkan_memory_model"
  5543. OpMemoryModel Logical VulkanKHR
  5544. %1 = OpTypeVoid
  5545. %2 = OpTypeInt 32 0
  5546. %3 = OpTypePointer Workgroup %2
  5547. %4 = OpVariable %3 Workgroup
  5548. %5 = OpTypePointer Uniform %2
  5549. %6 = OpVariable %5 Uniform
  5550. %7 = OpConstant %2 2
  5551. %8 = OpConstant %2 5
  5552. %9 = OpTypeFunction %1
  5553. %10 = OpFunction %1 None %9
  5554. %11 = OpLabel
  5555. OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerVisibleKHR %8
  5556. OpReturn
  5557. OpFunctionEnd
  5558. )";
  5559. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5560. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5561. }
  5562. TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryAvailableAndVisible) {
  5563. std::string spirv = R"(
  5564. OpCapability Shader
  5565. OpCapability Linkage
  5566. OpCapability VulkanMemoryModelKHR
  5567. OpExtension "SPV_KHR_vulkan_memory_model"
  5568. OpMemoryModel Logical VulkanKHR
  5569. %1 = OpTypeVoid
  5570. %2 = OpTypeInt 32 0
  5571. %3 = OpTypePointer Workgroup %2
  5572. %4 = OpVariable %3 Workgroup
  5573. %5 = OpTypePointer Uniform %2
  5574. %6 = OpVariable %5 Uniform
  5575. %7 = OpConstant %2 2
  5576. %8 = OpConstant %2 5
  5577. %9 = OpTypeFunction %1
  5578. %10 = OpFunction %1 None %9
  5579. %11 = OpLabel
  5580. OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR|MakePointerVisibleKHR %7 %8
  5581. OpReturn
  5582. OpFunctionEnd
  5583. )";
  5584. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5585. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5586. }
  5587. TEST_F(ValidateIdWithMessage,
  5588. VulkanMemoryModelCopyMemoryAvailableMissingNonPrivatePointer) {
  5589. std::string spirv = R"(
  5590. OpCapability Shader
  5591. OpCapability Linkage
  5592. OpCapability VulkanMemoryModelKHR
  5593. OpExtension "SPV_KHR_vulkan_memory_model"
  5594. OpMemoryModel Logical VulkanKHR
  5595. %1 = OpTypeVoid
  5596. %2 = OpTypeInt 32 0
  5597. %3 = OpTypePointer Workgroup %2
  5598. %4 = OpVariable %3 Workgroup
  5599. %5 = OpTypePointer Uniform %2
  5600. %6 = OpVariable %5 Uniform
  5601. %7 = OpConstant %2 2
  5602. %8 = OpConstant %2 5
  5603. %9 = OpTypeFunction %1
  5604. %10 = OpFunction %1 None %9
  5605. %11 = OpLabel
  5606. OpCopyMemory %4 %6 MakePointerAvailableKHR %7
  5607. OpReturn
  5608. OpFunctionEnd
  5609. )";
  5610. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5611. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5612. EXPECT_THAT(getDiagnosticString(),
  5613. HasSubstr("NonPrivatePointerKHR must be specified if "
  5614. "MakePointerAvailableKHR is specified."));
  5615. }
  5616. TEST_F(ValidateIdWithMessage,
  5617. VulkanMemoryModelCopyMemoryVisibleMissingNonPrivatePointer) {
  5618. std::string spirv = R"(
  5619. OpCapability Shader
  5620. OpCapability Linkage
  5621. OpCapability VulkanMemoryModelKHR
  5622. OpExtension "SPV_KHR_vulkan_memory_model"
  5623. OpMemoryModel Logical VulkanKHR
  5624. %1 = OpTypeVoid
  5625. %2 = OpTypeInt 32 0
  5626. %3 = OpTypePointer Workgroup %2
  5627. %4 = OpVariable %3 Workgroup
  5628. %5 = OpTypePointer Uniform %2
  5629. %6 = OpVariable %5 Uniform
  5630. %7 = OpConstant %2 2
  5631. %8 = OpConstant %2 5
  5632. %9 = OpTypeFunction %1
  5633. %10 = OpFunction %1 None %9
  5634. %11 = OpLabel
  5635. OpCopyMemory %4 %6 MakePointerVisibleKHR %8
  5636. OpReturn
  5637. OpFunctionEnd
  5638. )";
  5639. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5640. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5641. EXPECT_THAT(getDiagnosticString(),
  5642. HasSubstr("NonPrivatePointerKHR must be specified if "
  5643. "MakePointerVisibleKHR is specified."));
  5644. }
  5645. TEST_F(ValidateIdWithMessage,
  5646. VulkanMemoryModelCopyMemoryAvailableBadStorageClass) {
  5647. std::string spirv = R"(
  5648. OpCapability Shader
  5649. OpCapability Linkage
  5650. OpCapability VulkanMemoryModelKHR
  5651. OpExtension "SPV_KHR_vulkan_memory_model"
  5652. OpMemoryModel Logical VulkanKHR
  5653. %1 = OpTypeVoid
  5654. %2 = OpTypeInt 32 0
  5655. %3 = OpTypePointer Output %2
  5656. %4 = OpVariable %3 Output
  5657. %5 = OpTypePointer Uniform %2
  5658. %6 = OpVariable %5 Uniform
  5659. %7 = OpConstant %2 2
  5660. %8 = OpConstant %2 5
  5661. %9 = OpTypeFunction %1
  5662. %10 = OpFunction %1 None %9
  5663. %11 = OpLabel
  5664. OpCopyMemory %4 %6 NonPrivatePointerKHR
  5665. OpReturn
  5666. OpFunctionEnd
  5667. )";
  5668. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5669. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5670. EXPECT_THAT(getDiagnosticString(),
  5671. HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
  5672. "Workgroup, CrossWorkgroup, Generic, Image or "
  5673. "StorageBuffer storage classes."));
  5674. }
  5675. TEST_F(ValidateIdWithMessage,
  5676. VulkanMemoryModelCopyMemoryVisibleBadStorageClass) {
  5677. std::string spirv = R"(
  5678. OpCapability Shader
  5679. OpCapability Linkage
  5680. OpCapability VulkanMemoryModelKHR
  5681. OpExtension "SPV_KHR_vulkan_memory_model"
  5682. OpMemoryModel Logical VulkanKHR
  5683. %1 = OpTypeVoid
  5684. %2 = OpTypeInt 32 0
  5685. %3 = OpTypePointer Workgroup %2
  5686. %4 = OpVariable %3 Workgroup
  5687. %5 = OpTypePointer Input %2
  5688. %6 = OpVariable %5 Input
  5689. %7 = OpConstant %2 2
  5690. %8 = OpConstant %2 5
  5691. %9 = OpTypeFunction %1
  5692. %10 = OpFunction %1 None %9
  5693. %11 = OpLabel
  5694. OpCopyMemory %4 %6 NonPrivatePointerKHR
  5695. OpReturn
  5696. OpFunctionEnd
  5697. )";
  5698. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5699. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5700. EXPECT_THAT(getDiagnosticString(),
  5701. HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
  5702. "Workgroup, CrossWorkgroup, Generic, Image or "
  5703. "StorageBuffer storage classes."));
  5704. }
  5705. TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemorySizedAvailable) {
  5706. std::string spirv = R"(
  5707. OpCapability Shader
  5708. OpCapability Linkage
  5709. OpCapability Addresses
  5710. OpCapability VulkanMemoryModelKHR
  5711. OpExtension "SPV_KHR_vulkan_memory_model"
  5712. OpMemoryModel Logical VulkanKHR
  5713. %1 = OpTypeVoid
  5714. %2 = OpTypeInt 32 0
  5715. %3 = OpTypePointer Workgroup %2
  5716. %4 = OpVariable %3 Workgroup
  5717. %5 = OpTypePointer Uniform %2
  5718. %6 = OpVariable %5 Uniform
  5719. %7 = OpConstant %2 2
  5720. %8 = OpConstant %2 5
  5721. %9 = OpTypeFunction %1
  5722. %10 = OpFunction %1 None %9
  5723. %11 = OpLabel
  5724. OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR|MakePointerAvailableKHR %7
  5725. OpReturn
  5726. OpFunctionEnd
  5727. )";
  5728. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5729. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5730. }
  5731. TEST_F(ValidateIdWithMessage, VulkanMemoryModelCopyMemorySizedVisible) {
  5732. std::string spirv = R"(
  5733. OpCapability Shader
  5734. OpCapability Linkage
  5735. OpCapability Addresses
  5736. OpCapability VulkanMemoryModelKHR
  5737. OpExtension "SPV_KHR_vulkan_memory_model"
  5738. OpMemoryModel Logical VulkanKHR
  5739. %1 = OpTypeVoid
  5740. %2 = OpTypeInt 32 0
  5741. %3 = OpTypePointer Workgroup %2
  5742. %4 = OpVariable %3 Workgroup
  5743. %5 = OpTypePointer Uniform %2
  5744. %6 = OpVariable %5 Uniform
  5745. %7 = OpConstant %2 2
  5746. %8 = OpConstant %2 5
  5747. %9 = OpTypeFunction %1
  5748. %10 = OpFunction %1 None %9
  5749. %11 = OpLabel
  5750. OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR|MakePointerVisibleKHR %8
  5751. OpReturn
  5752. OpFunctionEnd
  5753. )";
  5754. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5755. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5756. }
  5757. TEST_F(ValidateIdWithMessage,
  5758. VulkanMemoryModelCopyMemorySizedAvailableAndVisible) {
  5759. std::string spirv = R"(
  5760. OpCapability Shader
  5761. OpCapability Linkage
  5762. OpCapability Addresses
  5763. OpCapability VulkanMemoryModelKHR
  5764. OpExtension "SPV_KHR_vulkan_memory_model"
  5765. OpMemoryModel Logical VulkanKHR
  5766. %1 = OpTypeVoid
  5767. %2 = OpTypeInt 32 0
  5768. %3 = OpTypePointer Workgroup %2
  5769. %4 = OpVariable %3 Workgroup
  5770. %5 = OpTypePointer Uniform %2
  5771. %6 = OpVariable %5 Uniform
  5772. %7 = OpConstant %2 2
  5773. %8 = OpConstant %2 5
  5774. %9 = OpTypeFunction %1
  5775. %10 = OpFunction %1 None %9
  5776. %11 = OpLabel
  5777. OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR|MakePointerAvailableKHR|MakePointerVisibleKHR %7 %8
  5778. OpReturn
  5779. OpFunctionEnd
  5780. )";
  5781. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5782. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5783. }
  5784. TEST_F(ValidateIdWithMessage,
  5785. VulkanMemoryModelCopyMemorySizedAvailableMissingNonPrivatePointer) {
  5786. std::string spirv = R"(
  5787. OpCapability Shader
  5788. OpCapability Linkage
  5789. OpCapability Addresses
  5790. OpCapability VulkanMemoryModelKHR
  5791. OpExtension "SPV_KHR_vulkan_memory_model"
  5792. OpMemoryModel Logical VulkanKHR
  5793. %1 = OpTypeVoid
  5794. %2 = OpTypeInt 32 0
  5795. %3 = OpTypePointer Workgroup %2
  5796. %4 = OpVariable %3 Workgroup
  5797. %5 = OpTypePointer Uniform %2
  5798. %6 = OpVariable %5 Uniform
  5799. %7 = OpConstant %2 2
  5800. %8 = OpConstant %2 5
  5801. %9 = OpTypeFunction %1
  5802. %10 = OpFunction %1 None %9
  5803. %11 = OpLabel
  5804. OpCopyMemorySized %4 %6 %7 MakePointerAvailableKHR %7
  5805. OpReturn
  5806. OpFunctionEnd
  5807. )";
  5808. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5809. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5810. EXPECT_THAT(getDiagnosticString(),
  5811. HasSubstr("NonPrivatePointerKHR must be specified if "
  5812. "MakePointerAvailableKHR is specified."));
  5813. }
  5814. TEST_F(ValidateIdWithMessage,
  5815. VulkanMemoryModelCopyMemorySizedVisibleMissingNonPrivatePointer) {
  5816. std::string spirv = R"(
  5817. OpCapability Shader
  5818. OpCapability Linkage
  5819. OpCapability Addresses
  5820. OpCapability VulkanMemoryModelKHR
  5821. OpExtension "SPV_KHR_vulkan_memory_model"
  5822. OpMemoryModel Logical VulkanKHR
  5823. %1 = OpTypeVoid
  5824. %2 = OpTypeInt 32 0
  5825. %3 = OpTypePointer Workgroup %2
  5826. %4 = OpVariable %3 Workgroup
  5827. %5 = OpTypePointer Uniform %2
  5828. %6 = OpVariable %5 Uniform
  5829. %7 = OpConstant %2 2
  5830. %8 = OpConstant %2 5
  5831. %9 = OpTypeFunction %1
  5832. %10 = OpFunction %1 None %9
  5833. %11 = OpLabel
  5834. OpCopyMemorySized %4 %6 %7 MakePointerVisibleKHR %8
  5835. OpReturn
  5836. OpFunctionEnd
  5837. )";
  5838. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5839. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5840. EXPECT_THAT(getDiagnosticString(),
  5841. HasSubstr("NonPrivatePointerKHR must be specified if "
  5842. "MakePointerVisibleKHR is specified."));
  5843. }
  5844. TEST_F(ValidateIdWithMessage,
  5845. VulkanMemoryModelCopyMemorySizedAvailableBadStorageClass) {
  5846. std::string spirv = R"(
  5847. OpCapability Shader
  5848. OpCapability Linkage
  5849. OpCapability Addresses
  5850. OpCapability VulkanMemoryModelKHR
  5851. OpExtension "SPV_KHR_vulkan_memory_model"
  5852. OpMemoryModel Logical VulkanKHR
  5853. %1 = OpTypeVoid
  5854. %2 = OpTypeInt 32 0
  5855. %3 = OpTypePointer Output %2
  5856. %4 = OpVariable %3 Output
  5857. %5 = OpTypePointer Uniform %2
  5858. %6 = OpVariable %5 Uniform
  5859. %7 = OpConstant %2 2
  5860. %8 = OpConstant %2 5
  5861. %9 = OpTypeFunction %1
  5862. %10 = OpFunction %1 None %9
  5863. %11 = OpLabel
  5864. OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR
  5865. OpReturn
  5866. OpFunctionEnd
  5867. )";
  5868. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5869. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5870. EXPECT_THAT(getDiagnosticString(),
  5871. HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
  5872. "Workgroup, CrossWorkgroup, Generic, Image or "
  5873. "StorageBuffer storage classes."));
  5874. }
  5875. TEST_F(ValidateIdWithMessage,
  5876. VulkanMemoryModelCopyMemorySizedVisibleBadStorageClass) {
  5877. std::string spirv = R"(
  5878. OpCapability Shader
  5879. OpCapability Linkage
  5880. OpCapability Addresses
  5881. OpCapability VulkanMemoryModelKHR
  5882. OpExtension "SPV_KHR_vulkan_memory_model"
  5883. OpMemoryModel Logical VulkanKHR
  5884. %1 = OpTypeVoid
  5885. %2 = OpTypeInt 32 0
  5886. %3 = OpTypePointer Workgroup %2
  5887. %4 = OpVariable %3 Workgroup
  5888. %5 = OpTypePointer Input %2
  5889. %6 = OpVariable %5 Input
  5890. %7 = OpConstant %2 2
  5891. %8 = OpConstant %2 5
  5892. %9 = OpTypeFunction %1
  5893. %10 = OpFunction %1 None %9
  5894. %11 = OpLabel
  5895. OpCopyMemorySized %4 %6 %7 NonPrivatePointerKHR
  5896. OpReturn
  5897. OpFunctionEnd
  5898. )";
  5899. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5900. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5901. EXPECT_THAT(getDiagnosticString(),
  5902. HasSubstr("NonPrivatePointerKHR requires a pointer in Uniform, "
  5903. "Workgroup, CrossWorkgroup, Generic, Image or "
  5904. "StorageBuffer storage classes."));
  5905. }
  5906. TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock1) {
  5907. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  5908. %1 = OpTypeVoid
  5909. %2 = OpTypeFunction %1
  5910. %3 = OpTypeFloat 32
  5911. %4 = OpTypeFunction %3
  5912. %5 = OpFunction %1 None %2
  5913. %6 = OpLabel
  5914. OpReturn
  5915. %7 = OpLabel
  5916. %8 = OpFunctionCall %3 %9
  5917. OpUnreachable
  5918. OpFunctionEnd
  5919. %9 = OpFunction %3 None %4
  5920. %10 = OpLabel
  5921. OpReturnValue %8
  5922. OpFunctionEnd
  5923. )";
  5924. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5925. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5926. EXPECT_THAT(getDiagnosticString(),
  5927. HasSubstr("ID 8[%8] defined in block 7[%7] does not dominate its "
  5928. "use in block 10[%10]\n %10 = OpLabel"));
  5929. }
  5930. TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock2) {
  5931. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  5932. %1 = OpTypeVoid
  5933. %2 = OpTypeFunction %1
  5934. %3 = OpTypeFloat 32
  5935. %4 = OpTypeFunction %3
  5936. %5 = OpFunction %1 None %2
  5937. %6 = OpLabel
  5938. OpReturn
  5939. %7 = OpLabel
  5940. %8 = OpFunctionCall %3 %9
  5941. OpUnreachable
  5942. OpFunctionEnd
  5943. %9 = OpFunction %3 None %4
  5944. %10 = OpLabel
  5945. OpReturnValue %8
  5946. OpFunctionEnd
  5947. )";
  5948. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5949. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5950. EXPECT_THAT(getDiagnosticString(),
  5951. HasSubstr("ID 8[%8] defined in block 7[%7] does not dominate its "
  5952. "use in block 10[%10]\n %10 = OpLabel"));
  5953. }
  5954. TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock3) {
  5955. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  5956. %1 = OpTypeVoid
  5957. %2 = OpTypeFunction %1
  5958. %3 = OpTypeFloat 32
  5959. %4 = OpTypeFunction %3
  5960. %5 = OpFunction %1 None %2
  5961. %6 = OpLabel
  5962. OpReturn
  5963. %7 = OpLabel
  5964. %8 = OpFunctionCall %3 %9
  5965. OpReturn
  5966. OpFunctionEnd
  5967. %9 = OpFunction %3 None %4
  5968. %10 = OpLabel
  5969. OpReturnValue %8
  5970. OpFunctionEnd
  5971. )";
  5972. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5973. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5974. EXPECT_THAT(getDiagnosticString(),
  5975. HasSubstr("ID 8[%8] defined in block 7[%7] does not dominate its "
  5976. "use in block 10[%10]\n %10 = OpLabel"));
  5977. }
  5978. TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock4) {
  5979. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  5980. %1 = OpTypeVoid
  5981. %2 = OpTypeFunction %1
  5982. %3 = OpTypeFloat 32
  5983. %4 = OpTypeFunction %3
  5984. %5 = OpFunction %1 None %2
  5985. %6 = OpLabel
  5986. OpReturn
  5987. %7 = OpLabel
  5988. %8 = OpUndef %3
  5989. %9 = OpCopyObject %3 %8
  5990. OpReturn
  5991. OpFunctionEnd
  5992. )";
  5993. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  5994. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  5995. }
  5996. TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock5) {
  5997. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  5998. %1 = OpTypeVoid
  5999. %2 = OpTypeFunction %1
  6000. %3 = OpTypeFloat 32
  6001. %4 = OpTypeFunction %3
  6002. %5 = OpFunction %1 None %2
  6003. %6 = OpLabel
  6004. OpReturn
  6005. %7 = OpLabel
  6006. %8 = OpUndef %3
  6007. OpBranch %9
  6008. %9 = OpLabel
  6009. %10 = OpCopyObject %3 %8
  6010. OpReturn
  6011. OpFunctionEnd
  6012. )";
  6013. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6014. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6015. }
  6016. TEST_F(ValidateIdWithMessage, IdDefInUnreachableBlock6) {
  6017. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  6018. %1 = OpTypeVoid
  6019. %2 = OpTypeFunction %1
  6020. %3 = OpTypeFloat 32
  6021. %4 = OpTypeFunction %3
  6022. %5 = OpFunction %1 None %2
  6023. %6 = OpLabel
  6024. OpBranch %7
  6025. %8 = OpLabel
  6026. %9 = OpUndef %3
  6027. OpBranch %7
  6028. %7 = OpLabel
  6029. %10 = OpCopyObject %3 %9
  6030. OpReturn
  6031. OpFunctionEnd
  6032. )";
  6033. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6034. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6035. EXPECT_THAT(getDiagnosticString(),
  6036. HasSubstr("ID 9[%9] defined in block 8[%8] does not dominate its "
  6037. "use in block 7[%7]\n %7 = OpLabel"));
  6038. }
  6039. TEST_F(ValidateIdWithMessage, ReachableDefUnreachableUse) {
  6040. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  6041. %1 = OpTypeVoid
  6042. %2 = OpTypeFunction %1
  6043. %3 = OpTypeFloat 32
  6044. %4 = OpTypeFunction %3
  6045. %5 = OpFunction %1 None %2
  6046. %6 = OpLabel
  6047. %7 = OpUndef %3
  6048. OpReturn
  6049. %8 = OpLabel
  6050. %9 = OpCopyObject %3 %7
  6051. OpReturn
  6052. OpFunctionEnd
  6053. )";
  6054. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6055. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6056. }
  6057. TEST_F(ValidateIdWithMessage, UnreachableDefUsedInPhi) {
  6058. const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
  6059. %void = OpTypeVoid
  6060. %3 = OpTypeFunction %void
  6061. %float = OpTypeFloat 32
  6062. %bool = OpTypeBool
  6063. %6 = OpTypeFunction %float
  6064. %1 = OpFunction %void None %3
  6065. %7 = OpLabel
  6066. %8 = OpUndef %bool
  6067. OpSelectionMerge %9 None
  6068. OpBranchConditional %8 %10 %9
  6069. %10 = OpLabel
  6070. %11 = OpUndef %float
  6071. OpBranch %9
  6072. %12 = OpLabel
  6073. %13 = OpUndef %float
  6074. OpUnreachable
  6075. %9 = OpLabel
  6076. %14 = OpPhi %float %11 %10 %13 %7
  6077. OpReturn
  6078. OpFunctionEnd
  6079. )";
  6080. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6081. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6082. EXPECT_THAT(
  6083. getDiagnosticString(),
  6084. HasSubstr("In OpPhi instruction 14[%14], ID 13[%13] definition does not "
  6085. "dominate its parent 7[%7]\n %14 = OpPhi %float %11 %10 %13 "
  6086. "%7"));
  6087. }
  6088. TEST_F(ValidateIdWithMessage, OpTypeForwardPointerNotAPointerType) {
  6089. std::string spirv = R"(
  6090. OpCapability GenericPointer
  6091. OpCapability VariablePointersStorageBuffer
  6092. OpMemoryModel Logical GLSL450
  6093. OpEntryPoint Fragment %1 "main"
  6094. OpExecutionMode %1 OriginLowerLeft
  6095. OpTypeForwardPointer %2 CrossWorkgroup
  6096. %2 = OpTypeVoid
  6097. %3 = OpTypeFunction %2
  6098. %1 = OpFunction %2 DontInline %3
  6099. %4 = OpLabel
  6100. OpReturn
  6101. OpFunctionEnd
  6102. )";
  6103. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6104. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6105. EXPECT_THAT(getDiagnosticString(),
  6106. HasSubstr("Pointer type in OpTypeForwardPointer is not a pointer "
  6107. "type.\n OpTypeForwardPointer %void CrossWorkgroup"));
  6108. }
  6109. TEST_F(ValidateIdWithMessage, OpTypeForwardPointerWrongStorageClass) {
  6110. std::string spirv = R"(
  6111. OpCapability GenericPointer
  6112. OpCapability VariablePointersStorageBuffer
  6113. OpMemoryModel Logical GLSL450
  6114. OpEntryPoint Fragment %1 "main"
  6115. OpExecutionMode %1 OriginLowerLeft
  6116. OpTypeForwardPointer %2 CrossWorkgroup
  6117. %int = OpTypeInt 32 1
  6118. %2 = OpTypePointer Function %int
  6119. %void = OpTypeVoid
  6120. %3 = OpTypeFunction %void
  6121. %1 = OpFunction %void None %3
  6122. %4 = OpLabel
  6123. OpReturn
  6124. OpFunctionEnd
  6125. )";
  6126. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6127. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6128. EXPECT_THAT(
  6129. getDiagnosticString(),
  6130. HasSubstr("Storage class in OpTypeForwardPointer does not match the "
  6131. "pointer definition.\n OpTypeForwardPointer "
  6132. "%_ptr_Function_int CrossWorkgroup"));
  6133. }
  6134. TEST_F(ValidateIdWithMessage, MissingForwardPointer) {
  6135. const std::string spirv = R"(
  6136. OpCapability Linkage
  6137. OpCapability Shader
  6138. OpMemoryModel Logical Simple
  6139. %float = OpTypeFloat 32
  6140. %_struct_9 = OpTypeStruct %float %_ptr_Uniform__struct_9
  6141. %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
  6142. %1278 = OpVariable %_ptr_Uniform__struct_9 Uniform
  6143. )";
  6144. CompileSuccessfully(spirv);
  6145. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6146. EXPECT_THAT(
  6147. getDiagnosticString(),
  6148. HasSubstr(
  6149. "Operand 3[%_ptr_Uniform__struct_2] requires a previous definition"));
  6150. }
  6151. } // namespace
  6152. } // namespace val
  6153. } // namespace spvtools