val_memory_test.cpp 272 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583
  1. // Copyright (c) 2018 Google Inc.
  2. // Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
  3. // reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Validation tests for memory/storage
  17. #include <string>
  18. #include <vector>
  19. #include "gmock/gmock.h"
  20. #include "test/unit_spirv.h"
  21. #include "test/val/val_code_generator.h"
  22. #include "test/val/val_fixtures.h"
  23. // For pretty-printing tuples with spv_target_env.
  24. std::ostream& operator<<(std::ostream& stream, spv_target_env target) {
  25. switch (target) {
  26. case SPV_ENV_UNIVERSAL_1_3:
  27. return stream << "SPV_ENV_UNIVERSAL_1_3";
  28. case SPV_ENV_UNIVERSAL_1_4:
  29. return stream << "SPV_ENV_UNIVERSAL_1_4";
  30. default:
  31. return stream << (unsigned)target;
  32. }
  33. }
  34. namespace spvtools {
  35. namespace val {
  36. namespace {
  37. using ::testing::Combine;
  38. using ::testing::Eq;
  39. using ::testing::HasSubstr;
  40. using ::testing::Values;
  41. using ValidateMemory = spvtest::ValidateBase<bool>;
  42. TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceBad) {
  43. std::string spirv = R"(
  44. OpCapability Shader
  45. OpMemoryModel Logical GLSL450
  46. OpEntryPoint Fragment %func "func"
  47. OpExecutionMode %func OriginUpperLeft
  48. %float = OpTypeFloat 32
  49. %float_ptr = OpTypePointer UniformConstant %float
  50. %2 = OpVariable %float_ptr UniformConstant
  51. %void = OpTypeVoid
  52. %functy = OpTypeFunction %void
  53. %func = OpFunction %void None %functy
  54. %1 = OpLabel
  55. OpReturn
  56. OpFunctionEnd
  57. )";
  58. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  59. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  60. EXPECT_THAT(getDiagnosticString(),
  61. AnyVUID("VUID-StandaloneSpirv-UniformConstant-04655"));
  62. EXPECT_THAT(
  63. getDiagnosticString(),
  64. HasSubstr("Variables identified with the UniformConstant storage class "
  65. "are used only as handles to refer to opaque resources. Such "
  66. "variables must be typed as OpTypeImage, OpTypeSampler, "
  67. "OpTypeSampledImage, OpTypeAccelerationStructureKHR, "
  68. "or an array of one of these types."));
  69. }
  70. TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceGood) {
  71. std::string spirv = R"(
  72. OpCapability Shader
  73. OpMemoryModel Logical GLSL450
  74. OpEntryPoint Fragment %func "func"
  75. OpExecutionMode %func OriginUpperLeft
  76. OpDecorate %2 DescriptorSet 0
  77. OpDecorate %2 Binding 0
  78. %sampler = OpTypeSampler
  79. %sampler_ptr = OpTypePointer UniformConstant %sampler
  80. %2 = OpVariable %sampler_ptr UniformConstant
  81. %void = OpTypeVoid
  82. %functy = OpTypeFunction %void
  83. %func = OpFunction %void None %functy
  84. %1 = OpLabel
  85. OpReturn
  86. OpFunctionEnd
  87. )";
  88. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  89. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  90. }
  91. TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceArrayBad) {
  92. std::string spirv = R"(
  93. OpCapability Shader
  94. OpMemoryModel Logical GLSL450
  95. OpEntryPoint Fragment %func "func"
  96. OpExecutionMode %func OriginUpperLeft
  97. %float = OpTypeFloat 32
  98. %uint = OpTypeInt 32 0
  99. %array_size = OpConstant %uint 5
  100. %array = OpTypeArray %float %array_size
  101. %array_ptr = OpTypePointer UniformConstant %array
  102. %2 = OpVariable %array_ptr UniformConstant
  103. %void = OpTypeVoid
  104. %functy = OpTypeFunction %void
  105. %func = OpFunction %void None %functy
  106. %1 = OpLabel
  107. OpReturn
  108. OpFunctionEnd
  109. )";
  110. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  111. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  112. EXPECT_THAT(getDiagnosticString(),
  113. AnyVUID("VUID-StandaloneSpirv-UniformConstant-04655"));
  114. EXPECT_THAT(
  115. getDiagnosticString(),
  116. HasSubstr("Variables identified with the UniformConstant storage class "
  117. "are used only as handles to refer to opaque resources. Such "
  118. "variables must be typed as OpTypeImage, OpTypeSampler, "
  119. "OpTypeSampledImage, OpTypeAccelerationStructureKHR, "
  120. "or an array of one of these types."));
  121. }
  122. TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceArrayGood) {
  123. std::string spirv = R"(
  124. OpCapability Shader
  125. OpMemoryModel Logical GLSL450
  126. OpEntryPoint Fragment %func "func"
  127. OpExecutionMode %func OriginUpperLeft
  128. OpDecorate %2 DescriptorSet 0
  129. OpDecorate %2 Binding 0
  130. %sampler = OpTypeSampler
  131. %uint = OpTypeInt 32 0
  132. %array_size = OpConstant %uint 5
  133. %array = OpTypeArray %sampler %array_size
  134. %array_ptr = OpTypePointer UniformConstant %array
  135. %2 = OpVariable %array_ptr UniformConstant
  136. %void = OpTypeVoid
  137. %functy = OpTypeFunction %void
  138. %func = OpFunction %void None %functy
  139. %1 = OpLabel
  140. OpReturn
  141. OpFunctionEnd
  142. )";
  143. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  144. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  145. }
  146. TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood) {
  147. std::string spirv = R"(
  148. OpCapability RuntimeDescriptorArrayEXT
  149. OpCapability Shader
  150. OpExtension "SPV_EXT_descriptor_indexing"
  151. OpMemoryModel Logical GLSL450
  152. OpEntryPoint Fragment %func "func"
  153. OpExecutionMode %func OriginUpperLeft
  154. OpDecorate %2 DescriptorSet 0
  155. OpDecorate %2 Binding 0
  156. %sampler = OpTypeSampler
  157. %uint = OpTypeInt 32 0
  158. %array = OpTypeRuntimeArray %sampler
  159. %array_ptr = OpTypePointer UniformConstant %array
  160. %2 = OpVariable %array_ptr UniformConstant
  161. %void = OpTypeVoid
  162. %functy = OpTypeFunction %void
  163. %func = OpFunction %void None %functy
  164. %1 = OpLabel
  165. OpReturn
  166. OpFunctionEnd
  167. )";
  168. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  169. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  170. }
  171. TEST_F(ValidateMemory, VulkanUniformOnIntBad) {
  172. char src[] = R"(
  173. OpCapability Shader
  174. OpMemoryModel Logical GLSL450
  175. OpEntryPoint GLCompute %kernel "main"
  176. OpExecutionMode %kernel LocalSize 1 1 1
  177. OpDecorate %var DescriptorSet 0
  178. OpDecorate %var Binding 0
  179. %voidty = OpTypeVoid
  180. %kernelty = OpTypeFunction %voidty
  181. %intty = OpTypeInt 32 0
  182. %varty = OpTypePointer Uniform %intty
  183. %value = OpConstant %intty 42
  184. %var = OpVariable %varty Uniform
  185. %kernel = OpFunction %voidty None %kernelty
  186. %label = OpLabel
  187. OpStore %var %value
  188. OpReturn
  189. OpFunctionEnd
  190. )";
  191. CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
  192. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  193. EXPECT_THAT(getDiagnosticString(),
  194. AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
  195. EXPECT_THAT(
  196. getDiagnosticString(),
  197. HasSubstr("From Vulkan spec:\n"
  198. "Variables identified with the Uniform storage class are used "
  199. "to access transparent buffer backed resources. Such variables "
  200. "must be typed as OpTypeStruct, or an array of this type"));
  201. }
  202. // #version 440
  203. // #extension GL_EXT_nonuniform_qualifier : enable
  204. // layout(binding = 1) uniform sampler2D s2d[][2];
  205. // layout(location = 0) in nonuniformEXT int i;
  206. // void main()
  207. // {
  208. // vec4 v = texture(s2d[i][i], vec2(0.3));
  209. // }
  210. TEST_F(ValidateMemory, VulkanUniformOnRuntimeArrayOfArrayBad) {
  211. char src[] = R"(
  212. OpCapability Shader
  213. OpCapability ShaderNonUniformEXT
  214. OpCapability RuntimeDescriptorArrayEXT
  215. OpCapability SampledImageArrayNonUniformIndexingEXT
  216. OpExtension "SPV_EXT_descriptor_indexing"
  217. %1 = OpExtInstImport "GLSL.std.450"
  218. OpMemoryModel Logical GLSL450
  219. OpEntryPoint Vertex %main "main" %i
  220. OpSource GLSL 440
  221. OpSourceExtension "GL_EXT_nonuniform_qualifier"
  222. OpName %main "main"
  223. OpName %v "v"
  224. OpName %s2d "s2d"
  225. OpName %i "i"
  226. OpDecorate %s2d DescriptorSet 0
  227. OpDecorate %s2d Binding 1
  228. OpDecorate %i Location 0
  229. OpDecorate %i NonUniformEXT
  230. OpDecorate %21 NonUniformEXT
  231. OpDecorate %22 NonUniformEXT
  232. OpDecorate %25 NonUniformEXT
  233. %void = OpTypeVoid
  234. %3 = OpTypeFunction %void
  235. %float = OpTypeFloat 32
  236. %v4float = OpTypeVector %float 4
  237. %_ptr_Function_v4float = OpTypePointer Function %v4float
  238. %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
  239. %11 = OpTypeSampledImage %10
  240. %uint = OpTypeInt 32 0
  241. %uint_2 = OpConstant %uint 2
  242. %_arr_11_uint_2 = OpTypeArray %11 %uint_2
  243. %_runtimearr__arr_11_uint_2 = OpTypeRuntimeArray %_arr_11_uint_2
  244. %_ptr_Uniform__runtimearr__arr_11_uint_2 = OpTypePointer Uniform %_runtimearr__arr_11_uint_2
  245. %s2d = OpVariable %_ptr_Uniform__runtimearr__arr_11_uint_2 Uniform
  246. %int = OpTypeInt 32 1
  247. %_ptr_Input_int = OpTypePointer Input %int
  248. %i = OpVariable %_ptr_Input_int Input
  249. %_ptr_Uniform_11 = OpTypePointer Uniform %11
  250. %v2float = OpTypeVector %float 2
  251. %float_0_300000012 = OpConstant %float 0.300000012
  252. %28 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
  253. %float_0 = OpConstant %float 0
  254. %main = OpFunction %void None %3
  255. %5 = OpLabel
  256. %v = OpVariable %_ptr_Function_v4float Function
  257. %21 = OpLoad %int %i
  258. %22 = OpLoad %int %i
  259. %24 = OpAccessChain %_ptr_Uniform_11 %s2d %21 %22
  260. %25 = OpLoad %11 %24
  261. %30 = OpImageSampleExplicitLod %v4float %25 %28 Lod %float_0
  262. OpStore %v %30
  263. OpReturn
  264. OpFunctionEnd
  265. )";
  266. CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
  267. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  268. EXPECT_THAT(getDiagnosticString(),
  269. AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
  270. EXPECT_THAT(
  271. getDiagnosticString(),
  272. HasSubstr("From Vulkan spec:\n"
  273. "Variables identified with the Uniform storage class are used "
  274. "to access transparent buffer backed resources. Such variables "
  275. "must be typed as OpTypeStruct, or an array of this type"));
  276. }
  277. // #version 440
  278. // layout (set=1, binding=1) uniform sampler2D variableName[2][2];
  279. // void main() {
  280. // }
  281. TEST_F(ValidateMemory, VulkanUniformOnArrayOfArrayBad) {
  282. char src[] = R"(
  283. OpCapability Shader
  284. %1 = OpExtInstImport "GLSL.std.450"
  285. OpMemoryModel Logical GLSL450
  286. OpEntryPoint Vertex %main "main"
  287. OpSource GLSL 440
  288. OpName %main "main"
  289. OpName %variableName "variableName"
  290. OpDecorate %variableName DescriptorSet 1
  291. OpDecorate %variableName Binding 1
  292. %void = OpTypeVoid
  293. %3 = OpTypeFunction %void
  294. %float = OpTypeFloat 32
  295. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  296. %8 = OpTypeSampledImage %7
  297. %uint = OpTypeInt 32 0
  298. %uint_2 = OpConstant %uint 2
  299. %_arr_8_uint_2 = OpTypeArray %8 %uint_2
  300. %_arr__arr_8_uint_2_uint_2 = OpTypeArray %_arr_8_uint_2 %uint_2
  301. %_ptr_Uniform__arr__arr_8_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_8_uint_2_uint_2
  302. %variableName = OpVariable %_ptr_Uniform__arr__arr_8_uint_2_uint_2 Uniform
  303. %main = OpFunction %void None %3
  304. %5 = OpLabel
  305. OpReturn
  306. OpFunctionEnd
  307. )";
  308. CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
  309. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  310. EXPECT_THAT(getDiagnosticString(),
  311. AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
  312. EXPECT_THAT(
  313. getDiagnosticString(),
  314. HasSubstr("From Vulkan spec:\n"
  315. "Variables identified with the Uniform storage class are used "
  316. "to access transparent buffer backed resources. Such variables "
  317. "must be typed as OpTypeStruct, or an array of this type"));
  318. }
  319. TEST_F(ValidateMemory, MismatchingStorageClassesBad) {
  320. std::string spirv = R"(
  321. OpCapability Shader
  322. OpMemoryModel Logical GLSL450
  323. OpEntryPoint Fragment %func "func"
  324. OpExecutionMode %func OriginUpperLeft
  325. %float = OpTypeFloat 32
  326. %float_ptr = OpTypePointer Uniform %float
  327. %void = OpTypeVoid
  328. %functy = OpTypeFunction %void
  329. %func = OpFunction %void None %functy
  330. %1 = OpLabel
  331. %2 = OpVariable %float_ptr Function
  332. OpReturn
  333. OpFunctionEnd
  334. )";
  335. CompileSuccessfully(spirv.c_str());
  336. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  337. EXPECT_THAT(getDiagnosticString(),
  338. HasSubstr("Storage class must match result type storage class"));
  339. }
  340. TEST_F(ValidateMemory, MatchingStorageClassesGood) {
  341. std::string spirv = R"(
  342. OpCapability Shader
  343. OpMemoryModel Logical GLSL450
  344. OpEntryPoint Fragment %func "func"
  345. OpExecutionMode %func OriginUpperLeft
  346. %float = OpTypeFloat 32
  347. %float_ptr = OpTypePointer Function %float
  348. %void = OpTypeVoid
  349. %functy = OpTypeFunction %void
  350. %func = OpFunction %void None %functy
  351. %1 = OpLabel
  352. %2 = OpVariable %float_ptr Function
  353. OpReturn
  354. OpFunctionEnd
  355. )";
  356. CompileSuccessfully(spirv.c_str());
  357. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  358. }
  359. TEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) {
  360. std::string spirv = R"(
  361. OpCapability Shader
  362. OpMemoryModel Logical GLSL450
  363. OpEntryPoint Fragment %func "func"
  364. OpExecutionMode %func OriginUpperLeft
  365. %float = OpTypeFloat 32
  366. %float_ptr = OpTypePointer Output %float
  367. %init_val = OpConstant %float 1.0
  368. %1 = OpVariable %float_ptr Output %init_val
  369. %void = OpTypeVoid
  370. %functy = OpTypeFunction %void
  371. %func = OpFunction %void None %functy
  372. %2 = OpLabel
  373. OpReturn
  374. OpFunctionEnd
  375. )";
  376. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  377. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  378. }
  379. TEST_F(ValidateMemory, VulkanInitializerWithFunctionStorageClassesGood) {
  380. std::string spirv = R"(
  381. OpCapability Shader
  382. OpMemoryModel Logical GLSL450
  383. OpEntryPoint Fragment %func "func"
  384. OpExecutionMode %func OriginUpperLeft
  385. %float = OpTypeFloat 32
  386. %float_ptr = OpTypePointer Function %float
  387. %init_val = OpConstant %float 1.0
  388. %void = OpTypeVoid
  389. %functy = OpTypeFunction %void
  390. %func = OpFunction %void None %functy
  391. %1 = OpLabel
  392. %2 = OpVariable %float_ptr Function %init_val
  393. OpReturn
  394. OpFunctionEnd
  395. )";
  396. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  397. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  398. }
  399. TEST_F(ValidateMemory, VulkanInitializerWithPrivateStorageClassesGood) {
  400. std::string spirv = R"(
  401. OpCapability Shader
  402. OpMemoryModel Logical GLSL450
  403. OpEntryPoint Fragment %func "func"
  404. OpExecutionMode %func OriginUpperLeft
  405. %float = OpTypeFloat 32
  406. %float_ptr = OpTypePointer Private %float
  407. %init_val = OpConstant %float 1.0
  408. %1 = OpVariable %float_ptr Private %init_val
  409. %void = OpTypeVoid
  410. %functy = OpTypeFunction %void
  411. %func = OpFunction %void None %functy
  412. %2 = OpLabel
  413. OpReturn
  414. OpFunctionEnd
  415. )";
  416. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  417. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  418. }
  419. TEST_F(ValidateMemory, VulkanInitializerWithDisallowedStorageClassesBad) {
  420. std::string spirv = R"(
  421. OpCapability Shader
  422. OpMemoryModel Logical GLSL450
  423. OpEntryPoint Fragment %func "func"
  424. OpExecutionMode %func OriginUpperLeft
  425. %float = OpTypeFloat 32
  426. %float_ptr = OpTypePointer Input %float
  427. %init_val = OpConstant %float 1.0
  428. %1 = OpVariable %float_ptr Input %init_val
  429. %void = OpTypeVoid
  430. %functy = OpTypeFunction %void
  431. %func = OpFunction %void None %functy
  432. %2 = OpLabel
  433. OpReturn
  434. OpFunctionEnd
  435. )";
  436. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  437. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  438. EXPECT_THAT(getDiagnosticString(),
  439. AnyVUID("VUID-StandaloneSpirv-OpVariable-04651"));
  440. EXPECT_THAT(
  441. getDiagnosticString(),
  442. HasSubstr("OpVariable, <id> '5[%5]', has a disallowed initializer & "
  443. "storage class combination.\nFrom Vulkan spec:\nVariable "
  444. "declarations that include initializers must have one of the "
  445. "following storage classes: Output, Private, Function or "
  446. "Workgroup\n %5 "
  447. "= OpVariable %_ptr_Input_float Input %float_1\n"));
  448. }
  449. TEST_F(ValidateMemory, UniversalInitializerWithDisallowedStorageClassesBad) {
  450. std::string spirv = R"(
  451. OpCapability Shader
  452. OpMemoryModel Logical GLSL450
  453. OpEntryPoint Fragment %func "func"
  454. OpExecutionMode %func OriginUpperLeft
  455. %float = OpTypeFloat 32
  456. %float_ptr = OpTypePointer Input %float
  457. %init_val = OpConstant %float 1.0
  458. %1 = OpVariable %float_ptr Input %init_val
  459. %void = OpTypeVoid
  460. %functy = OpTypeFunction %void
  461. %func = OpFunction %void None %functy
  462. %2 = OpLabel
  463. OpReturn
  464. OpFunctionEnd
  465. )";
  466. CompileSuccessfully(spirv.c_str(), SPV_ENV_UNIVERSAL_1_3);
  467. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  468. EXPECT_THAT(
  469. getDiagnosticString(),
  470. HasSubstr(
  471. "OpVariable, <id> '5[%5]', initializer are not allowed for Input"));
  472. }
  473. TEST_F(ValidateMemory, InitializerWithTaskPayloadWorkgroupEXT) {
  474. std::string spirv = R"(
  475. OpCapability MeshShadingEXT
  476. OpExtension "SPV_EXT_mesh_shader"
  477. OpMemoryModel Logical GLSL450
  478. OpEntryPoint TaskEXT %main "main" %payload
  479. %void = OpTypeVoid
  480. %func = OpTypeFunction %void
  481. %uint = OpTypeInt 32 0
  482. %_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
  483. %uint_1 = OpConstant %uint 1
  484. %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT %uint_1
  485. %main = OpFunction %void None %func
  486. %label = OpLabel
  487. OpReturn
  488. OpFunctionEnd
  489. )";
  490. CompileSuccessfully(spirv.c_str(), SPV_ENV_UNIVERSAL_1_5);
  491. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  492. EXPECT_THAT(getDiagnosticString(),
  493. HasSubstr("OpVariable, <id> '2[%2]', initializer are not allowed "
  494. "for TaskPayloadWorkgroupEXT"));
  495. }
  496. TEST_F(ValidateMemory, ArrayLenCorrectResultType) {
  497. std::string spirv = R"(
  498. OpCapability Shader
  499. OpMemoryModel Logical GLSL450
  500. OpEntryPoint Fragment %1 "main"
  501. OpExecutionMode %1 OriginUpperLeft
  502. %void = OpTypeVoid
  503. %3 = OpTypeFunction %void
  504. %float = OpTypeFloat 32
  505. %uint = OpTypeInt 32 0
  506. %_runtimearr_float = OpTypeRuntimeArray %float
  507. %_struct_7 = OpTypeStruct %_runtimearr_float
  508. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  509. %1 = OpFunction %void None %3
  510. %9 = OpLabel
  511. %10 = OpVariable %_ptr_Function__struct_7 Function
  512. %11 = OpArrayLength %uint %10 0
  513. OpReturn
  514. OpFunctionEnd
  515. )";
  516. CompileSuccessfully(spirv.c_str());
  517. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  518. }
  519. TEST_F(ValidateMemory, ArrayLenIndexCorrectWith2Members) {
  520. std::string spirv = R"(
  521. OpCapability Shader
  522. OpMemoryModel Logical GLSL450
  523. OpEntryPoint Fragment %1 "main"
  524. OpExecutionMode %1 OriginUpperLeft
  525. %void = OpTypeVoid
  526. %3 = OpTypeFunction %void
  527. %float = OpTypeFloat 32
  528. %uint = OpTypeInt 32 0
  529. %_runtimearr_float = OpTypeRuntimeArray %float
  530. %_struct_7 = OpTypeStruct %float %_runtimearr_float
  531. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  532. %1 = OpFunction %void None %3
  533. %9 = OpLabel
  534. %10 = OpVariable %_ptr_Function__struct_7 Function
  535. %11 = OpArrayLength %uint %10 1
  536. OpReturn
  537. OpFunctionEnd
  538. )";
  539. CompileSuccessfully(spirv.c_str());
  540. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  541. }
  542. TEST_F(ValidateMemory, ArrayLenResultNotIntType) {
  543. std::string spirv = R"(
  544. OpCapability Shader
  545. OpMemoryModel Logical GLSL450
  546. OpEntryPoint Fragment %1 "main"
  547. OpExecutionMode %1 OriginUpperLeft
  548. %void = OpTypeVoid
  549. %3 = OpTypeFunction %void
  550. %float = OpTypeFloat 32
  551. %_runtimearr_float = OpTypeRuntimeArray %float
  552. %_struct_6 = OpTypeStruct %_runtimearr_float
  553. %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
  554. %1 = OpFunction %void None %3
  555. %8 = OpLabel
  556. %9 = OpVariable %_ptr_Function__struct_6 Function
  557. %10 = OpArrayLength %float %9 0
  558. OpReturn
  559. OpFunctionEnd
  560. )";
  561. CompileSuccessfully(spirv.c_str());
  562. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  563. EXPECT_THAT(
  564. getDiagnosticString(),
  565. HasSubstr(
  566. "The Result Type of OpArrayLength <id> '10[%10]' must be OpTypeInt "
  567. "with width 32 and signedness 0.\n %10 = OpArrayLength %float %9 "
  568. "0\n"));
  569. }
  570. TEST_F(ValidateMemory, ArrayLenResultNot32bits) {
  571. std::string spirv = R"(
  572. OpCapability Shader
  573. OpCapability Int16
  574. OpMemoryModel Logical GLSL450
  575. OpEntryPoint Fragment %1 "main"
  576. OpExecutionMode %1 OriginUpperLeft
  577. %void = OpTypeVoid
  578. %3 = OpTypeFunction %void
  579. %float = OpTypeFloat 32
  580. %ushort = OpTypeInt 16 0
  581. %_runtimearr_float = OpTypeRuntimeArray %float
  582. %_struct_7 = OpTypeStruct %_runtimearr_float
  583. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  584. %1 = OpFunction %void None %3
  585. %9 = OpLabel
  586. %10 = OpVariable %_ptr_Function__struct_7 Function
  587. %11 = OpArrayLength %ushort %10 0
  588. OpReturn
  589. OpFunctionEnd
  590. )";
  591. CompileSuccessfully(spirv.c_str());
  592. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  593. EXPECT_THAT(
  594. getDiagnosticString(),
  595. HasSubstr(
  596. "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
  597. "with width 32 and signedness 0.\n %11 = OpArrayLength %ushort %10 "
  598. "0\n"));
  599. }
  600. TEST_F(ValidateMemory, ArrayLenResultSigned) {
  601. std::string spirv = R"(
  602. OpCapability Shader
  603. OpMemoryModel Logical GLSL450
  604. OpEntryPoint Fragment %1 "main"
  605. OpExecutionMode %1 OriginUpperLeft
  606. %void = OpTypeVoid
  607. %3 = OpTypeFunction %void
  608. %float = OpTypeFloat 32
  609. %int = OpTypeInt 32 1
  610. %_runtimearr_float = OpTypeRuntimeArray %float
  611. %_struct_7 = OpTypeStruct %_runtimearr_float
  612. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  613. %1 = OpFunction %void None %3
  614. %9 = OpLabel
  615. %10 = OpVariable %_ptr_Function__struct_7 Function
  616. %11 = OpArrayLength %int %10 0
  617. OpReturn
  618. OpFunctionEnd
  619. )";
  620. CompileSuccessfully(spirv.c_str());
  621. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  622. EXPECT_THAT(
  623. getDiagnosticString(),
  624. HasSubstr(
  625. "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
  626. "with width 32 and signedness 0.\n %11 = OpArrayLength %int %10 "
  627. "0\n"));
  628. }
  629. TEST_F(ValidateMemory, ArrayLenInputNotStruct) {
  630. std::string spirv = R"(
  631. OpCapability Shader
  632. OpMemoryModel Logical GLSL450
  633. OpEntryPoint Fragment %1 "main"
  634. OpExecutionMode %1 OriginUpperLeft
  635. %void = OpTypeVoid
  636. %3 = OpTypeFunction %void
  637. %float = OpTypeFloat 32
  638. %uint = OpTypeInt 32 0
  639. %_runtimearr_float = OpTypeRuntimeArray %float
  640. %_struct_7 = OpTypeStruct %_runtimearr_float
  641. %_ptr_Function_float = OpTypePointer Function %float
  642. %1 = OpFunction %void None %3
  643. %9 = OpLabel
  644. %10 = OpVariable %_ptr_Function_float Function
  645. %11 = OpArrayLength %uint %10 0
  646. OpReturn
  647. OpFunctionEnd
  648. )";
  649. CompileSuccessfully(spirv.c_str());
  650. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  651. EXPECT_THAT(getDiagnosticString(),
  652. HasSubstr("The Structure's type in OpArrayLength <id> '11[%11]' "
  653. "must be a pointer to an OpTypeStruct."));
  654. }
  655. TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA) {
  656. std::string spirv = R"(
  657. OpCapability Shader
  658. OpMemoryModel Logical GLSL450
  659. OpEntryPoint Fragment %1 "main"
  660. OpExecutionMode %1 OriginUpperLeft
  661. %void = OpTypeVoid
  662. %3 = OpTypeFunction %void
  663. %float = OpTypeFloat 32
  664. %uint = OpTypeInt 32 0
  665. %_runtimearr_float = OpTypeRuntimeArray %float
  666. %_struct_7 = OpTypeStruct %float
  667. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  668. %1 = OpFunction %void None %3
  669. %9 = OpLabel
  670. %10 = OpVariable %_ptr_Function__struct_7 Function
  671. %11 = OpArrayLength %uint %10 0
  672. OpReturn
  673. OpFunctionEnd
  674. )";
  675. CompileSuccessfully(spirv.c_str());
  676. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  677. EXPECT_THAT(
  678. getDiagnosticString(),
  679. HasSubstr("The Structure's last member in OpArrayLength <id> '11[%11]' "
  680. "must be an OpTypeRuntimeArray.\n %11 = OpArrayLength %uint "
  681. "%10 0\n"));
  682. }
  683. TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA2) {
  684. std::string spirv = R"(
  685. OpCapability Shader
  686. OpMemoryModel Logical GLSL450
  687. OpEntryPoint Fragment %1 "main"
  688. OpExecutionMode %1 OriginUpperLeft
  689. %void = OpTypeVoid
  690. %3 = OpTypeFunction %void
  691. %float = OpTypeFloat 32
  692. %uint = OpTypeInt 32 0
  693. %_runtimearr_float = OpTypeRuntimeArray %float
  694. %_struct_7 = OpTypeStruct %_runtimearr_float %float
  695. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  696. %1 = OpFunction %void None %3
  697. %9 = OpLabel
  698. %10 = OpVariable %_ptr_Function__struct_7 Function
  699. %11 = OpArrayLength %uint %10 1
  700. OpReturn
  701. OpFunctionEnd
  702. )";
  703. CompileSuccessfully(spirv.c_str());
  704. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  705. EXPECT_THAT(
  706. getDiagnosticString(),
  707. HasSubstr("The Structure's last member in OpArrayLength <id> '11[%11]' "
  708. "must be an OpTypeRuntimeArray.\n %11 = OpArrayLength %uint "
  709. "%10 1\n"));
  710. }
  711. TEST_F(ValidateMemory, ArrayLenIndexNotLastMember) {
  712. std::string spirv = R"(
  713. OpCapability Shader
  714. OpMemoryModel Logical GLSL450
  715. OpEntryPoint Fragment %1 "main"
  716. OpExecutionMode %1 OriginUpperLeft
  717. %void = OpTypeVoid
  718. %3 = OpTypeFunction %void
  719. %float = OpTypeFloat 32
  720. %uint = OpTypeInt 32 0
  721. %_runtimearr_float = OpTypeRuntimeArray %float
  722. %_struct_7 = OpTypeStruct %float %_runtimearr_float
  723. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  724. %1 = OpFunction %void None %3
  725. %9 = OpLabel
  726. %10 = OpVariable %_ptr_Function__struct_7 Function
  727. %11 = OpArrayLength %uint %10 0
  728. OpReturn
  729. OpFunctionEnd
  730. )";
  731. CompileSuccessfully(spirv.c_str());
  732. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  733. EXPECT_THAT(
  734. getDiagnosticString(),
  735. HasSubstr(
  736. "The array member in OpArrayLength <id> '11[%11]' must be the "
  737. "last member of the struct.\n %11 = OpArrayLength %uint %10 0\n"));
  738. }
  739. TEST_F(ValidateMemory, ArrayLenIndexNotPointerToStruct) {
  740. std::string spirv = R"(
  741. OpCapability Shader
  742. OpMemoryModel Logical GLSL450
  743. OpEntryPoint Fragment %1 "main"
  744. OpExecutionMode %1 OriginUpperLeft
  745. %void = OpTypeVoid
  746. %3 = OpTypeFunction %void
  747. %float = OpTypeFloat 32
  748. %uint = OpTypeInt 32 0
  749. %_runtimearr_float = OpTypeRuntimeArray %float
  750. %_struct_7 = OpTypeStruct %float
  751. %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
  752. %1 = OpFunction %void None %3
  753. %9 = OpLabel
  754. %10 = OpVariable %_ptr_Function__struct_7 Function
  755. %11 = OpLoad %_struct_7 %10
  756. %12 = OpArrayLength %uint %11 0
  757. OpReturn
  758. OpFunctionEnd
  759. )";
  760. CompileSuccessfully(spirv.c_str());
  761. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  762. EXPECT_THAT(
  763. getDiagnosticString(),
  764. HasSubstr(
  765. "The Structure's type in OpArrayLength <id> '12[%12]' must be a "
  766. "pointer to an OpTypeStruct.\n %12 = OpArrayLength %uint %11 0\n"));
  767. }
  768. TEST_F(ValidateMemory, ArrayLenPointerIsAType) {
  769. std::string spirv = R"(
  770. OpCapability Shader
  771. OpMemoryModel Logical GLSL450
  772. OpEntryPoint Fragment %1 "main"
  773. OpExecutionMode %1 OriginUpperLeft
  774. %void = OpTypeVoid
  775. %3 = OpTypeFunction %void
  776. %float = OpTypeFloat 32
  777. %uint = OpTypeInt 32 0
  778. %1 = OpFunction %void None %3
  779. %9 = OpLabel
  780. %12 = OpArrayLength %uint %float 0
  781. OpReturn
  782. OpFunctionEnd
  783. )";
  784. CompileSuccessfully(spirv.c_str());
  785. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  786. EXPECT_THAT(getDiagnosticString(),
  787. HasSubstr("Operand '4[%float]' cannot be a "
  788. "type"));
  789. }
  790. TEST_F(ValidateMemory, PushConstantNotStructGood) {
  791. std::string spirv = R"(
  792. OpCapability Shader
  793. OpMemoryModel Logical GLSL450
  794. OpEntryPoint Fragment %1 "main"
  795. OpExecutionMode %1 OriginUpperLeft
  796. %void = OpTypeVoid
  797. %voidfn = OpTypeFunction %void
  798. %float = OpTypeFloat 32
  799. %ptr = OpTypePointer PushConstant %float
  800. %pc = OpVariable %ptr PushConstant
  801. %1 = OpFunction %void None %voidfn
  802. %label = OpLabel
  803. OpReturn
  804. OpFunctionEnd
  805. )";
  806. CompileSuccessfully(spirv);
  807. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  808. }
  809. TEST_F(ValidateMemory, VulkanPushConstantNotStructBad) {
  810. std::string spirv = R"(
  811. OpCapability Shader
  812. OpMemoryModel Logical GLSL450
  813. OpEntryPoint Fragment %1 "main"
  814. OpExecutionMode %1 OriginUpperLeft
  815. %void = OpTypeVoid
  816. %voidfn = OpTypeFunction %void
  817. %float = OpTypeFloat 32
  818. %ptr = OpTypePointer PushConstant %float
  819. %pc = OpVariable %ptr PushConstant
  820. %1 = OpFunction %void None %voidfn
  821. %label = OpLabel
  822. OpReturn
  823. OpFunctionEnd
  824. )";
  825. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  826. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  827. EXPECT_THAT(getDiagnosticString(),
  828. AnyVUID("VUID-StandaloneSpirv-PushConstant-06808"));
  829. EXPECT_THAT(
  830. getDiagnosticString(),
  831. HasSubstr("PushConstant OpVariable <id> '6[%6]' has illegal "
  832. "type.\nFrom Vulkan spec, Push Constant Interface section:\n"
  833. "Such variables must be typed as OpTypeStruct"));
  834. }
  835. TEST_F(ValidateMemory, VulkanPushConstantArrayOfStructBad) {
  836. std::string spirv = R"(
  837. OpCapability Shader
  838. OpMemoryModel Logical GLSL450
  839. OpEntryPoint Fragment %1 "main"
  840. OpExecutionMode %1 OriginUpperLeft
  841. OpDecorate %struct Block
  842. OpMemberDecorate %struct 0 Offset 0
  843. %void = OpTypeVoid
  844. %voidfn = OpTypeFunction %void
  845. %float = OpTypeFloat 32
  846. %int = OpTypeInt 32 0
  847. %int_1 = OpConstant %int 1
  848. %struct = OpTypeStruct %float
  849. %array = OpTypeArray %struct %int_1
  850. %ptr = OpTypePointer PushConstant %array
  851. %pc = OpVariable %ptr PushConstant
  852. %1 = OpFunction %void None %voidfn
  853. %label = OpLabel
  854. OpReturn
  855. OpFunctionEnd
  856. )";
  857. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  858. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  859. EXPECT_THAT(getDiagnosticString(),
  860. AnyVUID("VUID-StandaloneSpirv-PushConstant-06808"));
  861. EXPECT_THAT(
  862. getDiagnosticString(),
  863. HasSubstr("PushConstant OpVariable <id> '10[%10]' has illegal "
  864. "type.\nFrom Vulkan spec, Push Constant Interface section:\n"
  865. "Such variables must be typed as OpTypeStruct"));
  866. }
  867. TEST_F(ValidateMemory, VulkanPushConstant) {
  868. std::string spirv = R"(
  869. OpCapability Shader
  870. OpMemoryModel Logical GLSL450
  871. OpEntryPoint Fragment %1 "main"
  872. OpExecutionMode %1 OriginUpperLeft
  873. OpDecorate %struct Block
  874. OpMemberDecorate %struct 0 Offset 0
  875. %void = OpTypeVoid
  876. %voidfn = OpTypeFunction %void
  877. %float = OpTypeFloat 32
  878. %struct = OpTypeStruct %float
  879. %ptr = OpTypePointer PushConstant %struct
  880. %pc = OpVariable %ptr PushConstant
  881. %1 = OpFunction %void None %voidfn
  882. %label = OpLabel
  883. OpReturn
  884. OpFunctionEnd
  885. )";
  886. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  887. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  888. }
  889. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad1) {
  890. const std::string spirv = R"(
  891. OpCapability Shader
  892. OpCapability VulkanMemoryModelKHR
  893. OpCapability Linkage
  894. OpExtension "SPV_KHR_vulkan_memory_model"
  895. OpMemoryModel Logical VulkanKHR
  896. %void = OpTypeVoid
  897. %int = OpTypeInt 32 0
  898. %device = OpConstant %int 1
  899. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  900. %var = OpVariable %int_ptr_ssbo StorageBuffer
  901. %voidfn = OpTypeFunction %void
  902. %func = OpFunction %void None %voidfn
  903. %entry = OpLabel
  904. %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
  905. OpReturn
  906. OpFunctionEnd
  907. )";
  908. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  909. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  910. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  911. EXPECT_THAT(
  912. getDiagnosticString(),
  913. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  914. "VulkanMemoryModelDeviceScopeKHR capability"));
  915. }
  916. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad2) {
  917. const std::string spirv = R"(
  918. OpCapability Shader
  919. OpCapability VulkanMemoryModelKHR
  920. OpCapability Linkage
  921. OpExtension "SPV_KHR_vulkan_memory_model"
  922. OpMemoryModel Logical VulkanKHR
  923. %void = OpTypeVoid
  924. %int = OpTypeInt 32 0
  925. %device = OpConstant %int 1
  926. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  927. %var = OpVariable %int_ptr_ssbo StorageBuffer
  928. %voidfn = OpTypeFunction %void
  929. %func = OpFunction %void None %voidfn
  930. %entry = OpLabel
  931. %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
  932. OpReturn
  933. OpFunctionEnd
  934. )";
  935. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  936. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  937. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  938. EXPECT_THAT(
  939. getDiagnosticString(),
  940. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  941. "VulkanMemoryModelDeviceScopeKHR capability"));
  942. }
  943. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood1) {
  944. const std::string spirv = R"(
  945. OpCapability Shader
  946. OpCapability VulkanMemoryModelKHR
  947. OpCapability VulkanMemoryModelDeviceScopeKHR
  948. OpCapability Linkage
  949. OpExtension "SPV_KHR_vulkan_memory_model"
  950. OpMemoryModel Logical VulkanKHR
  951. %void = OpTypeVoid
  952. %int = OpTypeInt 32 0
  953. %device = OpConstant %int 1
  954. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  955. %var = OpVariable %int_ptr_ssbo StorageBuffer
  956. %voidfn = OpTypeFunction %void
  957. %func = OpFunction %void None %voidfn
  958. %entry = OpLabel
  959. %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
  960. OpReturn
  961. OpFunctionEnd
  962. )";
  963. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  964. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  965. }
  966. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood2) {
  967. const std::string spirv = R"(
  968. OpCapability Shader
  969. OpCapability VulkanMemoryModelKHR
  970. OpCapability VulkanMemoryModelDeviceScopeKHR
  971. OpCapability Linkage
  972. OpExtension "SPV_KHR_vulkan_memory_model"
  973. OpMemoryModel Logical VulkanKHR
  974. %void = OpTypeVoid
  975. %int = OpTypeInt 32 0
  976. %device = OpConstant %int 1
  977. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  978. %var = OpVariable %int_ptr_ssbo StorageBuffer
  979. %voidfn = OpTypeFunction %void
  980. %func = OpFunction %void None %voidfn
  981. %entry = OpLabel
  982. %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
  983. OpReturn
  984. OpFunctionEnd
  985. )";
  986. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  987. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  988. }
  989. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad1) {
  990. const std::string spirv = R"(
  991. OpCapability Shader
  992. OpCapability VulkanMemoryModelKHR
  993. OpCapability Linkage
  994. OpExtension "SPV_KHR_vulkan_memory_model"
  995. OpMemoryModel Logical VulkanKHR
  996. %void = OpTypeVoid
  997. %int = OpTypeInt 32 0
  998. %device = OpConstant %int 1
  999. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1000. %var = OpVariable %int_ptr_ssbo StorageBuffer
  1001. %voidfn = OpTypeFunction %void
  1002. %func = OpFunction %void None %voidfn
  1003. %entry = OpLabel
  1004. OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1005. OpReturn
  1006. OpFunctionEnd
  1007. )";
  1008. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1009. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1010. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1011. EXPECT_THAT(
  1012. getDiagnosticString(),
  1013. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1014. "VulkanMemoryModelDeviceScopeKHR capability"));
  1015. }
  1016. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad2) {
  1017. const std::string spirv = R"(
  1018. OpCapability Shader
  1019. OpCapability VulkanMemoryModelKHR
  1020. OpCapability Linkage
  1021. OpExtension "SPV_KHR_vulkan_memory_model"
  1022. OpMemoryModel Logical VulkanKHR
  1023. %void = OpTypeVoid
  1024. %int = OpTypeInt 32 0
  1025. %device = OpConstant %int 1
  1026. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1027. %var = OpVariable %int_ptr_ssbo StorageBuffer
  1028. %voidfn = OpTypeFunction %void
  1029. %func = OpFunction %void None %voidfn
  1030. %entry = OpLabel
  1031. OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
  1032. OpReturn
  1033. OpFunctionEnd
  1034. )";
  1035. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1036. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1037. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1038. EXPECT_THAT(
  1039. getDiagnosticString(),
  1040. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1041. "VulkanMemoryModelDeviceScopeKHR capability"));
  1042. }
  1043. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood1) {
  1044. const std::string spirv = R"(
  1045. OpCapability Shader
  1046. OpCapability VulkanMemoryModelKHR
  1047. OpCapability VulkanMemoryModelDeviceScopeKHR
  1048. OpCapability Linkage
  1049. OpExtension "SPV_KHR_vulkan_memory_model"
  1050. OpMemoryModel Logical VulkanKHR
  1051. %void = OpTypeVoid
  1052. %int = OpTypeInt 32 0
  1053. %device = OpConstant %int 1
  1054. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1055. %var = OpVariable %int_ptr_ssbo StorageBuffer
  1056. %voidfn = OpTypeFunction %void
  1057. %func = OpFunction %void None %voidfn
  1058. %entry = OpLabel
  1059. OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1060. OpReturn
  1061. OpFunctionEnd
  1062. )";
  1063. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1064. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1065. }
  1066. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood2) {
  1067. const std::string spirv = R"(
  1068. OpCapability Shader
  1069. OpCapability VulkanMemoryModelKHR
  1070. OpCapability VulkanMemoryModelDeviceScopeKHR
  1071. OpCapability Linkage
  1072. OpExtension "SPV_KHR_vulkan_memory_model"
  1073. OpMemoryModel Logical VulkanKHR
  1074. %void = OpTypeVoid
  1075. %int = OpTypeInt 32 0
  1076. %device = OpConstant %int 1
  1077. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1078. %var = OpVariable %int_ptr_ssbo StorageBuffer
  1079. %voidfn = OpTypeFunction %void
  1080. %func = OpFunction %void None %voidfn
  1081. %entry = OpLabel
  1082. OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
  1083. OpReturn
  1084. OpFunctionEnd
  1085. )";
  1086. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1087. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1088. }
  1089. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad1) {
  1090. const std::string spirv = R"(
  1091. OpCapability Shader
  1092. OpCapability VulkanMemoryModelKHR
  1093. OpCapability Linkage
  1094. OpExtension "SPV_KHR_vulkan_memory_model"
  1095. OpMemoryModel Logical VulkanKHR
  1096. %void = OpTypeVoid
  1097. %int = OpTypeInt 32 0
  1098. %device = OpConstant %int 1
  1099. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1100. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1101. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1102. %voidfn = OpTypeFunction %void
  1103. %func = OpFunction %void None %voidfn
  1104. %entry = OpLabel
  1105. OpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1106. OpReturn
  1107. OpFunctionEnd
  1108. )";
  1109. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1110. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1111. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1112. EXPECT_THAT(
  1113. getDiagnosticString(),
  1114. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1115. "VulkanMemoryModelDeviceScopeKHR capability"));
  1116. }
  1117. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad2) {
  1118. const std::string spirv = R"(
  1119. OpCapability Shader
  1120. OpCapability VulkanMemoryModelKHR
  1121. OpCapability Linkage
  1122. OpExtension "SPV_KHR_vulkan_memory_model"
  1123. OpMemoryModel Logical VulkanKHR
  1124. %void = OpTypeVoid
  1125. %int = OpTypeInt 32 0
  1126. %device = OpConstant %int 1
  1127. %workgroup = OpConstant %int 1
  1128. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1129. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1130. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1131. %voidfn = OpTypeFunction %void
  1132. %func = OpFunction %void None %voidfn
  1133. %entry = OpLabel
  1134. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1135. OpReturn
  1136. OpFunctionEnd
  1137. )";
  1138. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1139. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1140. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1141. EXPECT_THAT(
  1142. getDiagnosticString(),
  1143. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1144. "VulkanMemoryModelDeviceScopeKHR capability"));
  1145. }
  1146. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad3) {
  1147. const std::string spirv = R"(
  1148. OpCapability Shader
  1149. OpCapability VulkanMemoryModelKHR
  1150. OpCapability Linkage
  1151. OpExtension "SPV_KHR_vulkan_memory_model"
  1152. OpMemoryModel Logical VulkanKHR
  1153. %void = OpTypeVoid
  1154. %int = OpTypeInt 32 0
  1155. %device = OpConstant %int 1
  1156. %workgroup = OpConstant %int 1
  1157. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1158. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1159. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1160. %voidfn = OpTypeFunction %void
  1161. %func = OpFunction %void None %voidfn
  1162. %entry = OpLabel
  1163. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1164. OpReturn
  1165. OpFunctionEnd
  1166. )";
  1167. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1168. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1169. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1170. EXPECT_THAT(
  1171. getDiagnosticString(),
  1172. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1173. "VulkanMemoryModelDeviceScopeKHR capability"));
  1174. }
  1175. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood2) {
  1176. const std::string spirv = R"(
  1177. OpCapability Shader
  1178. OpCapability VulkanMemoryModelKHR
  1179. OpCapability VulkanMemoryModelDeviceScopeKHR
  1180. OpCapability Linkage
  1181. OpExtension "SPV_KHR_vulkan_memory_model"
  1182. OpMemoryModel Logical VulkanKHR
  1183. %void = OpTypeVoid
  1184. %int = OpTypeInt 32 0
  1185. %device = OpConstant %int 1
  1186. %workgroup = OpConstant %int 2
  1187. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1188. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1189. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1190. %voidfn = OpTypeFunction %void
  1191. %func = OpFunction %void None %voidfn
  1192. %entry = OpLabel
  1193. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1194. OpReturn
  1195. OpFunctionEnd
  1196. )";
  1197. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1198. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1199. }
  1200. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood3) {
  1201. const std::string spirv = R"(
  1202. OpCapability Shader
  1203. OpCapability VulkanMemoryModelKHR
  1204. OpCapability VulkanMemoryModelDeviceScopeKHR
  1205. OpCapability Linkage
  1206. OpExtension "SPV_KHR_vulkan_memory_model"
  1207. OpMemoryModel Logical VulkanKHR
  1208. %void = OpTypeVoid
  1209. %int = OpTypeInt 32 0
  1210. %device = OpConstant %int 1
  1211. %workgroup = OpConstant %int 2
  1212. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1213. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1214. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1215. %voidfn = OpTypeFunction %void
  1216. %func = OpFunction %void None %voidfn
  1217. %entry = OpLabel
  1218. OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1219. OpReturn
  1220. OpFunctionEnd
  1221. )";
  1222. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1223. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1224. }
  1225. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessAvVisBadBinaryV13) {
  1226. const std::string spirv = R"(
  1227. OpCapability Shader
  1228. OpCapability VulkanMemoryModelKHR
  1229. OpCapability VulkanMemoryModelDeviceScopeKHR
  1230. OpCapability Linkage
  1231. OpExtension "SPV_KHR_vulkan_memory_model"
  1232. OpMemoryModel Logical VulkanKHR
  1233. %void = OpTypeVoid
  1234. %int = OpTypeInt 32 0
  1235. %device = OpConstant %int 1
  1236. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1237. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1238. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1239. %voidfn = OpTypeFunction %void
  1240. %func = OpFunction %void None %voidfn
  1241. %entry = OpLabel
  1242. OpCopyMemory %var1 %var2
  1243. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1244. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1245. OpReturn
  1246. OpFunctionEnd
  1247. )";
  1248. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1249. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1250. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1251. EXPECT_THAT(
  1252. getDiagnosticString(),
  1253. HasSubstr(
  1254. "with two memory access operands requires SPIR-V 1.4 or later"));
  1255. }
  1256. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessAvVisGood) {
  1257. const std::string spirv = R"(
  1258. OpCapability Shader
  1259. OpCapability VulkanMemoryModelKHR
  1260. OpCapability VulkanMemoryModelDeviceScopeKHR
  1261. OpCapability Linkage
  1262. OpExtension "SPV_KHR_vulkan_memory_model"
  1263. OpMemoryModel Logical VulkanKHR
  1264. %void = OpTypeVoid
  1265. %int = OpTypeInt 32 0
  1266. %device = OpConstant %int 1
  1267. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1268. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1269. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1270. %voidfn = OpTypeFunction %void
  1271. %func = OpFunction %void None %voidfn
  1272. %entry = OpLabel
  1273. OpCopyMemory %var1 %var2
  1274. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1275. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1276. OpReturn
  1277. OpFunctionEnd
  1278. )";
  1279. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1280. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1281. EXPECT_THAT(getDiagnosticString(), Eq(""));
  1282. }
  1283. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessFirstWithAvBad) {
  1284. const std::string spirv = R"(
  1285. OpCapability Shader
  1286. OpCapability VulkanMemoryModelKHR
  1287. OpCapability VulkanMemoryModelDeviceScopeKHR
  1288. OpCapability Linkage
  1289. OpExtension "SPV_KHR_vulkan_memory_model"
  1290. OpMemoryModel Logical VulkanKHR
  1291. %void = OpTypeVoid
  1292. %int = OpTypeInt 32 0
  1293. %device = OpConstant %int 1
  1294. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1295. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1296. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1297. %voidfn = OpTypeFunction %void
  1298. %func = OpFunction %void None %voidfn
  1299. %entry = OpLabel
  1300. OpCopyMemory %var1 %var2
  1301. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1302. MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1303. OpReturn
  1304. OpFunctionEnd
  1305. )";
  1306. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1307. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1308. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1309. EXPECT_THAT(
  1310. getDiagnosticString(),
  1311. HasSubstr(
  1312. "Source memory access must not include MakePointerAvailableKHR\n"
  1313. " OpCopyMemory %5 %6 MakePointerAvailable|NonPrivatePointer"
  1314. " %uint_1 MakePointerAvailable|NonPrivatePointer %uint_1"));
  1315. }
  1316. TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessSecondWithVisBad) {
  1317. const std::string spirv = R"(
  1318. OpCapability Shader
  1319. OpCapability VulkanMemoryModelKHR
  1320. OpCapability VulkanMemoryModelDeviceScopeKHR
  1321. OpCapability Linkage
  1322. OpExtension "SPV_KHR_vulkan_memory_model"
  1323. OpMemoryModel Logical VulkanKHR
  1324. %void = OpTypeVoid
  1325. %int = OpTypeInt 32 0
  1326. %device = OpConstant %int 1
  1327. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1328. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1329. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1330. %voidfn = OpTypeFunction %void
  1331. %func = OpFunction %void None %voidfn
  1332. %entry = OpLabel
  1333. OpCopyMemory %var1 %var2
  1334. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1335. MakePointerVisibleKHR|NonPrivatePointerKHR %device
  1336. OpReturn
  1337. OpFunctionEnd
  1338. )";
  1339. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  1340. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1341. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1342. EXPECT_THAT(
  1343. getDiagnosticString(),
  1344. HasSubstr("Target memory access must not include MakePointerVisibleKHR\n"
  1345. " OpCopyMemory %5 %6 MakePointerVisible|NonPrivatePointer"
  1346. " %uint_1 MakePointerVisible|NonPrivatePointer %uint_1"));
  1347. }
  1348. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad1) {
  1349. const std::string spirv = R"(
  1350. OpCapability Shader
  1351. OpCapability VulkanMemoryModelKHR
  1352. OpCapability Linkage
  1353. OpCapability Addresses
  1354. OpExtension "SPV_KHR_vulkan_memory_model"
  1355. OpMemoryModel Logical VulkanKHR
  1356. %void = OpTypeVoid
  1357. %int = OpTypeInt 32 0
  1358. %int_4 = OpConstant %int 4
  1359. %device = OpConstant %int 1
  1360. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1361. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1362. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1363. %voidfn = OpTypeFunction %void
  1364. %func = OpFunction %void None %voidfn
  1365. %entry = OpLabel
  1366. OpCopyMemorySized %var1 %var2 %int_4 MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1367. OpReturn
  1368. OpFunctionEnd
  1369. )";
  1370. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1371. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1372. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1373. EXPECT_THAT(
  1374. getDiagnosticString(),
  1375. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1376. "VulkanMemoryModelDeviceScopeKHR capability"));
  1377. }
  1378. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad2) {
  1379. const std::string spirv = R"(
  1380. OpCapability Shader
  1381. OpCapability VulkanMemoryModelKHR
  1382. OpCapability Linkage
  1383. OpCapability Addresses
  1384. OpExtension "SPV_KHR_vulkan_memory_model"
  1385. OpMemoryModel Logical VulkanKHR
  1386. %void = OpTypeVoid
  1387. %int = OpTypeInt 32 0
  1388. %int_4 = OpConstant %int 4
  1389. %device = OpConstant %int 1
  1390. %workgroup = OpConstant %int 1
  1391. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1392. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1393. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1394. %voidfn = OpTypeFunction %void
  1395. %func = OpFunction %void None %voidfn
  1396. %entry = OpLabel
  1397. OpCopyMemorySized %var1 %var2 %int_4 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1398. OpReturn
  1399. OpFunctionEnd
  1400. )";
  1401. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1402. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1403. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1404. EXPECT_THAT(
  1405. getDiagnosticString(),
  1406. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1407. "VulkanMemoryModelDeviceScopeKHR capability"));
  1408. }
  1409. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad3) {
  1410. const std::string spirv = R"(
  1411. OpCapability Shader
  1412. OpCapability VulkanMemoryModelKHR
  1413. OpCapability Linkage
  1414. OpCapability Addresses
  1415. OpExtension "SPV_KHR_vulkan_memory_model"
  1416. OpMemoryModel Logical VulkanKHR
  1417. %void = OpTypeVoid
  1418. %int = OpTypeInt 32 0
  1419. %int_4 = OpConstant %int 4
  1420. %device = OpConstant %int 1
  1421. %workgroup = OpConstant %int 1
  1422. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1423. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1424. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1425. %voidfn = OpTypeFunction %void
  1426. %func = OpFunction %void None %voidfn
  1427. %entry = OpLabel
  1428. OpCopyMemorySized %var1 %var2 %int_4 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1429. OpReturn
  1430. OpFunctionEnd
  1431. )";
  1432. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1433. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  1434. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1435. EXPECT_THAT(
  1436. getDiagnosticString(),
  1437. HasSubstr("Use of device scope with VulkanKHR memory model requires the "
  1438. "VulkanMemoryModelDeviceScopeKHR capability"));
  1439. }
  1440. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood1) {
  1441. const std::string spirv = R"(
  1442. OpCapability Shader
  1443. OpCapability VulkanMemoryModelKHR
  1444. OpCapability VulkanMemoryModelDeviceScopeKHR
  1445. OpCapability Linkage
  1446. OpCapability Addresses
  1447. OpExtension "SPV_KHR_vulkan_memory_model"
  1448. OpMemoryModel Logical VulkanKHR
  1449. %void = OpTypeVoid
  1450. %int = OpTypeInt 32 0
  1451. %int_4 = OpConstant %int 4
  1452. %device = OpConstant %int 1
  1453. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1454. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1455. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1456. %voidfn = OpTypeFunction %void
  1457. %func = OpFunction %void None %voidfn
  1458. %entry = OpLabel
  1459. OpCopyMemorySized %var1 %var2 %int_4 MakePointerAvailableKHR|NonPrivatePointerKHR %device
  1460. OpReturn
  1461. OpFunctionEnd
  1462. )";
  1463. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1464. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1465. }
  1466. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood2) {
  1467. const std::string spirv = R"(
  1468. OpCapability Shader
  1469. OpCapability VulkanMemoryModelKHR
  1470. OpCapability VulkanMemoryModelDeviceScopeKHR
  1471. OpCapability Linkage
  1472. OpCapability Addresses
  1473. OpExtension "SPV_KHR_vulkan_memory_model"
  1474. OpMemoryModel Logical VulkanKHR
  1475. %void = OpTypeVoid
  1476. %int = OpTypeInt 32 0
  1477. %int_4 = OpConstant %int 4
  1478. %device = OpConstant %int 1
  1479. %workgroup = OpConstant %int 2
  1480. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1481. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1482. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1483. %voidfn = OpTypeFunction %void
  1484. %func = OpFunction %void None %voidfn
  1485. %entry = OpLabel
  1486. OpCopyMemorySized %var1 %var2 %int_4 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
  1487. OpReturn
  1488. OpFunctionEnd
  1489. )";
  1490. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1491. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1492. }
  1493. TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood3) {
  1494. const std::string spirv = R"(
  1495. OpCapability Shader
  1496. OpCapability VulkanMemoryModelKHR
  1497. OpCapability VulkanMemoryModelDeviceScopeKHR
  1498. OpCapability Linkage
  1499. OpCapability Addresses
  1500. OpExtension "SPV_KHR_vulkan_memory_model"
  1501. OpMemoryModel Logical VulkanKHR
  1502. %void = OpTypeVoid
  1503. %int = OpTypeInt 32 0
  1504. %int_4 = OpConstant %int 4
  1505. %device = OpConstant %int 1
  1506. %workgroup = OpConstant %int 2
  1507. %int_ptr_ssbo = OpTypePointer StorageBuffer %int
  1508. %var1 = OpVariable %int_ptr_ssbo StorageBuffer
  1509. %var2 = OpVariable %int_ptr_ssbo StorageBuffer
  1510. %voidfn = OpTypeFunction %void
  1511. %func = OpFunction %void None %voidfn
  1512. %entry = OpLabel
  1513. OpCopyMemorySized %var1 %var2 %int_4 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
  1514. OpReturn
  1515. OpFunctionEnd
  1516. )";
  1517. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  1518. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  1519. }
  1520. TEST_F(ValidateMemory, ArrayLengthStructIsLabel) {
  1521. const std::string spirv = R"(
  1522. OpCapability Tessellation
  1523. OpMemoryModel Logical GLSL450
  1524. OpName %20 "incorrect"
  1525. %void = OpTypeVoid
  1526. %3 = OpTypeFunction %void
  1527. %float = OpTypeFloat 32
  1528. %v4float = OpTypeVector %float 4
  1529. %uint = OpTypeInt 32 0
  1530. %4 = OpFunction %void None %3
  1531. %20 = OpLabel
  1532. %24 = OpArrayLength %uint %20 0
  1533. %25 = OpLoad %v4float %24
  1534. OpReturnValue %25
  1535. OpFunctionEnd
  1536. )";
  1537. CompileSuccessfully(spirv);
  1538. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1539. EXPECT_THAT(getDiagnosticString(),
  1540. HasSubstr("Operand '1[%incorrect]' requires a type"));
  1541. }
  1542. TEST_F(ValidateMemory, PSBLoadAlignedSuccess) {
  1543. const std::string body = R"(
  1544. OpCapability PhysicalStorageBufferAddresses
  1545. OpCapability Int64
  1546. OpCapability Shader
  1547. OpExtension "SPV_EXT_physical_storage_buffer"
  1548. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1549. OpEntryPoint Fragment %main "main"
  1550. OpExecutionMode %main OriginUpperLeft
  1551. OpDecorate %val1 AliasedPointer
  1552. %uint64 = OpTypeInt 64 0
  1553. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1554. %pptr_f = OpTypePointer Function %ptr
  1555. %void = OpTypeVoid
  1556. %voidfn = OpTypeFunction %void
  1557. %main = OpFunction %void None %voidfn
  1558. %entry = OpLabel
  1559. %val1 = OpVariable %pptr_f Function
  1560. %val2 = OpLoad %ptr %val1
  1561. %val3 = OpLoad %uint64 %val2 Aligned 8
  1562. OpReturn
  1563. OpFunctionEnd
  1564. )";
  1565. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1566. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1567. }
  1568. TEST_F(ValidateMemory, PSBLoadAlignedMissing) {
  1569. const std::string body = R"(
  1570. OpCapability PhysicalStorageBufferAddresses
  1571. OpCapability Int64
  1572. OpCapability Shader
  1573. OpExtension "SPV_EXT_physical_storage_buffer"
  1574. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1575. OpEntryPoint Fragment %main "main"
  1576. OpExecutionMode %main OriginUpperLeft
  1577. OpDecorate %val1 AliasedPointer
  1578. %uint64 = OpTypeInt 64 0
  1579. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1580. %pptr_f = OpTypePointer Function %ptr
  1581. %void = OpTypeVoid
  1582. %voidfn = OpTypeFunction %void
  1583. %main = OpFunction %void None %voidfn
  1584. %entry = OpLabel
  1585. %val1 = OpVariable %pptr_f Function
  1586. %val2 = OpLoad %ptr %val1
  1587. %val3 = OpLoad %uint64 %val2
  1588. OpReturn
  1589. OpFunctionEnd
  1590. )";
  1591. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1592. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1593. EXPECT_THAT(getDiagnosticString(),
  1594. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
  1595. EXPECT_THAT(
  1596. getDiagnosticString(),
  1597. HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
  1598. }
  1599. TEST_F(ValidateMemory, PSBLoadAlignedMissingWithOtherOperand) {
  1600. const std::string body = R"(
  1601. OpCapability PhysicalStorageBufferAddresses
  1602. OpCapability Int64
  1603. OpCapability Shader
  1604. OpExtension "SPV_EXT_physical_storage_buffer"
  1605. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1606. OpEntryPoint Fragment %main "main"
  1607. OpExecutionMode %main OriginUpperLeft
  1608. OpDecorate %val1 AliasedPointer
  1609. %uint64 = OpTypeInt 64 0
  1610. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1611. %pptr_f = OpTypePointer Function %ptr
  1612. %void = OpTypeVoid
  1613. %voidfn = OpTypeFunction %void
  1614. %main = OpFunction %void None %voidfn
  1615. %entry = OpLabel
  1616. %val1 = OpVariable %pptr_f Function
  1617. %val2 = OpLoad %ptr %val1
  1618. %val3 = OpLoad %uint64 %val2 Volatile
  1619. OpReturn
  1620. OpFunctionEnd
  1621. )";
  1622. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1623. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1624. EXPECT_THAT(getDiagnosticString(),
  1625. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
  1626. EXPECT_THAT(
  1627. getDiagnosticString(),
  1628. HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
  1629. }
  1630. TEST_F(ValidateMemory, PSBStoreAlignedSuccess) {
  1631. const std::string body = R"(
  1632. OpCapability PhysicalStorageBufferAddresses
  1633. OpCapability Int64
  1634. OpCapability Shader
  1635. OpExtension "SPV_EXT_physical_storage_buffer"
  1636. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1637. OpEntryPoint Fragment %main "main"
  1638. OpExecutionMode %main OriginUpperLeft
  1639. OpDecorate %val1 AliasedPointer
  1640. %uint64 = OpTypeInt 64 0
  1641. %u64_1 = OpConstant %uint64 1
  1642. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1643. %pptr_f = OpTypePointer Function %ptr
  1644. %void = OpTypeVoid
  1645. %voidfn = OpTypeFunction %void
  1646. %main = OpFunction %void None %voidfn
  1647. %entry = OpLabel
  1648. %val1 = OpVariable %pptr_f Function
  1649. %val2 = OpLoad %ptr %val1
  1650. OpStore %val2 %u64_1 Aligned 8
  1651. OpReturn
  1652. OpFunctionEnd
  1653. )";
  1654. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1655. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1656. }
  1657. TEST_F(ValidateMemory, PSBStoreAlignedMissing) {
  1658. const std::string body = R"(
  1659. OpCapability PhysicalStorageBufferAddresses
  1660. OpCapability Int64
  1661. OpCapability Shader
  1662. OpExtension "SPV_EXT_physical_storage_buffer"
  1663. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1664. OpEntryPoint Fragment %main "main"
  1665. OpExecutionMode %main OriginUpperLeft
  1666. OpDecorate %val1 AliasedPointer
  1667. %uint64 = OpTypeInt 64 0
  1668. %u64_1 = OpConstant %uint64 1
  1669. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1670. %pptr_f = OpTypePointer Function %ptr
  1671. %void = OpTypeVoid
  1672. %voidfn = OpTypeFunction %void
  1673. %main = OpFunction %void None %voidfn
  1674. %entry = OpLabel
  1675. %val1 = OpVariable %pptr_f Function
  1676. %val2 = OpLoad %ptr %val1
  1677. OpStore %val2 %u64_1 None
  1678. OpReturn
  1679. OpFunctionEnd
  1680. )";
  1681. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1682. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1683. EXPECT_THAT(getDiagnosticString(),
  1684. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
  1685. EXPECT_THAT(
  1686. getDiagnosticString(),
  1687. HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
  1688. }
  1689. TEST_F(ValidateMemory, PSBStoreAlignedZero) {
  1690. const std::string body = R"(
  1691. OpCapability PhysicalStorageBufferAddresses
  1692. OpCapability Shader
  1693. OpExtension "SPV_EXT_physical_storage_buffer"
  1694. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1695. OpEntryPoint Fragment %main "main"
  1696. OpExecutionMode %main OriginUpperLeft
  1697. %uint = OpTypeInt 32 0
  1698. %uint_1 = OpConstant %uint 1
  1699. %ptr = OpTypePointer PhysicalStorageBuffer %uint
  1700. %pptr_f = OpTypePointer Function %ptr
  1701. %void = OpTypeVoid
  1702. %voidfn = OpTypeFunction %void
  1703. %main = OpFunction %void None %voidfn
  1704. %entry = OpLabel
  1705. %val1 = OpVariable %pptr_f Function
  1706. %val2 = OpLoad %ptr %val1
  1707. OpStore %val2 %uint_1 Aligned 0
  1708. OpReturn
  1709. OpFunctionEnd
  1710. )";
  1711. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1712. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1713. EXPECT_THAT(
  1714. getDiagnosticString(),
  1715. HasSubstr(
  1716. "Memory accesses Aligned operand value 0 is not a power of two"));
  1717. }
  1718. TEST_F(ValidateMemory, PSBStoreAlignedNonPoT) {
  1719. const std::string body = R"(
  1720. OpCapability PhysicalStorageBufferAddresses
  1721. OpCapability Shader
  1722. OpExtension "SPV_EXT_physical_storage_buffer"
  1723. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1724. OpEntryPoint Fragment %main "main"
  1725. OpExecutionMode %main OriginUpperLeft
  1726. %uint = OpTypeInt 32 0
  1727. %uint_1 = OpConstant %uint 1
  1728. %ptr = OpTypePointer PhysicalStorageBuffer %uint
  1729. %pptr_f = OpTypePointer Function %ptr
  1730. %void = OpTypeVoid
  1731. %voidfn = OpTypeFunction %void
  1732. %main = OpFunction %void None %voidfn
  1733. %entry = OpLabel
  1734. %val1 = OpVariable %pptr_f Function
  1735. %val2 = OpLoad %ptr %val1
  1736. OpStore %val2 %uint_1 Aligned 3
  1737. OpReturn
  1738. OpFunctionEnd
  1739. )";
  1740. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1741. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1742. EXPECT_THAT(
  1743. getDiagnosticString(),
  1744. HasSubstr(
  1745. "Memory accesses Aligned operand value 3 is not a power of two."));
  1746. }
  1747. TEST_F(ValidateMemory, PSBCopyMemoryAlignedSuccess) {
  1748. const std::string body = R"(
  1749. OpCapability PhysicalStorageBufferAddresses
  1750. OpCapability Int64
  1751. OpCapability Shader
  1752. OpExtension "SPV_EXT_physical_storage_buffer"
  1753. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1754. OpEntryPoint Fragment %main "main"
  1755. OpExecutionMode %main OriginUpperLeft
  1756. OpDecorate %val1 AliasedPointer
  1757. %int = OpTypeInt 32 0
  1758. %uint64 = OpTypeInt 64 0
  1759. %u64_1 = OpConstant %uint64 1
  1760. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1761. %pptr_f = OpTypePointer Function %ptr
  1762. %void = OpTypeVoid
  1763. %voidfn = OpTypeFunction %void
  1764. %main = OpFunction %void None %voidfn
  1765. %entry = OpLabel
  1766. %val1 = OpVariable %pptr_f Function
  1767. %val2 = OpLoad %ptr %val1
  1768. %val3 = OpLoad %ptr %val1
  1769. OpCopyMemory %val2 %val3 Aligned 4
  1770. OpCopyMemory %val3 %val2 Aligned 4 Aligned 4
  1771. OpReturn
  1772. OpFunctionEnd
  1773. )";
  1774. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1775. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1776. }
  1777. TEST_F(ValidateMemory, PSBCopyMemoryAlignedMissingTarget) {
  1778. const std::string body = R"(
  1779. OpCapability PhysicalStorageBufferAddresses
  1780. OpCapability Int64
  1781. OpCapability Shader
  1782. OpExtension "SPV_EXT_physical_storage_buffer"
  1783. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1784. OpEntryPoint Fragment %main "main"
  1785. OpExecutionMode %main OriginUpperLeft
  1786. OpDecorate %val1 AliasedPointer
  1787. %int = OpTypeInt 32 0
  1788. %uint64 = OpTypeInt 64 0
  1789. %u64_1 = OpConstant %uint64 1
  1790. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1791. %pptr_f = OpTypePointer Function %ptr
  1792. %void = OpTypeVoid
  1793. %voidfn = OpTypeFunction %void
  1794. %main = OpFunction %void None %voidfn
  1795. %entry = OpLabel
  1796. %val1 = OpVariable %pptr_f Function
  1797. %val2 = OpLoad %ptr %val1
  1798. %val3 = OpLoad %ptr %val1
  1799. OpCopyMemory %val2 %val3 Volatile Aligned 4
  1800. OpReturn
  1801. OpFunctionEnd
  1802. )";
  1803. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1804. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1805. EXPECT_THAT(getDiagnosticString(),
  1806. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
  1807. EXPECT_THAT(
  1808. getDiagnosticString(),
  1809. HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
  1810. }
  1811. TEST_F(ValidateMemory, PSBCopyMemoryAlignedMissingSource) {
  1812. const std::string body = R"(
  1813. OpCapability PhysicalStorageBufferAddresses
  1814. OpCapability Int64
  1815. OpCapability Shader
  1816. OpExtension "SPV_EXT_physical_storage_buffer"
  1817. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1818. OpEntryPoint Fragment %main "main"
  1819. OpExecutionMode %main OriginUpperLeft
  1820. OpDecorate %val1 AliasedPointer
  1821. %int = OpTypeInt 32 0
  1822. %uint64 = OpTypeInt 64 0
  1823. %u64_1 = OpConstant %uint64 1
  1824. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1825. %pptr_f = OpTypePointer Function %ptr
  1826. %void = OpTypeVoid
  1827. %voidfn = OpTypeFunction %void
  1828. %main = OpFunction %void None %voidfn
  1829. %entry = OpLabel
  1830. %val1 = OpVariable %pptr_f Function
  1831. %val2 = OpLoad %ptr %val1
  1832. %val3 = OpLoad %ptr %val1
  1833. OpCopyMemory %val2 %val3 Aligned 4 Volatile
  1834. OpReturn
  1835. OpFunctionEnd
  1836. )";
  1837. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1838. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1839. EXPECT_THAT(getDiagnosticString(),
  1840. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
  1841. EXPECT_THAT(
  1842. getDiagnosticString(),
  1843. HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
  1844. }
  1845. TEST_F(ValidateMemory, PSBCopyMemoryAlignedMissingBoth) {
  1846. const std::string body = R"(
  1847. OpCapability PhysicalStorageBufferAddresses
  1848. OpCapability Int64
  1849. OpCapability Shader
  1850. OpExtension "SPV_EXT_physical_storage_buffer"
  1851. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1852. OpEntryPoint Fragment %main "main"
  1853. OpExecutionMode %main OriginUpperLeft
  1854. OpDecorate %val1 AliasedPointer
  1855. %int = OpTypeInt 32 0
  1856. %uint64 = OpTypeInt 64 0
  1857. %u64_1 = OpConstant %uint64 1
  1858. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1859. %pptr_f = OpTypePointer Function %ptr
  1860. %void = OpTypeVoid
  1861. %voidfn = OpTypeFunction %void
  1862. %main = OpFunction %void None %voidfn
  1863. %entry = OpLabel
  1864. %val1 = OpVariable %pptr_f Function
  1865. %val2 = OpLoad %ptr %val1
  1866. %val3 = OpLoad %ptr %val1
  1867. OpCopyMemory %val2 %val3 Volatile
  1868. OpReturn
  1869. OpFunctionEnd
  1870. )";
  1871. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  1872. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1873. EXPECT_THAT(getDiagnosticString(),
  1874. AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
  1875. EXPECT_THAT(
  1876. getDiagnosticString(),
  1877. HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
  1878. }
  1879. TEST_F(ValidateMemory, PSBVariable) {
  1880. const std::string body = R"(
  1881. OpCapability PhysicalStorageBufferAddresses
  1882. OpCapability Int64
  1883. OpCapability Shader
  1884. OpExtension "SPV_EXT_physical_storage_buffer"
  1885. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1886. OpEntryPoint Fragment %main "main"
  1887. OpExecutionMode %main OriginUpperLeft
  1888. OpDecorate %val1 AliasedPointer
  1889. %uint64 = OpTypeInt 64 0
  1890. %ptr = OpTypePointer PhysicalStorageBuffer %uint64
  1891. %val1 = OpVariable %ptr PhysicalStorageBuffer
  1892. %void = OpTypeVoid
  1893. %voidfn = OpTypeFunction %void
  1894. %main = OpFunction %void None %voidfn
  1895. %entry = OpLabel
  1896. OpReturn
  1897. OpFunctionEnd
  1898. )";
  1899. CompileSuccessfully(body);
  1900. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1901. EXPECT_THAT(
  1902. getDiagnosticString(),
  1903. HasSubstr("PhysicalStorageBuffer must not be used with OpVariable"));
  1904. }
  1905. std::string GenCoopMatLoadStoreShader(const std::string& storeMemoryAccess,
  1906. const std::string& loadMemoryAccess) {
  1907. std::string s = R"(
  1908. OpCapability Shader
  1909. OpCapability GroupNonUniform
  1910. OpCapability VulkanMemoryModelKHR
  1911. OpCapability CooperativeMatrixNV
  1912. OpExtension "SPV_KHR_vulkan_memory_model"
  1913. OpExtension "SPV_NV_cooperative_matrix"
  1914. %1 = OpExtInstImport "GLSL.std.450"
  1915. OpMemoryModel Logical VulkanKHR
  1916. OpEntryPoint GLCompute %4 "main" %11 %21
  1917. OpExecutionMode %4 LocalSize 1 1 1
  1918. OpDecorate %11 BuiltIn SubgroupId
  1919. OpDecorate %21 BuiltIn WorkgroupId
  1920. OpDecorate %74 ArrayStride 4
  1921. OpMemberDecorate %75 0 Offset 0
  1922. OpDecorate %75 Block
  1923. OpDecorate %77 DescriptorSet 0
  1924. OpDecorate %77 Binding 0
  1925. OpDecorate %92 ArrayStride 4
  1926. OpMemberDecorate %93 0 Offset 0
  1927. OpDecorate %93 Block
  1928. OpDecorate %95 DescriptorSet 0
  1929. OpDecorate %95 Binding 1
  1930. OpDecorate %102 ArrayStride 4
  1931. OpMemberDecorate %103 0 Offset 0
  1932. OpDecorate %103 Block
  1933. OpDecorate %105 DescriptorSet 0
  1934. OpDecorate %105 Binding 2
  1935. OpDecorate %117 ArrayStride 4
  1936. OpMemberDecorate %118 0 Offset 0
  1937. OpDecorate %118 Block
  1938. OpDecorate %120 DescriptorSet 0
  1939. OpDecorate %120 Binding 3
  1940. OpDecorate %123 SpecId 2
  1941. OpDecorate %124 SpecId 3
  1942. OpDecorate %125 SpecId 4
  1943. OpDecorate %126 SpecId 5
  1944. OpDecorate %127 SpecId 0
  1945. OpDecorate %128 SpecId 1
  1946. OpDecorate %129 BuiltIn WorkgroupSize
  1947. %2 = OpTypeVoid
  1948. %3 = OpTypeFunction %2
  1949. %6 = OpTypeInt 32 0
  1950. %7 = OpTypeVector %6 2
  1951. %8 = OpTypePointer Function %7
  1952. %10 = OpTypePointer Input %6
  1953. %11 = OpVariable %10 Input
  1954. %13 = OpConstant %6 2
  1955. %19 = OpTypeVector %6 3
  1956. %20 = OpTypePointer Input %19
  1957. %21 = OpVariable %20 Input
  1958. %27 = OpConstantComposite %7 %13 %13
  1959. %31 = OpTypePointer Function %6
  1960. %33 = OpConstant %6 1024
  1961. %34 = OpConstant %6 1
  1962. %38 = OpConstant %6 8
  1963. %39 = OpConstant %6 0
  1964. %68 = OpTypeFloat 32
  1965. %69 = OpConstant %6 16
  1966. %70 = OpConstant %6 3
  1967. %71 = OpTypeCooperativeMatrixNV %68 %70 %69 %38
  1968. %72 = OpTypePointer Function %71
  1969. %74 = OpTypeRuntimeArray %68
  1970. %75 = OpTypeStruct %74
  1971. %76 = OpTypePointer StorageBuffer %75
  1972. %77 = OpVariable %76 StorageBuffer
  1973. %78 = OpTypeInt 32 1
  1974. %79 = OpConstant %78 0
  1975. %81 = OpConstant %6 5
  1976. %82 = OpTypePointer StorageBuffer %68
  1977. %84 = OpConstant %6 64
  1978. %85 = OpTypeBool
  1979. %86 = OpConstantFalse %85
  1980. %88 = OpTypePointer Private %71
  1981. %89 = OpVariable %88 Private
  1982. %92 = OpTypeRuntimeArray %68
  1983. %93 = OpTypeStruct %92
  1984. %94 = OpTypePointer StorageBuffer %93
  1985. %95 = OpVariable %94 StorageBuffer
  1986. %99 = OpVariable %88 Private
  1987. %102 = OpTypeRuntimeArray %68
  1988. %103 = OpTypeStruct %102
  1989. %104 = OpTypePointer StorageBuffer %103
  1990. %105 = OpVariable %104 StorageBuffer
  1991. %109 = OpVariable %88 Private
  1992. %111 = OpVariable %88 Private
  1993. %112 = OpSpecConstantOp %6 CooperativeMatrixLengthNV %71
  1994. %113 = OpSpecConstantOp %78 IAdd %112 %79
  1995. %117 = OpTypeRuntimeArray %68
  1996. %118 = OpTypeStruct %117
  1997. %119 = OpTypePointer StorageBuffer %118
  1998. %120 = OpVariable %119 StorageBuffer
  1999. %123 = OpSpecConstant %78 1
  2000. %124 = OpSpecConstant %78 1
  2001. %125 = OpSpecConstant %78 1
  2002. %126 = OpSpecConstant %78 1
  2003. %127 = OpSpecConstant %6 1
  2004. %128 = OpSpecConstant %6 1
  2005. %129 = OpSpecConstantComposite %19 %127 %128 %34
  2006. %4 = OpFunction %2 None %3
  2007. %5 = OpLabel
  2008. %9 = OpVariable %8 Function
  2009. %18 = OpVariable %8 Function
  2010. %32 = OpVariable %31 Function
  2011. %44 = OpVariable %31 Function
  2012. %52 = OpVariable %31 Function
  2013. %60 = OpVariable %31 Function
  2014. %73 = OpVariable %72 Function
  2015. %91 = OpVariable %72 Function
  2016. %101 = OpVariable %72 Function
  2017. %12 = OpLoad %6 %11
  2018. %14 = OpUMod %6 %12 %13
  2019. %15 = OpLoad %6 %11
  2020. %16 = OpUDiv %6 %15 %13
  2021. %17 = OpCompositeConstruct %7 %14 %16
  2022. OpStore %9 %17
  2023. %22 = OpLoad %19 %21
  2024. %23 = OpVectorShuffle %7 %22 %22 0 1
  2025. %24 = OpCompositeExtract %6 %23 0
  2026. %25 = OpCompositeExtract %6 %23 1
  2027. %26 = OpCompositeConstruct %7 %24 %25
  2028. %28 = OpIMul %7 %26 %27
  2029. %29 = OpLoad %7 %9
  2030. %30 = OpIAdd %7 %28 %29
  2031. OpStore %18 %30
  2032. %35 = OpAccessChain %31 %18 %34
  2033. %36 = OpLoad %6 %35
  2034. %37 = OpIMul %6 %33 %36
  2035. %40 = OpAccessChain %31 %18 %39
  2036. %41 = OpLoad %6 %40
  2037. %42 = OpIMul %6 %38 %41
  2038. %43 = OpIAdd %6 %37 %42
  2039. OpStore %32 %43
  2040. %45 = OpAccessChain %31 %18 %34
  2041. %46 = OpLoad %6 %45
  2042. %47 = OpIMul %6 %33 %46
  2043. %48 = OpAccessChain %31 %18 %39
  2044. %49 = OpLoad %6 %48
  2045. %50 = OpIMul %6 %38 %49
  2046. %51 = OpIAdd %6 %47 %50
  2047. OpStore %44 %51
  2048. %53 = OpAccessChain %31 %18 %34
  2049. %54 = OpLoad %6 %53
  2050. %55 = OpIMul %6 %33 %54
  2051. %56 = OpAccessChain %31 %18 %39
  2052. %57 = OpLoad %6 %56
  2053. %58 = OpIMul %6 %38 %57
  2054. %59 = OpIAdd %6 %55 %58
  2055. OpStore %52 %59
  2056. %61 = OpAccessChain %31 %18 %34
  2057. %62 = OpLoad %6 %61
  2058. %63 = OpIMul %6 %33 %62
  2059. %64 = OpAccessChain %31 %18 %39
  2060. %65 = OpLoad %6 %64
  2061. %66 = OpIMul %6 %38 %65
  2062. %67 = OpIAdd %6 %63 %66
  2063. OpStore %60 %67
  2064. %80 = OpLoad %6 %32
  2065. %83 = OpAccessChain %82 %77 %79 %80
  2066. %87 = OpCooperativeMatrixLoadNV %71 %83 %84 %86 )" +
  2067. loadMemoryAccess + R"( %81
  2068. OpStore %73 %87
  2069. %90 = OpLoad %71 %73
  2070. OpStore %89 %90
  2071. %96 = OpLoad %6 %44
  2072. %97 = OpAccessChain %82 %95 %79 %96
  2073. %98 = OpCooperativeMatrixLoadNV %71 %97 %84 %86 MakePointerVisibleKHR|NonPrivatePointerKHR %81
  2074. OpStore %91 %98
  2075. %100 = OpLoad %71 %91
  2076. OpStore %99 %100
  2077. %106 = OpLoad %6 %52
  2078. %107 = OpAccessChain %82 %105 %79 %106
  2079. %108 = OpCooperativeMatrixLoadNV %71 %107 %84 %86 MakePointerVisibleKHR|NonPrivatePointerKHR %81
  2080. OpStore %101 %108
  2081. %110 = OpLoad %71 %101
  2082. OpStore %109 %110
  2083. %114 = OpConvertSToF %68 %113
  2084. %115 = OpCompositeConstruct %71 %114
  2085. OpStore %111 %115
  2086. %116 = OpLoad %71 %111
  2087. %121 = OpLoad %6 %60
  2088. %122 = OpAccessChain %82 %120 %79 %121
  2089. OpCooperativeMatrixStoreNV %122 %116 %84 %86 )" + storeMemoryAccess + R"( %81
  2090. OpReturn
  2091. OpFunctionEnd
  2092. )";
  2093. return s;
  2094. }
  2095. TEST_F(ValidateMemory, CoopMatLoadStoreSuccess) {
  2096. std::string spirv =
  2097. GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
  2098. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  2099. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2100. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2101. }
  2102. TEST_F(ValidateMemory, CoopMatStoreMemoryAccessFail) {
  2103. std::string spirv =
  2104. GenCoopMatLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR",
  2105. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  2106. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2107. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2108. EXPECT_THAT(getDiagnosticString(),
  2109. HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
  2110. }
  2111. TEST_F(ValidateMemory, CoopMatLoadMemoryAccessFail) {
  2112. std::string spirv =
  2113. GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
  2114. "MakePointerAvailableKHR|NonPrivatePointerKHR");
  2115. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2116. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2117. EXPECT_THAT(getDiagnosticString(),
  2118. HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
  2119. }
  2120. TEST_F(ValidateMemory, CoopMatInvalidStorageClassFail) {
  2121. const std::string body =
  2122. R"(
  2123. OpCapability Shader
  2124. OpCapability Float16
  2125. OpCapability CooperativeMatrixNV
  2126. OpExtension "SPV_NV_cooperative_matrix"
  2127. OpMemoryModel Logical GLSL450
  2128. OpEntryPoint GLCompute %main "main"
  2129. %void = OpTypeVoid
  2130. %func = OpTypeFunction %void
  2131. %f16 = OpTypeFloat 16
  2132. %u32 = OpTypeInt 32 0
  2133. %u32_8 = OpConstant %u32 8
  2134. %subgroup = OpConstant %u32 3
  2135. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  2136. %str = OpTypeStruct %f16mat
  2137. %str_ptr = OpTypePointer Workgroup %str
  2138. %sh = OpVariable %str_ptr Workgroup
  2139. %main = OpFunction %void None %func
  2140. %main_entry = OpLabel
  2141. OpReturn
  2142. OpFunctionEnd)";
  2143. CompileSuccessfully(body.c_str());
  2144. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2145. EXPECT_THAT(
  2146. getDiagnosticString(),
  2147. HasSubstr(
  2148. "Cooperative matrix types (or types containing them) can only be "
  2149. "allocated in Function or Private storage classes or as function "
  2150. "parameters"));
  2151. }
  2152. TEST_F(ValidateMemory, CoopMatMatrixLengthResultTypeBad) {
  2153. const std::string body =
  2154. R"(
  2155. OpCapability Shader
  2156. OpCapability Float16
  2157. OpCapability CooperativeMatrixNV
  2158. OpExtension "SPV_NV_cooperative_matrix"
  2159. OpMemoryModel Logical GLSL450
  2160. OpEntryPoint GLCompute %main "main"
  2161. %void = OpTypeVoid
  2162. %func = OpTypeFunction %void
  2163. %f16 = OpTypeFloat 16
  2164. %u32 = OpTypeInt 32 0
  2165. %i32 = OpTypeInt 32 1
  2166. %u32_8 = OpConstant %u32 8
  2167. %subgroup = OpConstant %u32 3
  2168. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  2169. %main = OpFunction %void None %func
  2170. %main_entry = OpLabel
  2171. %1 = OpCooperativeMatrixLengthNV %i32 %f16mat
  2172. OpReturn
  2173. OpFunctionEnd)";
  2174. CompileSuccessfully(body.c_str());
  2175. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2176. EXPECT_THAT(
  2177. getDiagnosticString(),
  2178. HasSubstr("The Result Type of OpCooperativeMatrixLengthNV <id> "
  2179. "'11[%11]' must be OpTypeInt with width 32 and signedness 0"));
  2180. }
  2181. TEST_F(ValidateMemory, CoopMatMatrixLengthOperandTypeBad) {
  2182. const std::string body =
  2183. R"(
  2184. OpCapability Shader
  2185. OpCapability Float16
  2186. OpCapability CooperativeMatrixNV
  2187. OpExtension "SPV_NV_cooperative_matrix"
  2188. OpMemoryModel Logical GLSL450
  2189. OpEntryPoint GLCompute %main "main"
  2190. %void = OpTypeVoid
  2191. %func = OpTypeFunction %void
  2192. %f16 = OpTypeFloat 16
  2193. %u32 = OpTypeInt 32 0
  2194. %i32 = OpTypeInt 32 1
  2195. %u32_8 = OpConstant %u32 8
  2196. %subgroup = OpConstant %u32 3
  2197. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  2198. %main = OpFunction %void None %func
  2199. %main_entry = OpLabel
  2200. %1 = OpCooperativeMatrixLengthNV %u32 %u32
  2201. OpReturn
  2202. OpFunctionEnd)";
  2203. CompileSuccessfully(body.c_str());
  2204. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2205. EXPECT_THAT(
  2206. getDiagnosticString(),
  2207. HasSubstr("The type in OpCooperativeMatrixLengthNV <id> '5[%uint]' "
  2208. "must be OpTypeCooperativeMatrixNV"));
  2209. }
  2210. TEST_F(ValidateMemory, CoopMatMatrixLengthGood) {
  2211. const std::string body =
  2212. R"(
  2213. OpCapability Shader
  2214. OpCapability Float16
  2215. OpCapability CooperativeMatrixNV
  2216. OpExtension "SPV_NV_cooperative_matrix"
  2217. OpMemoryModel Logical GLSL450
  2218. OpEntryPoint GLCompute %main "main"
  2219. %void = OpTypeVoid
  2220. %func = OpTypeFunction %void
  2221. %f16 = OpTypeFloat 16
  2222. %u32 = OpTypeInt 32 0
  2223. %i32 = OpTypeInt 32 1
  2224. %u32_8 = OpConstant %u32 8
  2225. %subgroup = OpConstant %u32 3
  2226. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  2227. %main = OpFunction %void None %func
  2228. %main_entry = OpLabel
  2229. %1 = OpCooperativeMatrixLengthNV %u32 %f16mat
  2230. OpReturn
  2231. OpFunctionEnd)";
  2232. CompileSuccessfully(body.c_str());
  2233. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2234. }
  2235. std::string GenCoopMatLoadStoreShaderKHR(const std::string& storeMemoryAccess,
  2236. const std::string& loadMemoryAccess,
  2237. unsigned layout = 0,
  2238. bool useSpecConstantLayout = false,
  2239. bool useStoreStride = true,
  2240. bool useLoadStride = true) {
  2241. std::string s = R"(
  2242. OpCapability Shader
  2243. OpCapability GroupNonUniform
  2244. OpCapability VulkanMemoryModelKHR
  2245. OpCapability CooperativeMatrixKHR
  2246. OpExtension "SPV_KHR_vulkan_memory_model"
  2247. OpExtension "SPV_KHR_cooperative_matrix"
  2248. %1 = OpExtInstImport "GLSL.std.450"
  2249. OpMemoryModel Logical VulkanKHR
  2250. OpEntryPoint GLCompute %4 "main" %11 %21
  2251. OpExecutionMode %4 LocalSize 1 1 1
  2252. OpDecorate %11 BuiltIn SubgroupId
  2253. OpDecorate %21 BuiltIn WorkgroupId
  2254. OpDecorate %74 ArrayStride 4
  2255. OpMemberDecorate %75 0 Offset 0
  2256. OpDecorate %75 Block
  2257. OpDecorate %77 DescriptorSet 0
  2258. OpDecorate %77 Binding 0
  2259. OpDecorate %92 ArrayStride 4
  2260. OpMemberDecorate %93 0 Offset 0
  2261. OpDecorate %93 Block
  2262. OpDecorate %95 DescriptorSet 0
  2263. OpDecorate %95 Binding 1
  2264. OpDecorate %102 ArrayStride 4
  2265. OpMemberDecorate %103 0 Offset 0
  2266. OpDecorate %103 Block
  2267. OpDecorate %105 DescriptorSet 0
  2268. OpDecorate %105 Binding 2
  2269. OpDecorate %117 ArrayStride 4
  2270. OpMemberDecorate %118 0 Offset 0
  2271. OpDecorate %118 Block
  2272. OpDecorate %120 DescriptorSet 0
  2273. OpDecorate %120 Binding 3
  2274. OpDecorate %123 SpecId 2
  2275. OpDecorate %124 SpecId 3
  2276. OpDecorate %125 SpecId 4
  2277. OpDecorate %126 SpecId 5
  2278. OpDecorate %127 SpecId 0
  2279. OpDecorate %128 SpecId 1
  2280. OpDecorate %129 BuiltIn WorkgroupSize
  2281. %2 = OpTypeVoid
  2282. %3 = OpTypeFunction %2
  2283. %6 = OpTypeInt 32 0
  2284. %7 = OpTypeVector %6 2
  2285. %8 = OpTypePointer Function %7
  2286. %10 = OpTypePointer Input %6
  2287. %11 = OpVariable %10 Input
  2288. %13 = OpConstant %6 2
  2289. %19 = OpTypeVector %6 3
  2290. %20 = OpTypePointer Input %19
  2291. %21 = OpVariable %20 Input
  2292. %27 = OpConstantComposite %7 %13 %13
  2293. %31 = OpTypePointer Function %6
  2294. %33 = OpConstant %6 1024
  2295. %34 = OpConstant %6 1
  2296. %38 = OpConstant %6 8
  2297. %uint_0 = OpConstant %6 0
  2298. )";
  2299. if (useSpecConstantLayout) {
  2300. s += "%layout = OpSpecConstant %6 " + std::to_string(layout);
  2301. } else {
  2302. s += "%layout = OpConstant %6 " + std::to_string(layout);
  2303. }
  2304. s += R"(
  2305. %68 = OpTypeFloat 32
  2306. %69 = OpConstant %6 16
  2307. %70 = OpConstant %6 3
  2308. %71 = OpTypeCooperativeMatrixKHR %68 %70 %69 %38 %uint_0
  2309. %72 = OpTypePointer Function %71
  2310. %74 = OpTypeRuntimeArray %68
  2311. %75 = OpTypeStruct %74
  2312. %76 = OpTypePointer StorageBuffer %75
  2313. %77 = OpVariable %76 StorageBuffer
  2314. %78 = OpTypeInt 32 1
  2315. %79 = OpConstant %78 0
  2316. %81 = OpConstant %6 5
  2317. %82 = OpTypePointer StorageBuffer %68
  2318. %stride = OpConstant %6 64
  2319. %88 = OpTypePointer Private %71
  2320. %89 = OpVariable %88 Private
  2321. %92 = OpTypeRuntimeArray %68
  2322. %93 = OpTypeStruct %92
  2323. %94 = OpTypePointer StorageBuffer %93
  2324. %95 = OpVariable %94 StorageBuffer
  2325. %99 = OpVariable %88 Private
  2326. %102 = OpTypeRuntimeArray %68
  2327. %103 = OpTypeStruct %102
  2328. %104 = OpTypePointer StorageBuffer %103
  2329. %105 = OpVariable %104 StorageBuffer
  2330. %109 = OpVariable %88 Private
  2331. %111 = OpVariable %88 Private
  2332. %112 = OpSpecConstantOp %6 CooperativeMatrixLengthKHR %71
  2333. %113 = OpSpecConstantOp %78 IAdd %112 %79
  2334. %117 = OpTypeRuntimeArray %68
  2335. %118 = OpTypeStruct %117
  2336. %119 = OpTypePointer StorageBuffer %118
  2337. %120 = OpVariable %119 StorageBuffer
  2338. %123 = OpSpecConstant %78 1
  2339. %124 = OpSpecConstant %78 1
  2340. %125 = OpSpecConstant %78 1
  2341. %126 = OpSpecConstant %78 1
  2342. %127 = OpSpecConstant %6 1
  2343. %128 = OpSpecConstant %6 1
  2344. %129 = OpSpecConstantComposite %19 %127 %128 %34
  2345. %4 = OpFunction %2 None %3
  2346. %5 = OpLabel
  2347. %9 = OpVariable %8 Function
  2348. %18 = OpVariable %8 Function
  2349. %32 = OpVariable %31 Function
  2350. %44 = OpVariable %31 Function
  2351. %52 = OpVariable %31 Function
  2352. %60 = OpVariable %31 Function
  2353. %73 = OpVariable %72 Function
  2354. %91 = OpVariable %72 Function
  2355. %101 = OpVariable %72 Function
  2356. %12 = OpLoad %6 %11
  2357. %14 = OpUMod %6 %12 %13
  2358. %15 = OpLoad %6 %11
  2359. %16 = OpUDiv %6 %15 %13
  2360. %17 = OpCompositeConstruct %7 %14 %16
  2361. OpStore %9 %17
  2362. %22 = OpLoad %19 %21
  2363. %23 = OpVectorShuffle %7 %22 %22 0 1
  2364. %24 = OpCompositeExtract %6 %23 0
  2365. %25 = OpCompositeExtract %6 %23 1
  2366. %26 = OpCompositeConstruct %7 %24 %25
  2367. %28 = OpIMul %7 %26 %27
  2368. %29 = OpLoad %7 %9
  2369. %30 = OpIAdd %7 %28 %29
  2370. OpStore %18 %30
  2371. %35 = OpAccessChain %31 %18 %34
  2372. %36 = OpLoad %6 %35
  2373. %37 = OpIMul %6 %33 %36
  2374. %40 = OpAccessChain %31 %18 %uint_0
  2375. %41 = OpLoad %6 %40
  2376. %42 = OpIMul %6 %38 %41
  2377. %43 = OpIAdd %6 %37 %42
  2378. OpStore %32 %43
  2379. %45 = OpAccessChain %31 %18 %34
  2380. %46 = OpLoad %6 %45
  2381. %47 = OpIMul %6 %33 %46
  2382. %48 = OpAccessChain %31 %18 %uint_0
  2383. %49 = OpLoad %6 %48
  2384. %50 = OpIMul %6 %38 %49
  2385. %51 = OpIAdd %6 %47 %50
  2386. OpStore %44 %51
  2387. %53 = OpAccessChain %31 %18 %34
  2388. %54 = OpLoad %6 %53
  2389. %55 = OpIMul %6 %33 %54
  2390. %56 = OpAccessChain %31 %18 %uint_0
  2391. %57 = OpLoad %6 %56
  2392. %58 = OpIMul %6 %38 %57
  2393. %59 = OpIAdd %6 %55 %58
  2394. OpStore %52 %59
  2395. %61 = OpAccessChain %31 %18 %34
  2396. %62 = OpLoad %6 %61
  2397. %63 = OpIMul %6 %33 %62
  2398. %64 = OpAccessChain %31 %18 %uint_0
  2399. %65 = OpLoad %6 %64
  2400. %66 = OpIMul %6 %38 %65
  2401. %67 = OpIAdd %6 %63 %66
  2402. OpStore %60 %67
  2403. %80 = OpLoad %6 %32
  2404. %83 = OpAccessChain %82 %77 %79 %80
  2405. )";
  2406. if (useLoadStride) {
  2407. s += "%87 = OpCooperativeMatrixLoadKHR %71 %83 %layout %stride " +
  2408. loadMemoryAccess + " %81";
  2409. } else {
  2410. s += "%87 = OpCooperativeMatrixLoadKHR %71 %83 %layout";
  2411. }
  2412. s += R"(
  2413. OpStore %73 %87
  2414. %90 = OpLoad %71 %73
  2415. OpStore %89 %90
  2416. %96 = OpLoad %6 %44
  2417. %97 = OpAccessChain %82 %95 %79 %96
  2418. %98 = OpCooperativeMatrixLoadKHR %71 %97 %layout %stride MakePointerVisibleKHR|NonPrivatePointerKHR %81
  2419. OpStore %91 %98
  2420. %100 = OpLoad %71 %91
  2421. OpStore %99 %100
  2422. %106 = OpLoad %6 %52
  2423. %107 = OpAccessChain %82 %105 %79 %106
  2424. %108 = OpCooperativeMatrixLoadKHR %71 %107 %layout %stride MakePointerVisibleKHR|NonPrivatePointerKHR %81
  2425. OpStore %101 %108
  2426. %110 = OpLoad %71 %101
  2427. OpStore %109 %110
  2428. %114 = OpConvertSToF %68 %113
  2429. %115 = OpCompositeConstruct %71 %114
  2430. OpStore %111 %115
  2431. %116 = OpLoad %71 %111
  2432. %121 = OpLoad %6 %60
  2433. %122 = OpAccessChain %82 %120 %79 %121
  2434. )";
  2435. if (useStoreStride) {
  2436. s += "OpCooperativeMatrixStoreKHR %122 %116 %layout %stride " +
  2437. storeMemoryAccess + " %81";
  2438. } else {
  2439. s += "OpCooperativeMatrixStoreKHR %122 %116 %layout";
  2440. }
  2441. s += R"(
  2442. OpReturn
  2443. OpFunctionEnd
  2444. )";
  2445. return s;
  2446. }
  2447. TEST_F(ValidateMemory, CoopMatKHRLoadStoreSuccess) {
  2448. std::string spirv = GenCoopMatLoadStoreShaderKHR(
  2449. "MakePointerAvailableKHR|NonPrivatePointerKHR",
  2450. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  2451. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2452. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2453. }
  2454. struct StrideMissingCase {
  2455. unsigned layout;
  2456. bool useLoadStride;
  2457. bool useStoreStride;
  2458. };
  2459. using ValidateCoopMatrixStrideMissing =
  2460. spvtest::ValidateBase<StrideMissingCase>;
  2461. INSTANTIATE_TEST_SUITE_P(
  2462. CoopMatrixStrideMissing, ValidateCoopMatrixStrideMissing,
  2463. Values(
  2464. StrideMissingCase{(unsigned)spv::CooperativeMatrixLayout::RowMajorKHR,
  2465. false, true},
  2466. StrideMissingCase{(unsigned)spv::CooperativeMatrixLayout::RowMajorKHR,
  2467. true, false},
  2468. StrideMissingCase{
  2469. (unsigned)spv::CooperativeMatrixLayout::ColumnMajorKHR, false,
  2470. true},
  2471. StrideMissingCase{
  2472. (unsigned)spv::CooperativeMatrixLayout::ColumnMajorKHR, true,
  2473. false}));
  2474. TEST_P(ValidateCoopMatrixStrideMissing, CoopMatKHRLoadStrideMissingFail) {
  2475. const StrideMissingCase& param = GetParam();
  2476. std::string spirv = GenCoopMatLoadStoreShaderKHR(
  2477. "MakePointerAvailableKHR|NonPrivatePointerKHR",
  2478. "MakePointerVisibleKHR|NonPrivatePointerKHR", param.layout,
  2479. false /*useSpecConstantLayout*/, param.useStoreStride,
  2480. param.useLoadStride);
  2481. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  2482. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2483. EXPECT_THAT(getDiagnosticString(),
  2484. HasSubstr("MemoryLayout " + std::to_string(param.layout) +
  2485. " requires a Stride"));
  2486. }
  2487. TEST_F(ValidateMemory, CoopMatKHRMemoryLayoutFromSpecConstantSuccess) {
  2488. std::string spirv = GenCoopMatLoadStoreShaderKHR(
  2489. "MakePointerAvailableKHR|NonPrivatePointerKHR",
  2490. "MakePointerVisibleKHR|NonPrivatePointerKHR",
  2491. (unsigned)spv::CooperativeMatrixLayout::RowMajorKHR,
  2492. true /*useSpecConstantLayout*/);
  2493. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2494. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2495. }
  2496. TEST_F(ValidateMemory, CoopMatKHRStoreMemoryAccessFail) {
  2497. std::string spirv = GenCoopMatLoadStoreShaderKHR(
  2498. "MakePointerVisibleKHR|NonPrivatePointerKHR",
  2499. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  2500. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2501. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2502. EXPECT_THAT(getDiagnosticString(),
  2503. HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
  2504. }
  2505. TEST_F(ValidateMemory, CoopMatKHRLoadMemoryAccessFail) {
  2506. std::string spirv = GenCoopMatLoadStoreShaderKHR(
  2507. "MakePointerAvailableKHR|NonPrivatePointerKHR",
  2508. "MakePointerAvailableKHR|NonPrivatePointerKHR");
  2509. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2510. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2511. EXPECT_THAT(getDiagnosticString(),
  2512. HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
  2513. }
  2514. TEST_F(ValidateMemory, CoopMatKHRInvalidStorageClassFail) {
  2515. const std::string body = R"(
  2516. OpCapability Shader
  2517. OpCapability Float16
  2518. OpCapability CooperativeMatrixKHR
  2519. OpExtension "SPV_KHR_cooperative_matrix"
  2520. OpExtension "SPV_KHR_vulkan_memory_model"
  2521. OpMemoryModel Logical GLSL450
  2522. OpEntryPoint GLCompute %main "main"
  2523. %void = OpTypeVoid
  2524. %func = OpTypeFunction %void
  2525. %f16 = OpTypeFloat 16
  2526. %u32 = OpTypeInt 32 0
  2527. %u32_8 = OpConstant %u32 8
  2528. %use_A = OpConstant %u32 0
  2529. %subgroup = OpConstant %u32 3
  2530. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  2531. %str = OpTypeStruct %f16mat
  2532. %str_ptr = OpTypePointer Workgroup %str
  2533. %sh = OpVariable %str_ptr Workgroup
  2534. %main = OpFunction %void None %func
  2535. %main_entry = OpLabel
  2536. OpReturn
  2537. OpFunctionEnd)";
  2538. CompileSuccessfully(body.c_str());
  2539. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2540. EXPECT_THAT(
  2541. getDiagnosticString(),
  2542. HasSubstr(
  2543. "Cooperative matrix types (or types containing them) can only be "
  2544. "allocated in Function or Private storage classes or as function "
  2545. "parameters"));
  2546. }
  2547. TEST_F(ValidateMemory, CoopMatMatrixKHRLengthResultTypeBad) {
  2548. const std::string body = R"(
  2549. OpCapability Shader
  2550. OpCapability Float16
  2551. OpCapability CooperativeMatrixKHR
  2552. OpExtension "SPV_KHR_cooperative_matrix"
  2553. OpExtension "SPV_KHR_vulkan_memory_model"
  2554. OpMemoryModel Logical GLSL450
  2555. OpEntryPoint GLCompute %main "main"
  2556. %void = OpTypeVoid
  2557. %func = OpTypeFunction %void
  2558. %f16 = OpTypeFloat 16
  2559. %u32 = OpTypeInt 32 0
  2560. %i32 = OpTypeInt 32 1
  2561. %u32_8 = OpConstant %u32 8
  2562. %use_A = OpConstant %u32 0
  2563. %subgroup = OpConstant %u32 3
  2564. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  2565. %main = OpFunction %void None %func
  2566. %main_entry = OpLabel
  2567. %1 = OpCooperativeMatrixLengthKHR %i32 %f16mat
  2568. OpReturn
  2569. OpFunctionEnd)";
  2570. CompileSuccessfully(body.c_str());
  2571. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2572. EXPECT_THAT(
  2573. getDiagnosticString(),
  2574. HasSubstr("The Result Type of OpCooperativeMatrixLengthKHR <id> "
  2575. "'12[%12]' must be OpTypeInt with width 32 and signedness 0"));
  2576. }
  2577. TEST_F(ValidateMemory, CoopMatMatrixKHRLengthOperandTypeBad) {
  2578. const std::string body =
  2579. R"(
  2580. OpCapability Shader
  2581. OpCapability Float16
  2582. OpCapability CooperativeMatrixKHR
  2583. OpExtension "SPV_KHR_cooperative_matrix"
  2584. OpExtension "SPV_KHR_vulkan_memory_model"
  2585. OpMemoryModel Logical GLSL450
  2586. OpEntryPoint GLCompute %main "main"
  2587. %void = OpTypeVoid
  2588. %func = OpTypeFunction %void
  2589. %f16 = OpTypeFloat 16
  2590. %u32 = OpTypeInt 32 0
  2591. %i32 = OpTypeInt 32 1
  2592. %u32_8 = OpConstant %u32 8
  2593. %use_A = OpConstant %u32 0
  2594. %subgroup = OpConstant %u32 3
  2595. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  2596. %main = OpFunction %void None %func
  2597. %main_entry = OpLabel
  2598. %1 = OpCooperativeMatrixLengthKHR %u32 %u32
  2599. OpReturn
  2600. OpFunctionEnd)";
  2601. CompileSuccessfully(body.c_str());
  2602. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2603. EXPECT_THAT(
  2604. getDiagnosticString(),
  2605. HasSubstr("The type in OpCooperativeMatrixLengthKHR <id> '5[%uint]' "
  2606. "must be OpTypeCooperativeMatrixKHR"));
  2607. }
  2608. TEST_F(ValidateMemory, CoopMatMatrixKHRLengthGood) {
  2609. const std::string body =
  2610. R"(
  2611. OpCapability Shader
  2612. OpCapability Float16
  2613. OpCapability CooperativeMatrixKHR
  2614. OpExtension "SPV_KHR_cooperative_matrix"
  2615. OpExtension "SPV_KHR_vulkan_memory_model"
  2616. OpMemoryModel Logical GLSL450
  2617. OpEntryPoint GLCompute %main "main"
  2618. %void = OpTypeVoid
  2619. %func = OpTypeFunction %void
  2620. %f16 = OpTypeFloat 16
  2621. %u32 = OpTypeInt 32 0
  2622. %i32 = OpTypeInt 32 1
  2623. %u32_8 = OpConstant %u32 8
  2624. %use_A = OpConstant %u32 0
  2625. %subgroup = OpConstant %u32 3
  2626. %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
  2627. %main = OpFunction %void None %func
  2628. %main_entry = OpLabel
  2629. %1 = OpCooperativeMatrixLengthKHR %u32 %f16mat
  2630. OpReturn
  2631. OpFunctionEnd)";
  2632. CompileSuccessfully(body.c_str());
  2633. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  2634. }
  2635. TEST_F(ValidateMemory, VulkanRTAOutsideOfStructBad) {
  2636. std::string spirv = R"(
  2637. OpCapability Shader
  2638. OpMemoryModel Logical GLSL450
  2639. OpEntryPoint Fragment %func "func"
  2640. OpExecutionMode %func OriginUpperLeft
  2641. %sampler_t = OpTypeSampler
  2642. %array_t = OpTypeRuntimeArray %sampler_t
  2643. %array_ptr = OpTypePointer UniformConstant %array_t
  2644. %2 = OpVariable %array_ptr UniformConstant
  2645. %void = OpTypeVoid
  2646. %func_t = OpTypeFunction %void
  2647. %func = OpFunction %void None %func_t
  2648. %1 = OpLabel
  2649. OpReturn
  2650. OpFunctionEnd
  2651. )";
  2652. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2653. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2654. EXPECT_THAT(getDiagnosticString(),
  2655. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2656. EXPECT_THAT(
  2657. getDiagnosticString(),
  2658. HasSubstr(
  2659. "OpVariable, <id> '5[%5]', is attempting to create memory for an "
  2660. "illegal type, OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray "
  2661. "can only appear as the final member of an OpTypeStruct, thus cannot "
  2662. "be instantiated via OpVariable\n %5 = OpVariable "
  2663. "%_ptr_UniformConstant__runtimearr_2 UniformConstant\n"));
  2664. }
  2665. TEST_F(ValidateMemory, VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayGood) {
  2666. std::string spirv = R"(
  2667. OpCapability Shader
  2668. OpCapability RuntimeDescriptorArrayEXT
  2669. OpExtension "SPV_EXT_descriptor_indexing"
  2670. OpMemoryModel Logical GLSL450
  2671. OpEntryPoint Fragment %func "func"
  2672. OpExecutionMode %func OriginUpperLeft
  2673. OpDecorate %struct Block
  2674. OpMemberDecorate %struct 0 Offset 0
  2675. %sampler_t = OpTypeSampler
  2676. %uint = OpTypeInt 32 0
  2677. %array_t = OpTypeRuntimeArray %sampler_t
  2678. %struct = OpTypeStruct %uint
  2679. %sb_array_t = OpTypeRuntimeArray %struct
  2680. %array_sb_ptr = OpTypePointer StorageBuffer %sb_array_t
  2681. %2 = OpVariable %array_sb_ptr StorageBuffer
  2682. %array_uc_ptr = OpTypePointer UniformConstant %array_t
  2683. %3 = OpVariable %array_uc_ptr UniformConstant
  2684. %void = OpTypeVoid
  2685. %func_t = OpTypeFunction %void
  2686. %func = OpFunction %void None %func_t
  2687. %1 = OpLabel
  2688. OpReturn
  2689. OpFunctionEnd
  2690. )";
  2691. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2692. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2693. }
  2694. TEST_F(
  2695. ValidateMemory,
  2696. VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayAndWrongStorageClassBad) {
  2697. std::string spirv = R"(
  2698. OpCapability Shader
  2699. OpCapability RuntimeDescriptorArrayEXT
  2700. OpExtension "SPV_EXT_descriptor_indexing"
  2701. OpMemoryModel Logical GLSL450
  2702. OpEntryPoint Fragment %func "func"
  2703. OpExecutionMode %func OriginUpperLeft
  2704. %uint_t = OpTypeInt 32 0
  2705. %array_t = OpTypeRuntimeArray %uint_t
  2706. %array_ptr = OpTypePointer Workgroup %array_t
  2707. %2 = OpVariable %array_ptr Workgroup
  2708. %void = OpTypeVoid
  2709. %func_t = OpTypeFunction %void
  2710. %func = OpFunction %void None %func_t
  2711. %1 = OpLabel
  2712. OpReturn
  2713. OpFunctionEnd
  2714. )";
  2715. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2716. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2717. EXPECT_THAT(getDiagnosticString(),
  2718. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2719. EXPECT_THAT(
  2720. getDiagnosticString(),
  2721. HasSubstr("For Vulkan with RuntimeDescriptorArrayEXT, a variable "
  2722. "containing OpTypeRuntimeArray must have storage class of "
  2723. "StorageBuffer, Uniform, or UniformConstant.\n %5 = "
  2724. "OpVariable %_ptr_Workgroup__runtimearr_uint Workgroup\n"));
  2725. }
  2726. TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructGood) {
  2727. std::string spirv = R"(
  2728. OpCapability Shader
  2729. OpMemoryModel Logical GLSL450
  2730. OpEntryPoint Fragment %func "func"
  2731. OpExecutionMode %func OriginUpperLeft
  2732. OpDecorate %array_t ArrayStride 4
  2733. OpMemberDecorate %struct_t 0 Offset 0
  2734. OpDecorate %struct_t Block
  2735. %uint_t = OpTypeInt 32 0
  2736. %array_t = OpTypeRuntimeArray %uint_t
  2737. %struct_t = OpTypeStruct %array_t
  2738. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2739. %2 = OpVariable %struct_ptr StorageBuffer
  2740. %void = OpTypeVoid
  2741. %func_t = OpTypeFunction %void
  2742. %func = OpFunction %void None %func_t
  2743. %1 = OpLabel
  2744. OpReturn
  2745. OpFunctionEnd
  2746. )";
  2747. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2748. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2749. }
  2750. TEST_F(ValidateMemory, VulkanRTAInsideWrongStorageClassStructBad) {
  2751. std::string spirv = R"(
  2752. OpCapability Shader
  2753. OpMemoryModel Logical GLSL450
  2754. OpEntryPoint Fragment %func "func"
  2755. OpExecutionMode %func OriginUpperLeft
  2756. OpDecorate %struct_t Block
  2757. %uint_t = OpTypeInt 32 0
  2758. %array_t = OpTypeRuntimeArray %uint_t
  2759. %struct_t = OpTypeStruct %array_t
  2760. %struct_ptr = OpTypePointer Workgroup %struct_t
  2761. %2 = OpVariable %struct_ptr Workgroup
  2762. %void = OpTypeVoid
  2763. %func_t = OpTypeFunction %void
  2764. %func = OpFunction %void None %func_t
  2765. %1 = OpLabel
  2766. OpReturn
  2767. OpFunctionEnd
  2768. )";
  2769. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2770. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2771. EXPECT_THAT(getDiagnosticString(),
  2772. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2773. EXPECT_THAT(
  2774. getDiagnosticString(),
  2775. HasSubstr(
  2776. "For Vulkan, OpTypeStruct variables containing OpTypeRuntimeArray "
  2777. "must have storage class of StorageBuffer, PhysicalStorageBuffer, or "
  2778. "Uniform.\n %6 = "
  2779. "OpVariable %_ptr_Workgroup__struct_2 Workgroup\n"));
  2780. }
  2781. TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructWithoutBlockBad) {
  2782. std::string spirv = R"(
  2783. OpCapability Shader
  2784. OpMemoryModel Logical GLSL450
  2785. OpEntryPoint Fragment %func "func"
  2786. OpExecutionMode %func OriginUpperLeft
  2787. OpDecorate %struct_t BufferBlock
  2788. %uint_t = OpTypeInt 32 0
  2789. %array_t = OpTypeRuntimeArray %uint_t
  2790. %struct_t = OpTypeStruct %array_t
  2791. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2792. %2 = OpVariable %struct_ptr StorageBuffer
  2793. %void = OpTypeVoid
  2794. %func_t = OpTypeFunction %void
  2795. %func = OpFunction %void None %func_t
  2796. %1 = OpLabel
  2797. OpReturn
  2798. OpFunctionEnd
  2799. )";
  2800. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2801. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2802. EXPECT_THAT(getDiagnosticString(),
  2803. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2804. EXPECT_THAT(getDiagnosticString(),
  2805. HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
  2806. "OpTypeRuntimeArray must be decorated with Block if it "
  2807. "has storage class StorageBuffer or "
  2808. "PhysicalStorageBuffer.\n %6 = OpVariable "
  2809. "%_ptr_StorageBuffer__struct_2 StorageBuffer\n"));
  2810. }
  2811. TEST_F(ValidateMemory, VulkanRTAInsideUniformStructGood) {
  2812. std::string spirv = R"(
  2813. OpCapability Shader
  2814. OpMemoryModel Logical GLSL450
  2815. OpEntryPoint Fragment %func "func"
  2816. OpExecutionMode %func OriginUpperLeft
  2817. OpDecorate %array_t ArrayStride 4
  2818. OpMemberDecorate %struct_t 0 Offset 0
  2819. OpDecorate %struct_t BufferBlock
  2820. %uint_t = OpTypeInt 32 0
  2821. %array_t = OpTypeRuntimeArray %uint_t
  2822. %struct_t = OpTypeStruct %array_t
  2823. %struct_ptr = OpTypePointer Uniform %struct_t
  2824. %2 = OpVariable %struct_ptr Uniform
  2825. %void = OpTypeVoid
  2826. %func_t = OpTypeFunction %void
  2827. %func = OpFunction %void None %func_t
  2828. %1 = OpLabel
  2829. OpReturn
  2830. OpFunctionEnd
  2831. )";
  2832. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2833. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2834. }
  2835. TEST_F(ValidateMemory, VulkanRTAInsideUniformStructWithoutBufferBlockBad) {
  2836. std::string spirv = R"(
  2837. OpCapability Shader
  2838. OpMemoryModel Logical GLSL450
  2839. OpEntryPoint Fragment %func "func"
  2840. OpExecutionMode %func OriginUpperLeft
  2841. OpDecorate %struct_t Block
  2842. %uint_t = OpTypeInt 32 0
  2843. %array_t = OpTypeRuntimeArray %uint_t
  2844. %struct_t = OpTypeStruct %array_t
  2845. %struct_ptr = OpTypePointer Uniform %struct_t
  2846. %2 = OpVariable %struct_ptr Uniform
  2847. %void = OpTypeVoid
  2848. %func_t = OpTypeFunction %void
  2849. %func = OpFunction %void None %func_t
  2850. %1 = OpLabel
  2851. OpReturn
  2852. OpFunctionEnd
  2853. )";
  2854. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2855. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2856. EXPECT_THAT(getDiagnosticString(),
  2857. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2858. EXPECT_THAT(getDiagnosticString(),
  2859. HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
  2860. "OpTypeRuntimeArray must be decorated with BufferBlock "
  2861. "if it has storage class Uniform.\n %6 = OpVariable "
  2862. "%_ptr_Uniform__struct_2 Uniform\n"));
  2863. }
  2864. TEST_F(ValidateMemory, VulkanRTAInsideRTABad) {
  2865. std::string spirv = R"(
  2866. OpCapability Shader
  2867. OpMemoryModel Logical GLSL450
  2868. OpEntryPoint Fragment %func "func"
  2869. OpExecutionMode %func OriginUpperLeft
  2870. %sampler_t = OpTypeSampler
  2871. %inner_array_t = OpTypeRuntimeArray %sampler_t
  2872. %array_t = OpTypeRuntimeArray %inner_array_t
  2873. %array_ptr = OpTypePointer UniformConstant %array_t
  2874. %2 = OpVariable %array_ptr UniformConstant
  2875. %void = OpTypeVoid
  2876. %func_t = OpTypeFunction %void
  2877. %func = OpFunction %void None %func_t
  2878. %1 = OpLabel
  2879. OpReturn
  2880. OpFunctionEnd
  2881. )";
  2882. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2883. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2884. EXPECT_THAT(getDiagnosticString(),
  2885. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2886. EXPECT_THAT(
  2887. getDiagnosticString(),
  2888. HasSubstr(
  2889. "OpTypeRuntimeArray Element Type <id> '3[%_runtimearr_2]' is not "
  2890. "valid in Vulkan environments.\n %_runtimearr__runtimearr_2 = "
  2891. "OpTypeRuntimeArray %_runtimearr_2\n"));
  2892. }
  2893. TEST_F(ValidateMemory, VulkanRTAInsideRTAWithRuntimeDescriptorArrayBad) {
  2894. std::string spirv = R"(
  2895. OpCapability RuntimeDescriptorArrayEXT
  2896. OpCapability Shader
  2897. OpExtension "SPV_EXT_descriptor_indexing"
  2898. OpMemoryModel Logical GLSL450
  2899. OpEntryPoint Fragment %func "func"
  2900. OpExecutionMode %func OriginUpperLeft
  2901. OpDecorate %struct Block
  2902. %uint_t = OpTypeInt 32 0
  2903. %inner_array_t = OpTypeRuntimeArray %uint_t
  2904. %array_t = OpTypeRuntimeArray %inner_array_t
  2905. %struct = OpTypeStruct %array_t
  2906. %array_ptr = OpTypePointer StorageBuffer %struct
  2907. %2 = OpVariable %array_ptr StorageBuffer
  2908. %void = OpTypeVoid
  2909. %func_t = OpTypeFunction %void
  2910. %func = OpFunction %void None %func_t
  2911. %1 = OpLabel
  2912. OpReturn
  2913. OpFunctionEnd
  2914. )";
  2915. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2916. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2917. EXPECT_THAT(getDiagnosticString(),
  2918. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2919. EXPECT_THAT(
  2920. getDiagnosticString(),
  2921. HasSubstr(
  2922. "OpTypeRuntimeArray Element Type <id> '4[%_runtimearr_uint]' is not "
  2923. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  2924. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  2925. }
  2926. TEST_F(ValidateMemory,
  2927. VulkanUniformStructInsideRTAWithRuntimeDescriptorArrayGood) {
  2928. std::string spirv = R"(
  2929. OpCapability RuntimeDescriptorArrayEXT
  2930. OpCapability Shader
  2931. OpExtension "SPV_EXT_descriptor_indexing"
  2932. OpMemoryModel Logical GLSL450
  2933. OpEntryPoint Fragment %func "func"
  2934. OpExecutionMode %func OriginUpperLeft
  2935. OpMemberDecorate %struct_t 0 Offset 0
  2936. OpDecorate %struct_t Block
  2937. %uint_t = OpTypeInt 32 0
  2938. %struct_t = OpTypeStruct %uint_t
  2939. %array_t = OpTypeRuntimeArray %struct_t
  2940. %array_ptr = OpTypePointer Uniform %array_t
  2941. %2 = OpVariable %array_ptr Uniform
  2942. %void = OpTypeVoid
  2943. %func_t = OpTypeFunction %void
  2944. %func = OpFunction %void None %func_t
  2945. %1 = OpLabel
  2946. OpReturn
  2947. OpFunctionEnd
  2948. )";
  2949. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2950. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2951. }
  2952. TEST_F(ValidateMemory, VulkanRTAInsideRTAInsideStructBad) {
  2953. std::string spirv = R"(
  2954. OpCapability Shader
  2955. OpMemoryModel Logical GLSL450
  2956. OpEntryPoint Fragment %func "func"
  2957. OpExecutionMode %func OriginUpperLeft
  2958. OpDecorate %array_t ArrayStride 4
  2959. OpMemberDecorate %struct_t 0 Offset 0
  2960. OpDecorate %struct_t Block
  2961. %uint_t = OpTypeInt 32 0
  2962. %inner_array_t = OpTypeRuntimeArray %uint_t
  2963. %array_t = OpTypeRuntimeArray %inner_array_t
  2964. %struct_t = OpTypeStruct %array_t
  2965. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  2966. %2 = OpVariable %struct_ptr StorageBuffer
  2967. %void = OpTypeVoid
  2968. %func_t = OpTypeFunction %void
  2969. %func = OpFunction %void None %func_t
  2970. %1 = OpLabel
  2971. OpReturn
  2972. OpFunctionEnd
  2973. )";
  2974. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  2975. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  2976. EXPECT_THAT(getDiagnosticString(),
  2977. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  2978. EXPECT_THAT(
  2979. getDiagnosticString(),
  2980. HasSubstr(
  2981. "OpTypeRuntimeArray Element Type <id> '5[%_runtimearr_uint]' is not "
  2982. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  2983. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  2984. }
  2985. TEST_F(ValidateMemory,
  2986. VulkanRTAInsideRTAInsideStructWithRuntimeDescriptorArrayBad) {
  2987. std::string spirv = R"(
  2988. OpCapability RuntimeDescriptorArrayEXT
  2989. OpCapability Shader
  2990. OpExtension "SPV_EXT_descriptor_indexing"
  2991. OpMemoryModel Logical GLSL450
  2992. OpEntryPoint Fragment %func "func"
  2993. OpExecutionMode %func OriginUpperLeft
  2994. OpDecorate %array_t ArrayStride 4
  2995. OpMemberDecorate %struct_t 0 Offset 0
  2996. OpDecorate %struct_t Block
  2997. %uint_t = OpTypeInt 32 0
  2998. %inner_array_t = OpTypeRuntimeArray %uint_t
  2999. %array_t = OpTypeRuntimeArray %inner_array_t
  3000. %struct_t = OpTypeStruct %array_t
  3001. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  3002. %2 = OpVariable %struct_ptr StorageBuffer
  3003. %void = OpTypeVoid
  3004. %func_t = OpTypeFunction %void
  3005. %func = OpFunction %void None %func_t
  3006. %1 = OpLabel
  3007. OpReturn
  3008. OpFunctionEnd
  3009. )";
  3010. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3011. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3012. EXPECT_THAT(getDiagnosticString(),
  3013. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  3014. EXPECT_THAT(
  3015. getDiagnosticString(),
  3016. HasSubstr(
  3017. "OpTypeRuntimeArray Element Type <id> '5[%_runtimearr_uint]' is not "
  3018. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  3019. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  3020. }
  3021. TEST_F(ValidateMemory, VulkanRTAInsideArrayBad) {
  3022. std::string spirv = R"(
  3023. OpCapability Shader
  3024. OpMemoryModel Logical GLSL450
  3025. OpEntryPoint Fragment %func "func"
  3026. OpExecutionMode %func OriginUpperLeft
  3027. %uint_t = OpTypeInt 32 0
  3028. %dim = OpConstant %uint_t 1
  3029. %sampler_t = OpTypeSampler
  3030. %inner_array_t = OpTypeRuntimeArray %sampler_t
  3031. %array_t = OpTypeArray %inner_array_t %dim
  3032. %array_ptr = OpTypePointer UniformConstant %array_t
  3033. %2 = OpVariable %array_ptr UniformConstant
  3034. %void = OpTypeVoid
  3035. %func_t = OpTypeFunction %void
  3036. %func = OpFunction %void None %func_t
  3037. %1 = OpLabel
  3038. OpReturn
  3039. OpFunctionEnd
  3040. )";
  3041. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3042. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3043. EXPECT_THAT(getDiagnosticString(),
  3044. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  3045. EXPECT_THAT(
  3046. getDiagnosticString(),
  3047. HasSubstr("OpTypeArray Element Type <id> '5[%_runtimearr_4]' is not "
  3048. "valid in Vulkan environments.\n %_arr__runtimearr_4_uint_1 = "
  3049. "OpTypeArray %_runtimearr_4 %uint_1\n"));
  3050. }
  3051. TEST_F(ValidateMemory, VulkanRTAInsideArrayWithRuntimeDescriptorArrayBad) {
  3052. std::string spirv = R"(
  3053. OpCapability RuntimeDescriptorArrayEXT
  3054. OpCapability Shader
  3055. OpExtension "SPV_EXT_descriptor_indexing"
  3056. OpMemoryModel Logical GLSL450
  3057. OpEntryPoint Fragment %func "func"
  3058. OpExecutionMode %func OriginUpperLeft
  3059. OpDecorate %struct Block
  3060. %uint_t = OpTypeInt 32 0
  3061. %dim = OpConstant %uint_t 1
  3062. %sampler_t = OpTypeSampler
  3063. %inner_array_t = OpTypeRuntimeArray %uint_t
  3064. %array_t = OpTypeRuntimeArray %inner_array_t
  3065. %struct = OpTypeStruct %array_t
  3066. %array_ptr = OpTypePointer StorageBuffer %struct
  3067. %2 = OpVariable %array_ptr StorageBuffer
  3068. %void = OpTypeVoid
  3069. %func_t = OpTypeFunction %void
  3070. %func = OpFunction %void None %func_t
  3071. %1 = OpLabel
  3072. OpReturn
  3073. OpFunctionEnd
  3074. )";
  3075. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3076. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3077. EXPECT_THAT(getDiagnosticString(),
  3078. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  3079. EXPECT_THAT(
  3080. getDiagnosticString(),
  3081. HasSubstr(
  3082. "OpTypeRuntimeArray Element Type <id> '6[%_runtimearr_uint]' is not "
  3083. "valid in Vulkan environments.\n %_runtimearr__runtimearr_uint = "
  3084. "OpTypeRuntimeArray %_runtimearr_uint\n"));
  3085. }
  3086. TEST_F(ValidateMemory, VulkanRTAInsideArrayInsideStructBad) {
  3087. std::string spirv = R"(
  3088. OpCapability Shader
  3089. OpMemoryModel Logical GLSL450
  3090. OpEntryPoint Fragment %func "func"
  3091. OpExecutionMode %func OriginUpperLeft
  3092. OpDecorate %array_t ArrayStride 4
  3093. OpMemberDecorate %struct_t 0 Offset 0
  3094. OpDecorate %struct_t Block
  3095. %uint_t = OpTypeInt 32 0
  3096. %dim = OpConstant %uint_t 1
  3097. %inner_array_t = OpTypeRuntimeArray %uint_t
  3098. %array_t = OpTypeArray %inner_array_t %dim
  3099. %struct_t = OpTypeStruct %array_t
  3100. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  3101. %2 = OpVariable %struct_ptr StorageBuffer
  3102. %void = OpTypeVoid
  3103. %func_t = OpTypeFunction %void
  3104. %func = OpFunction %void None %func_t
  3105. %1 = OpLabel
  3106. OpReturn
  3107. OpFunctionEnd
  3108. )";
  3109. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3110. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3111. EXPECT_THAT(getDiagnosticString(),
  3112. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  3113. EXPECT_THAT(
  3114. getDiagnosticString(),
  3115. HasSubstr(
  3116. "OpTypeArray Element Type <id> '6[%_runtimearr_uint]' is not "
  3117. "valid in Vulkan environments.\n %_arr__runtimearr_uint_uint_1 "
  3118. "= OpTypeArray %_runtimearr_uint %uint_1\n"));
  3119. }
  3120. TEST_F(ValidateMemory,
  3121. VulkanRTAInsideArrayInsideStructWithRuntimeDescriptorArrayBad) {
  3122. std::string spirv = R"(
  3123. OpCapability RuntimeDescriptorArrayEXT
  3124. OpCapability Shader
  3125. OpExtension "SPV_EXT_descriptor_indexing"
  3126. OpMemoryModel Logical GLSL450
  3127. OpEntryPoint Fragment %func "func"
  3128. OpExecutionMode %func OriginUpperLeft
  3129. OpDecorate %array_t ArrayStride 4
  3130. OpMemberDecorate %struct_t 0 Offset 0
  3131. OpDecorate %struct_t Block
  3132. %uint_t = OpTypeInt 32 0
  3133. %dim = OpConstant %uint_t 1
  3134. %inner_array_t = OpTypeRuntimeArray %uint_t
  3135. %array_t = OpTypeArray %inner_array_t %dim
  3136. %struct_t = OpTypeStruct %array_t
  3137. %struct_ptr = OpTypePointer StorageBuffer %struct_t
  3138. %2 = OpVariable %struct_ptr StorageBuffer
  3139. %void = OpTypeVoid
  3140. %func_t = OpTypeFunction %void
  3141. %func = OpFunction %void None %func_t
  3142. %1 = OpLabel
  3143. OpReturn
  3144. OpFunctionEnd
  3145. )";
  3146. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3147. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3148. EXPECT_THAT(getDiagnosticString(),
  3149. AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
  3150. EXPECT_THAT(
  3151. getDiagnosticString(),
  3152. HasSubstr(
  3153. "OpTypeArray Element Type <id> '6[%_runtimearr_uint]' is not "
  3154. "valid in Vulkan environments.\n %_arr__runtimearr_uint_uint_1 "
  3155. "= OpTypeArray %_runtimearr_uint %uint_1\n"));
  3156. }
  3157. TEST_F(ValidateMemory, VulkanRTAStructInsideRTAWithRuntimeDescriptorArrayGood) {
  3158. std::string spirv = R"(
  3159. OpCapability RuntimeDescriptorArrayEXT
  3160. OpCapability Shader
  3161. OpExtension "SPV_EXT_descriptor_indexing"
  3162. OpMemoryModel Logical GLSL450
  3163. OpEntryPoint Fragment %func "func"
  3164. OpExecutionMode %func OriginUpperLeft
  3165. OpDecorate %inner_array_t ArrayStride 4
  3166. OpMemberDecorate %struct_t 0 Offset 0
  3167. OpDecorate %struct_t Block
  3168. %uint_t = OpTypeInt 32 0
  3169. %inner_array_t = OpTypeRuntimeArray %uint_t
  3170. %struct_t = OpTypeStruct %inner_array_t
  3171. %array_t = OpTypeRuntimeArray %struct_t
  3172. %array_ptr = OpTypePointer StorageBuffer %array_t
  3173. %2 = OpVariable %array_ptr StorageBuffer
  3174. %void = OpTypeVoid
  3175. %func_t = OpTypeFunction %void
  3176. %func = OpFunction %void None %func_t
  3177. %1 = OpLabel
  3178. OpReturn
  3179. OpFunctionEnd
  3180. )";
  3181. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3182. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3183. }
  3184. TEST_F(ValidateMemory, VulkanRTAStructInsideArrayGood) {
  3185. std::string spirv = R"(
  3186. OpCapability RuntimeDescriptorArrayEXT
  3187. OpCapability Shader
  3188. OpExtension "SPV_EXT_descriptor_indexing"
  3189. OpMemoryModel Logical GLSL450
  3190. OpEntryPoint Fragment %func "func"
  3191. OpExecutionMode %func OriginUpperLeft
  3192. OpDecorate %inner_array_t ArrayStride 4
  3193. OpMemberDecorate %struct_t 0 Offset 0
  3194. OpDecorate %struct_t Block
  3195. %uint_t = OpTypeInt 32 0
  3196. %inner_array_t = OpTypeRuntimeArray %uint_t
  3197. %struct_t = OpTypeStruct %inner_array_t
  3198. %array_size = OpConstant %uint_t 5
  3199. %array_t = OpTypeArray %struct_t %array_size
  3200. %array_ptr = OpTypePointer StorageBuffer %array_t
  3201. %2 = OpVariable %array_ptr StorageBuffer
  3202. %void = OpTypeVoid
  3203. %func_t = OpTypeFunction %void
  3204. %func = OpFunction %void None %func_t
  3205. %1 = OpLabel
  3206. OpReturn
  3207. OpFunctionEnd
  3208. )";
  3209. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
  3210. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3211. }
  3212. TEST_F(ValidateMemory, CopyMemoryNoAccessGood) {
  3213. const std::string spirv = R"(
  3214. OpCapability Shader
  3215. OpCapability Linkage
  3216. OpMemoryModel Logical GLSL450
  3217. %void = OpTypeVoid
  3218. %int = OpTypeInt 32 0
  3219. %int_ptr_priv = OpTypePointer Private %int
  3220. %var1 = OpVariable %int_ptr_priv Private
  3221. %var2 = OpVariable %int_ptr_priv Private
  3222. %voidfn = OpTypeFunction %void
  3223. %func = OpFunction %void None %voidfn
  3224. %entry = OpLabel
  3225. OpCopyMemory %var1 %var2
  3226. OpReturn
  3227. OpFunctionEnd
  3228. )";
  3229. CompileSuccessfully(spirv);
  3230. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3231. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3232. }
  3233. TEST_F(ValidateMemory, CopyMemorySimpleMixedAccessGood) {
  3234. // Test one memory access operand using features that don't require the
  3235. // Vulkan memory model.
  3236. const std::string spirv = R"(
  3237. OpCapability Shader
  3238. OpCapability Linkage
  3239. OpMemoryModel Logical GLSL450
  3240. %void = OpTypeVoid
  3241. %int = OpTypeInt 32 0
  3242. %int_ptr_priv = OpTypePointer Private %int
  3243. %var1 = OpVariable %int_ptr_priv Private
  3244. %var2 = OpVariable %int_ptr_priv Private
  3245. %voidfn = OpTypeFunction %void
  3246. %func = OpFunction %void None %voidfn
  3247. %entry = OpLabel
  3248. OpCopyMemory %var1 %var2 Volatile|Aligned|Nontemporal 4
  3249. OpReturn
  3250. OpFunctionEnd
  3251. )";
  3252. CompileSuccessfully(spirv);
  3253. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3254. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3255. }
  3256. TEST_F(ValidateMemory, CopyMemorySimpleTwoMixedAccessV13Bad) {
  3257. // Two memory access operands is invalid up to SPIR-V 1.3
  3258. const std::string spirv = R"(
  3259. OpCapability Shader
  3260. OpCapability Linkage
  3261. OpMemoryModel Logical GLSL450
  3262. %void = OpTypeVoid
  3263. %int = OpTypeInt 32 0
  3264. %int_ptr_priv = OpTypePointer Private %int
  3265. %var1 = OpVariable %int_ptr_priv Private
  3266. %var2 = OpVariable %int_ptr_priv Private
  3267. %voidfn = OpTypeFunction %void
  3268. %func = OpFunction %void None %voidfn
  3269. %entry = OpLabel
  3270. OpCopyMemory %var1 %var2 Volatile Volatile
  3271. OpReturn
  3272. OpFunctionEnd
  3273. )";
  3274. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3275. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  3276. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3277. EXPECT_THAT(getDiagnosticString(),
  3278. HasSubstr("CopyMemory with two memory access operands requires "
  3279. "SPIR-V 1.4 or later"));
  3280. }
  3281. TEST_F(ValidateMemory, CopyMemorySimpleTwoMixedAccessV14Good) {
  3282. // Two memory access operands is valid in SPIR-V 1.4
  3283. const std::string spirv = R"(
  3284. OpCapability Shader
  3285. OpCapability Linkage
  3286. OpMemoryModel Logical GLSL450
  3287. %void = OpTypeVoid
  3288. %int = OpTypeInt 32 0
  3289. %int_ptr_priv = OpTypePointer Private %int
  3290. %var1 = OpVariable %int_ptr_priv Private
  3291. %var2 = OpVariable %int_ptr_priv Private
  3292. %voidfn = OpTypeFunction %void
  3293. %func = OpFunction %void None %voidfn
  3294. %entry = OpLabel
  3295. OpCopyMemory %var1 %var2 Volatile Volatile
  3296. OpReturn
  3297. OpFunctionEnd
  3298. )";
  3299. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3300. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3301. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3302. }
  3303. TEST_F(ValidateMemory, CopyMemorySizedNoAccessGood) {
  3304. const std::string spirv = R"(
  3305. OpCapability Shader
  3306. OpCapability Linkage
  3307. OpCapability Addresses
  3308. OpMemoryModel Logical GLSL450
  3309. %void = OpTypeVoid
  3310. %int = OpTypeInt 32 0
  3311. %int_16 = OpConstant %int 16
  3312. %int_ptr_priv = OpTypePointer Private %int
  3313. %var1 = OpVariable %int_ptr_priv Private
  3314. %var2 = OpVariable %int_ptr_priv Private
  3315. %voidfn = OpTypeFunction %void
  3316. %func = OpFunction %void None %voidfn
  3317. %entry = OpLabel
  3318. OpCopyMemorySized %var1 %var2 %int_16
  3319. OpReturn
  3320. OpFunctionEnd
  3321. )";
  3322. CompileSuccessfully(spirv);
  3323. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  3324. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3325. }
  3326. TEST_F(ValidateMemory, CopyMemorySizedSimpleMixedAccessGood) {
  3327. // Test one memory access operand using features that don't require the
  3328. // Vulkan memory model.
  3329. const std::string spirv = R"(
  3330. OpCapability Shader
  3331. OpCapability Linkage
  3332. OpCapability Addresses
  3333. OpMemoryModel Logical GLSL450
  3334. %void = OpTypeVoid
  3335. %int = OpTypeInt 32 0
  3336. %int_16 = OpConstant %int 16
  3337. %int_ptr_priv = OpTypePointer Private %int
  3338. %var1 = OpVariable %int_ptr_priv Private
  3339. %var2 = OpVariable %int_ptr_priv Private
  3340. %voidfn = OpTypeFunction %void
  3341. %func = OpFunction %void None %voidfn
  3342. %entry = OpLabel
  3343. OpCopyMemorySized %var1 %var2 %int_16 Volatile|Aligned|Nontemporal 4
  3344. OpReturn
  3345. OpFunctionEnd
  3346. )";
  3347. CompileSuccessfully(spirv);
  3348. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3349. }
  3350. TEST_F(ValidateMemory, CopyMemorySizedSimpleTwoMixedAccessV13Bad) {
  3351. // Two memory access operands is invalid up to SPIR-V 1.3
  3352. const std::string spirv = R"(
  3353. OpCapability Shader
  3354. OpCapability Linkage
  3355. OpCapability Addresses
  3356. OpMemoryModel Logical GLSL450
  3357. %void = OpTypeVoid
  3358. %int = OpTypeInt 32 0
  3359. %int_16 = OpConstant %int 16
  3360. %int_ptr_priv = OpTypePointer Private %int
  3361. %var1 = OpVariable %int_ptr_priv Private
  3362. %var2 = OpVariable %int_ptr_priv Private
  3363. %voidfn = OpTypeFunction %void
  3364. %func = OpFunction %void None %voidfn
  3365. %entry = OpLabel
  3366. OpCopyMemorySized %var1 %var2 %int_16 Volatile Volatile
  3367. OpReturn
  3368. OpFunctionEnd
  3369. )";
  3370. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3371. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  3372. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3373. EXPECT_THAT(
  3374. getDiagnosticString(),
  3375. HasSubstr("CopyMemorySized with two memory access operands requires "
  3376. "SPIR-V 1.4 or later"));
  3377. }
  3378. TEST_F(ValidateMemory, CopyMemorySizedSimpleTwoMixedAccessV14Good) {
  3379. // Two memory access operands is valid in SPIR-V 1.4
  3380. const std::string spirv = R"(
  3381. OpCapability Shader
  3382. OpCapability Linkage
  3383. OpCapability Addresses
  3384. OpMemoryModel Logical GLSL450
  3385. %void = OpTypeVoid
  3386. %int = OpTypeInt 32 0
  3387. %int_16 = OpConstant %int 16
  3388. %int_ptr_priv = OpTypePointer Private %int
  3389. %var1 = OpVariable %int_ptr_priv Private
  3390. %var2 = OpVariable %int_ptr_priv Private
  3391. %voidfn = OpTypeFunction %void
  3392. %func = OpFunction %void None %voidfn
  3393. %entry = OpLabel
  3394. OpCopyMemorySized %var1 %var2 %int_16 Volatile Volatile
  3395. OpReturn
  3396. OpFunctionEnd
  3397. )";
  3398. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3399. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3400. EXPECT_THAT(getDiagnosticString(), Eq(""));
  3401. }
  3402. using ValidatePointerComparisons = spvtest::ValidateBase<std::string>;
  3403. TEST_P(ValidatePointerComparisons, Good) {
  3404. const std::string operation = GetParam();
  3405. std::string spirv = R"(
  3406. OpCapability Shader
  3407. OpCapability Linkage
  3408. OpCapability VariablePointersStorageBuffer
  3409. OpMemoryModel Logical GLSL450
  3410. %void = OpTypeVoid
  3411. %bool = OpTypeBool
  3412. %int = OpTypeInt 32 0
  3413. %ptr_int = OpTypePointer StorageBuffer %int
  3414. %var = OpVariable %ptr_int StorageBuffer
  3415. %func_ty = OpTypeFunction %void
  3416. %func = OpFunction %void None %func_ty
  3417. %1 = OpLabel
  3418. %equal = )" + operation;
  3419. if (operation == "OpPtrDiff") {
  3420. spirv += " %int ";
  3421. } else {
  3422. spirv += " %bool ";
  3423. }
  3424. spirv += R"(%var %var
  3425. OpReturn
  3426. OpFunctionEnd
  3427. )";
  3428. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3429. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3430. }
  3431. TEST_P(ValidatePointerComparisons, GoodWorkgroup) {
  3432. const std::string operation = GetParam();
  3433. std::string spirv = R"(
  3434. OpCapability Shader
  3435. OpCapability Linkage
  3436. OpCapability VariablePointers
  3437. OpMemoryModel Logical GLSL450
  3438. %void = OpTypeVoid
  3439. %bool = OpTypeBool
  3440. %int = OpTypeInt 32 0
  3441. %ptr_int = OpTypePointer Workgroup %int
  3442. %var = OpVariable %ptr_int Workgroup
  3443. %func_ty = OpTypeFunction %void
  3444. %func = OpFunction %void None %func_ty
  3445. %1 = OpLabel
  3446. %equal = )" + operation;
  3447. if (operation == "OpPtrDiff") {
  3448. spirv += " %int ";
  3449. } else {
  3450. spirv += " %bool ";
  3451. }
  3452. spirv += R"(%var %var
  3453. OpReturn
  3454. OpFunctionEnd
  3455. )";
  3456. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3457. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3458. }
  3459. TEST_P(ValidatePointerComparisons, BadResultType) {
  3460. const std::string operation = GetParam();
  3461. std::string spirv = R"(
  3462. OpCapability Shader
  3463. OpCapability Linkage
  3464. OpCapability VariablePointersStorageBuffer
  3465. OpMemoryModel Logical GLSL450
  3466. %void = OpTypeVoid
  3467. %bool = OpTypeBool
  3468. %int = OpTypeInt 32 0
  3469. %ptr_int = OpTypePointer StorageBuffer %int
  3470. %var = OpVariable %ptr_int StorageBuffer
  3471. %func_ty = OpTypeFunction %void
  3472. %func = OpFunction %void None %func_ty
  3473. %1 = OpLabel
  3474. %equal = )" + operation;
  3475. if (operation == "OpPtrDiff") {
  3476. spirv += " %bool ";
  3477. } else {
  3478. spirv += " %int ";
  3479. }
  3480. spirv += R"(%var %var
  3481. OpReturn
  3482. OpFunctionEnd
  3483. )";
  3484. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3485. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3486. if (operation == "OpPtrDiff") {
  3487. EXPECT_THAT(getDiagnosticString(),
  3488. HasSubstr("Result Type must be an integer scalar"));
  3489. } else {
  3490. EXPECT_THAT(getDiagnosticString(),
  3491. HasSubstr("Result Type must be OpTypeBool"));
  3492. }
  3493. }
  3494. TEST_P(ValidatePointerComparisons, BadCapabilities) {
  3495. const std::string operation = GetParam();
  3496. std::string spirv = R"(
  3497. OpCapability Shader
  3498. OpCapability Linkage
  3499. OpMemoryModel Logical GLSL450
  3500. %void = OpTypeVoid
  3501. %bool = OpTypeBool
  3502. %int = OpTypeInt 32 0
  3503. %ptr_int = OpTypePointer StorageBuffer %int
  3504. %var = OpVariable %ptr_int StorageBuffer
  3505. %func_ty = OpTypeFunction %void
  3506. %func = OpFunction %void None %func_ty
  3507. %1 = OpLabel
  3508. %equal = )" + operation;
  3509. if (operation == "OpPtrDiff") {
  3510. spirv += " %int ";
  3511. } else {
  3512. spirv += " %bool ";
  3513. }
  3514. spirv += R"(%var %var
  3515. OpReturn
  3516. OpFunctionEnd
  3517. )";
  3518. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3519. if (operation == "OpPtrDiff") {
  3520. // Gets caught by the grammar.
  3521. EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
  3522. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3523. } else {
  3524. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3525. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3526. EXPECT_THAT(getDiagnosticString(),
  3527. HasSubstr("Instruction cannot for logical addressing model be "
  3528. "used without a variable pointers capability"));
  3529. }
  3530. }
  3531. TEST_P(ValidatePointerComparisons, BadOperandType) {
  3532. const std::string operation = GetParam();
  3533. std::string spirv = R"(
  3534. OpCapability Shader
  3535. OpCapability Linkage
  3536. OpCapability VariablePointersStorageBuffer
  3537. OpMemoryModel Logical GLSL450
  3538. %void = OpTypeVoid
  3539. %bool = OpTypeBool
  3540. %int = OpTypeInt 32 0
  3541. %ptr_int = OpTypePointer StorageBuffer %int
  3542. %var = OpVariable %ptr_int StorageBuffer
  3543. %func_ty = OpTypeFunction %void
  3544. %func = OpFunction %void None %func_ty
  3545. %1 = OpLabel
  3546. %ld = OpLoad %int %var
  3547. %equal = )" + operation;
  3548. if (operation == "OpPtrDiff") {
  3549. spirv += " %int ";
  3550. } else {
  3551. spirv += " %bool ";
  3552. }
  3553. spirv += R"(%ld %ld
  3554. OpReturn
  3555. OpFunctionEnd
  3556. )";
  3557. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3558. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3559. EXPECT_THAT(getDiagnosticString(),
  3560. HasSubstr("Operand type must be a pointer"));
  3561. }
  3562. TEST_P(ValidatePointerComparisons, BadStorageClassWorkgroup) {
  3563. const std::string operation = GetParam();
  3564. std::string spirv = R"(
  3565. OpCapability Shader
  3566. OpCapability Linkage
  3567. OpCapability VariablePointersStorageBuffer
  3568. OpMemoryModel Logical GLSL450
  3569. %void = OpTypeVoid
  3570. %bool = OpTypeBool
  3571. %int = OpTypeInt 32 0
  3572. %ptr_int = OpTypePointer Workgroup %int
  3573. %var = OpVariable %ptr_int Workgroup
  3574. %func_ty = OpTypeFunction %void
  3575. %func = OpFunction %void None %func_ty
  3576. %1 = OpLabel
  3577. %equal = )" + operation;
  3578. if (operation == "OpPtrDiff") {
  3579. spirv += " %int ";
  3580. } else {
  3581. spirv += " %bool ";
  3582. }
  3583. spirv += R"(%var %var
  3584. OpReturn
  3585. OpFunctionEnd
  3586. )";
  3587. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3588. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3589. EXPECT_THAT(getDiagnosticString(),
  3590. HasSubstr("Workgroup storage class pointer requires "
  3591. "VariablePointers capability to be specified"));
  3592. }
  3593. TEST_P(ValidatePointerComparisons, BadStorageClass) {
  3594. const std::string operation = GetParam();
  3595. std::string spirv = R"(
  3596. OpCapability Shader
  3597. OpCapability Linkage
  3598. OpCapability VariablePointersStorageBuffer
  3599. OpMemoryModel Logical GLSL450
  3600. %void = OpTypeVoid
  3601. %bool = OpTypeBool
  3602. %int = OpTypeInt 32 0
  3603. %ptr_int = OpTypePointer Private %int
  3604. %var = OpVariable %ptr_int Private
  3605. %func_ty = OpTypeFunction %void
  3606. %func = OpFunction %void None %func_ty
  3607. %1 = OpLabel
  3608. %equal = )" + operation;
  3609. if (operation == "OpPtrDiff") {
  3610. spirv += " %int ";
  3611. } else {
  3612. spirv += " %bool ";
  3613. }
  3614. spirv += R"(%var %var
  3615. OpReturn
  3616. OpFunctionEnd
  3617. )";
  3618. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3619. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3620. EXPECT_THAT(getDiagnosticString(),
  3621. HasSubstr("Invalid pointer storage class"));
  3622. }
  3623. TEST_P(ValidatePointerComparisons, BadDiffOperandTypes) {
  3624. const std::string operation = GetParam();
  3625. std::string spirv = R"(
  3626. OpCapability Shader
  3627. OpCapability Linkage
  3628. OpCapability VariablePointersStorageBuffer
  3629. OpMemoryModel Logical GLSL450
  3630. %void = OpTypeVoid
  3631. %bool = OpTypeBool
  3632. %int = OpTypeInt 32 0
  3633. %float = OpTypeFloat 32
  3634. %ptr_int = OpTypePointer Private %int
  3635. %var = OpVariable %ptr_int Private
  3636. %ptr_float = OpTypePointer Private %float
  3637. %var2 = OpVariable %ptr_float Private
  3638. %func_ty = OpTypeFunction %void
  3639. %func = OpFunction %void None %func_ty
  3640. %1 = OpLabel
  3641. %ld = OpLoad %int %var
  3642. %equal = )" + operation;
  3643. if (operation == "OpPtrDiff") {
  3644. spirv += " %int ";
  3645. } else {
  3646. spirv += " %bool ";
  3647. }
  3648. spirv += R"(%var %var2
  3649. OpReturn
  3650. OpFunctionEnd
  3651. )";
  3652. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3653. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3654. EXPECT_THAT(getDiagnosticString(),
  3655. HasSubstr("The types of Operand 1 and Operand 2 must match"));
  3656. }
  3657. TEST_P(ValidatePointerComparisons, GoodUntypedPointerSameType) {
  3658. const std::string operation = GetParam();
  3659. std::string spirv = R"(
  3660. OpCapability Shader
  3661. OpCapability Linkage
  3662. OpCapability VariablePointersStorageBuffer
  3663. OpCapability UntypedPointersKHR
  3664. OpExtension "SPV_KHR_untyped_pointers"
  3665. OpMemoryModel Logical GLSL450
  3666. %void = OpTypeVoid
  3667. %bool = OpTypeBool
  3668. %int = OpTypeInt 32 0
  3669. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  3670. %var = OpUntypedVariableKHR %ptr StorageBuffer
  3671. %func_ty = OpTypeFunction %void
  3672. %func = OpFunction %void None %func_ty
  3673. %1 = OpLabel
  3674. %equal = )" + operation;
  3675. if (operation == "OpPtrDiff") {
  3676. spirv += " %int ";
  3677. } else {
  3678. spirv += " %bool ";
  3679. }
  3680. spirv += R"(%var %var
  3681. OpReturn
  3682. OpFunctionEnd
  3683. )";
  3684. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3685. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3686. }
  3687. TEST_P(ValidatePointerComparisons, GoodUntypedPointerSameStorageClass) {
  3688. const std::string operation = GetParam();
  3689. std::string spirv = R"(
  3690. OpCapability Shader
  3691. OpCapability Linkage
  3692. OpCapability VariablePointersStorageBuffer
  3693. OpCapability UntypedPointersKHR
  3694. OpExtension "SPV_KHR_untyped_pointers"
  3695. OpMemoryModel Logical GLSL450
  3696. %void = OpTypeVoid
  3697. %bool = OpTypeBool
  3698. %int = OpTypeInt 32 0
  3699. %ptr1 = OpTypeUntypedPointerKHR StorageBuffer
  3700. %var = OpUntypedVariableKHR %ptr1 StorageBuffer
  3701. %ptr2 = OpTypeUntypedPointerKHR StorageBuffer
  3702. %var2 = OpUntypedVariableKHR %ptr2 StorageBuffer
  3703. %func_ty = OpTypeFunction %void
  3704. %func = OpFunction %void None %func_ty
  3705. %1 = OpLabel
  3706. %equal = )" + operation;
  3707. if (operation == "OpPtrDiff") {
  3708. spirv += " %int ";
  3709. } else {
  3710. spirv += " %bool ";
  3711. }
  3712. spirv += R"(%var %var2
  3713. OpReturn
  3714. OpFunctionEnd
  3715. )";
  3716. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3717. if (operation == "OpPtrDiff") {
  3718. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3719. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3720. EXPECT_THAT(getDiagnosticString(),
  3721. HasSubstr("The types of Operand 1 and Operand 2 must match"));
  3722. } else {
  3723. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3724. }
  3725. }
  3726. TEST_P(ValidatePointerComparisons, BadUntypedPointerDiffStorageClass) {
  3727. const std::string operation = GetParam();
  3728. std::string spirv = R"(
  3729. OpCapability Shader
  3730. OpCapability Linkage
  3731. OpCapability VariablePointers
  3732. OpCapability UntypedPointersKHR
  3733. OpExtension "SPV_KHR_untyped_pointers"
  3734. OpMemoryModel Logical GLSL450
  3735. %void = OpTypeVoid
  3736. %bool = OpTypeBool
  3737. %int = OpTypeInt 32 0
  3738. %ptr1 = OpTypeUntypedPointerKHR StorageBuffer
  3739. %var1 = OpUntypedVariableKHR %ptr1 StorageBuffer
  3740. %ptr2 = OpTypeUntypedPointerKHR Workgroup
  3741. %var2 = OpUntypedVariableKHR %ptr2 Workgroup %int
  3742. %func_ty = OpTypeFunction %void
  3743. %func = OpFunction %void None %func_ty
  3744. %1 = OpLabel
  3745. %equal = )" + operation;
  3746. if (operation == "OpPtrDiff") {
  3747. spirv += " %int ";
  3748. } else {
  3749. spirv += " %bool ";
  3750. }
  3751. spirv += R"(%var1 %var2
  3752. OpReturn
  3753. OpFunctionEnd
  3754. )";
  3755. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3756. if (operation == "OpPtrDiff") {
  3757. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3758. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3759. EXPECT_THAT(getDiagnosticString(),
  3760. HasSubstr("The types of Operand 1 and Operand 2 must match"));
  3761. } else {
  3762. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3763. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3764. EXPECT_THAT(getDiagnosticString(),
  3765. HasSubstr("Pointer storage classes must match"));
  3766. }
  3767. }
  3768. TEST_P(ValidatePointerComparisons, GoodMixedPointerSameStorageClass) {
  3769. const std::string operation = GetParam();
  3770. std::string spirv = R"(
  3771. OpCapability Shader
  3772. OpCapability Linkage
  3773. OpCapability VariablePointersStorageBuffer
  3774. OpCapability UntypedPointersKHR
  3775. OpExtension "SPV_KHR_untyped_pointers"
  3776. OpMemoryModel Logical GLSL450
  3777. %void = OpTypeVoid
  3778. %bool = OpTypeBool
  3779. %int = OpTypeInt 32 0
  3780. %ptr1 = OpTypeUntypedPointerKHR StorageBuffer
  3781. %var = OpUntypedVariableKHR %ptr1 StorageBuffer
  3782. %ptr2 = OpTypePointer StorageBuffer %int
  3783. %var2 = OpVariable %ptr2 StorageBuffer
  3784. %func_ty = OpTypeFunction %void
  3785. %func = OpFunction %void None %func_ty
  3786. %1 = OpLabel
  3787. %equal = )" + operation;
  3788. if (operation == "OpPtrDiff") {
  3789. spirv += " %int ";
  3790. } else {
  3791. spirv += " %bool ";
  3792. }
  3793. spirv += R"(%var %var2
  3794. OpReturn
  3795. OpFunctionEnd
  3796. )";
  3797. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3798. if (operation == "OpPtrDiff") {
  3799. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3800. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3801. EXPECT_THAT(getDiagnosticString(),
  3802. HasSubstr("The types of Operand 1 and Operand 2 must match"));
  3803. } else {
  3804. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3805. }
  3806. }
  3807. TEST_P(ValidatePointerComparisons, BadMixedPointerDiffStorageClass) {
  3808. const std::string operation = GetParam();
  3809. std::string spirv = R"(
  3810. OpCapability Shader
  3811. OpCapability Linkage
  3812. OpCapability VariablePointers
  3813. OpCapability UntypedPointersKHR
  3814. OpExtension "SPV_KHR_untyped_pointers"
  3815. OpMemoryModel Logical GLSL450
  3816. %void = OpTypeVoid
  3817. %bool = OpTypeBool
  3818. %int = OpTypeInt 32 0
  3819. %ptr1 = OpTypeUntypedPointerKHR StorageBuffer
  3820. %var1 = OpUntypedVariableKHR %ptr1 StorageBuffer
  3821. %ptr2 = OpTypePointer Workgroup %int
  3822. %var2 = OpVariable %ptr2 Workgroup
  3823. %func_ty = OpTypeFunction %void
  3824. %func = OpFunction %void None %func_ty
  3825. %1 = OpLabel
  3826. %equal = )" + operation;
  3827. if (operation == "OpPtrDiff") {
  3828. spirv += " %int ";
  3829. } else {
  3830. spirv += " %bool ";
  3831. }
  3832. spirv += R"(%var1 %var2
  3833. OpReturn
  3834. OpFunctionEnd
  3835. )";
  3836. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  3837. if (operation == "OpPtrDiff") {
  3838. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3839. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3840. EXPECT_THAT(getDiagnosticString(),
  3841. HasSubstr("The types of Operand 1 and Operand 2 must match"));
  3842. } else {
  3843. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  3844. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  3845. EXPECT_THAT(getDiagnosticString(),
  3846. HasSubstr("Pointer storage classes must match"));
  3847. }
  3848. }
  3849. INSTANTIATE_TEST_SUITE_P(PointerComparisons, ValidatePointerComparisons,
  3850. Values("OpPtrEqual", "OpPtrNotEqual", "OpPtrDiff"));
  3851. TEST_F(ValidateMemory, VariableInitializerWrongType) {
  3852. const std::string spirv = R"(
  3853. OpCapability Shader
  3854. OpCapability Linkage
  3855. OpCapability VariablePointersStorageBuffer
  3856. OpMemoryModel Logical GLSL450
  3857. %void = OpTypeVoid
  3858. %int = OpTypeInt 32 0
  3859. %float = OpTypeFloat 32
  3860. %ptr_wg_int = OpTypePointer Workgroup %int
  3861. %ptr_wg_float = OpTypePointer Workgroup %int
  3862. %wg_var = OpVariable %ptr_wg_int Workgroup
  3863. %ptr_private_wg_float = OpTypePointer Private %ptr_wg_float
  3864. %priv_var = OpVariable %ptr_private_wg_float Private %wg_var
  3865. )";
  3866. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  3867. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  3868. EXPECT_THAT(getDiagnosticString(),
  3869. HasSubstr("Initializer type must match the data type"));
  3870. }
  3871. TEST_F(ValidateMemory, StoreToImage) {
  3872. const std::string spirv = R"(
  3873. OpCapability Shader
  3874. OpMemoryModel Logical GLSL450
  3875. OpEntryPoint GLCompute %main "main"
  3876. OpExecutionMode %main LocalSize 1 1 1
  3877. %void = OpTypeVoid
  3878. %int = OpTypeInt 32 0
  3879. %img = OpTypeImage %int 2D 2 0 0 2 R32i
  3880. %ptr_img = OpTypePointer Function %img
  3881. %void_fn = OpTypeFunction %void
  3882. %main = OpFunction %void None %void_fn
  3883. %entry = OpLabel
  3884. %var = OpVariable %ptr_img Function
  3885. %value = OpLoad %img %var
  3886. OpStore %var %value
  3887. OpReturn
  3888. OpFunctionEnd
  3889. )";
  3890. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3891. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3892. EXPECT_THAT(getDiagnosticString(),
  3893. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
  3894. EXPECT_THAT(
  3895. getDiagnosticString(),
  3896. HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
  3897. "OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
  3898. }
  3899. TEST_F(ValidateMemory, StoreToImageArray) {
  3900. const std::string spirv = R"(
  3901. OpCapability Shader
  3902. OpMemoryModel Logical GLSL450
  3903. OpEntryPoint GLCompute %main "main"
  3904. OpExecutionMode %main LocalSize 1 1 1
  3905. %void = OpTypeVoid
  3906. %int = OpTypeInt 32 0
  3907. %img = OpTypeImage %int 2D 2 0 0 2 R32i
  3908. %arr_size = OpConstant %int 5
  3909. %i = OpConstant %int 2
  3910. %arr_img = OpTypeArray %img %arr_size
  3911. %ptr_img = OpTypePointer Function %img
  3912. %ptr_arr_img = OpTypePointer Function %arr_img
  3913. %void_fn = OpTypeFunction %void
  3914. %main = OpFunction %void None %void_fn
  3915. %entry = OpLabel
  3916. %var = OpVariable %ptr_arr_img Function
  3917. %value = OpLoad %arr_img %var
  3918. OpStore %var %value
  3919. OpReturn
  3920. OpFunctionEnd
  3921. )";
  3922. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3923. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3924. EXPECT_THAT(getDiagnosticString(),
  3925. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
  3926. EXPECT_THAT(
  3927. getDiagnosticString(),
  3928. HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
  3929. "OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
  3930. }
  3931. TEST_F(ValidateMemory, StoreToSampler) {
  3932. const std::string spirv = R"(
  3933. OpCapability Shader
  3934. OpMemoryModel Logical GLSL450
  3935. OpEntryPoint GLCompute %main "main"
  3936. OpExecutionMode %main LocalSize 1 1 1
  3937. %void = OpTypeVoid
  3938. %smp = OpTypeSampler
  3939. %ptr_smp = OpTypePointer Function %smp
  3940. %void_fn = OpTypeFunction %void
  3941. %main = OpFunction %void None %void_fn
  3942. %entry = OpLabel
  3943. %var = OpVariable %ptr_smp Function
  3944. %value = OpLoad %smp %var
  3945. OpStore %var %value
  3946. OpReturn
  3947. OpFunctionEnd
  3948. )";
  3949. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3950. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3951. EXPECT_THAT(getDiagnosticString(),
  3952. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
  3953. EXPECT_THAT(
  3954. getDiagnosticString(),
  3955. HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
  3956. "OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
  3957. }
  3958. TEST_F(ValidateMemory, StoreToSampledImage) {
  3959. const std::string spirv = R"(
  3960. OpCapability Shader
  3961. OpMemoryModel Logical GLSL450
  3962. OpEntryPoint GLCompute %main "main"
  3963. OpExecutionMode %main LocalSize 1 1 1
  3964. %void = OpTypeVoid
  3965. %int = OpTypeInt 32 0
  3966. %img = OpTypeImage %int 2D 2 0 0 1 R32i
  3967. %samp_img = OpTypeSampledImage %img
  3968. %ptr_samp_img = OpTypePointer Function %samp_img
  3969. %void_fn = OpTypeFunction %void
  3970. %main = OpFunction %void None %void_fn
  3971. %entry = OpLabel
  3972. %var = OpVariable %ptr_samp_img Function
  3973. %value = OpLoad %samp_img %var
  3974. OpStore %var %value
  3975. OpReturn
  3976. OpFunctionEnd
  3977. )";
  3978. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  3979. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  3980. EXPECT_THAT(getDiagnosticString(),
  3981. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
  3982. EXPECT_THAT(
  3983. getDiagnosticString(),
  3984. HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
  3985. "OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
  3986. }
  3987. TEST_F(ValidateMemory, StoreToAccelarationStructureKHR) {
  3988. const std::string spirv = R"(
  3989. OpCapability Shader
  3990. OpCapability RayQueryKHR
  3991. OpExtension "SPV_KHR_ray_query"
  3992. OpMemoryModel Logical GLSL450
  3993. OpEntryPoint GLCompute %main "main"
  3994. OpExecutionMode %main LocalSize 1 1 1
  3995. %void = OpTypeVoid
  3996. %as = OpTypeAccelerationStructureKHR
  3997. %ptr_as = OpTypePointer Function %as
  3998. %void_fn = OpTypeFunction %void
  3999. %main = OpFunction %void None %void_fn
  4000. %entry = OpLabel
  4001. %var = OpVariable %ptr_as Function
  4002. %value = OpLoad %as %var
  4003. OpStore %var %value
  4004. OpReturn
  4005. OpFunctionEnd
  4006. )";
  4007. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4008. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4009. EXPECT_THAT(getDiagnosticString(),
  4010. AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
  4011. EXPECT_THAT(
  4012. getDiagnosticString(),
  4013. HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
  4014. "OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
  4015. }
  4016. TEST_F(ValidateMemory, StoreToUniformBlock) {
  4017. const std::string spirv = R"(
  4018. OpCapability Shader
  4019. OpMemoryModel Logical GLSL450
  4020. OpEntryPoint GLCompute %main "main"
  4021. OpExecutionMode %main LocalSize 1 1 1
  4022. OpDecorate %struct Block
  4023. OpMemberDecorate %struct 0 Offset 0
  4024. OpDecorate %var DescriptorSet 0
  4025. OpDecorate %var Binding 0
  4026. %void = OpTypeVoid
  4027. %int = OpTypeInt 32 0
  4028. %int_0 = OpConstant %int 0
  4029. %int4 = OpTypeVector %int 4
  4030. %struct = OpTypeStruct %int4
  4031. %ptr_uniform_struct = OpTypePointer Uniform %struct
  4032. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4033. %ptr_uniform_int = OpTypePointer Uniform %int
  4034. %var = OpVariable %ptr_uniform_struct Uniform
  4035. %void_fn = OpTypeFunction %void
  4036. %main = OpFunction %void None %void_fn
  4037. %entry = OpLabel
  4038. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  4039. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  4040. OpStore %gep2 %int_0
  4041. OpReturn
  4042. OpFunctionEnd
  4043. )";
  4044. CompileSuccessfully(spirv);
  4045. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  4046. }
  4047. TEST_F(ValidateMemory, StoreToUniformBlockVulkan) {
  4048. const std::string spirv = R"(
  4049. OpCapability Shader
  4050. OpMemoryModel Logical GLSL450
  4051. OpEntryPoint GLCompute %main "main"
  4052. OpExecutionMode %main LocalSize 1 1 1
  4053. OpDecorate %struct Block
  4054. OpMemberDecorate %struct 0 Offset 0
  4055. OpDecorate %var DescriptorSet 0
  4056. OpDecorate %var Binding 0
  4057. %void = OpTypeVoid
  4058. %int = OpTypeInt 32 0
  4059. %int_0 = OpConstant %int 0
  4060. %int4 = OpTypeVector %int 4
  4061. %struct = OpTypeStruct %int4
  4062. %ptr_uniform_struct = OpTypePointer Uniform %struct
  4063. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4064. %ptr_uniform_int = OpTypePointer Uniform %int
  4065. %var = OpVariable %ptr_uniform_struct Uniform
  4066. %void_fn = OpTypeFunction %void
  4067. %main = OpFunction %void None %void_fn
  4068. %entry = OpLabel
  4069. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  4070. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  4071. OpStore %gep2 %int_0
  4072. OpReturn
  4073. OpFunctionEnd
  4074. )";
  4075. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4076. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4077. EXPECT_THAT(getDiagnosticString(),
  4078. AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
  4079. EXPECT_THAT(
  4080. getDiagnosticString(),
  4081. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  4082. }
  4083. // This test requires that the struct is not id 2.
  4084. TEST_F(ValidateMemory, StoreToUniformBlockVulkan2) {
  4085. const std::string spirv = R"(
  4086. OpCapability Shader
  4087. OpMemoryModel Logical GLSL450
  4088. OpEntryPoint GLCompute %main "main" %gid_var
  4089. OpExecutionMode %main LocalSize 1 1 1
  4090. OpDecorate %3 Block
  4091. OpMemberDecorate %3 0 Offset 0
  4092. OpDecorate %var DescriptorSet 0
  4093. OpDecorate %var Binding 0
  4094. OpDecorate %gid_var BuiltIn GlobalInvocationId
  4095. %void = OpTypeVoid
  4096. %int = OpTypeInt 32 0
  4097. %int_0 = OpConstant %int 0
  4098. %int3 = OpTypeVector %int 3
  4099. %int4 = OpTypeVector %int 4
  4100. %3 = OpTypeStruct %int4
  4101. %ptr_uniform_struct = OpTypePointer Uniform %3
  4102. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4103. %ptr_uniform_int = OpTypePointer Uniform %int
  4104. %var = OpVariable %ptr_uniform_struct Uniform
  4105. %ptr_input_int3 = OpTypePointer Input %int3
  4106. %gid_var = OpVariable %ptr_input_int3 Input
  4107. %void_fn = OpTypeFunction %void
  4108. %main = OpFunction %void None %void_fn
  4109. %entry = OpLabel
  4110. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  4111. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  4112. OpStore %gep2 %int_0
  4113. OpReturn
  4114. OpFunctionEnd
  4115. )";
  4116. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4117. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4118. EXPECT_THAT(getDiagnosticString(),
  4119. AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
  4120. EXPECT_THAT(
  4121. getDiagnosticString(),
  4122. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  4123. }
  4124. TEST_F(ValidateMemory, StoreToUniformBufferBlockVulkan) {
  4125. const std::string spirv = R"(
  4126. OpCapability Shader
  4127. OpMemoryModel Logical GLSL450
  4128. OpEntryPoint GLCompute %main "main"
  4129. OpExecutionMode %main LocalSize 1 1 1
  4130. OpDecorate %struct BufferBlock
  4131. OpMemberDecorate %struct 0 Offset 0
  4132. OpDecorate %var DescriptorSet 0
  4133. OpDecorate %var Binding 0
  4134. %void = OpTypeVoid
  4135. %int = OpTypeInt 32 0
  4136. %int_0 = OpConstant %int 0
  4137. %int4 = OpTypeVector %int 4
  4138. %struct = OpTypeStruct %int4
  4139. %ptr_uniform_struct = OpTypePointer Uniform %struct
  4140. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4141. %ptr_uniform_int = OpTypePointer Uniform %int
  4142. %var = OpVariable %ptr_uniform_struct Uniform
  4143. %void_fn = OpTypeFunction %void
  4144. %main = OpFunction %void None %void_fn
  4145. %entry = OpLabel
  4146. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
  4147. %gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
  4148. OpStore %gep2 %int_0
  4149. OpReturn
  4150. OpFunctionEnd
  4151. )";
  4152. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4153. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4154. }
  4155. TEST_F(ValidateMemory, StoreToUniformBlockVulkanArray) {
  4156. const std::string spirv = R"(
  4157. OpCapability Shader
  4158. OpMemoryModel Logical GLSL450
  4159. OpEntryPoint GLCompute %main "main"
  4160. OpExecutionMode %main LocalSize 1 1 1
  4161. OpDecorate %struct Block
  4162. OpMemberDecorate %struct 0 Offset 0
  4163. OpDecorate %var DescriptorSet 0
  4164. OpDecorate %var Binding 0
  4165. %void = OpTypeVoid
  4166. %int = OpTypeInt 32 0
  4167. %int_0 = OpConstant %int 0
  4168. %int_1 = OpConstant %int 1
  4169. %int4 = OpTypeVector %int 4
  4170. %struct = OpTypeStruct %int4
  4171. %array_struct = OpTypeArray %struct %int_1
  4172. %ptr_uniform_array = OpTypePointer Uniform %array_struct
  4173. %ptr_uniform_struct = OpTypePointer Uniform %struct
  4174. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4175. %ptr_uniform_int = OpTypePointer Uniform %int
  4176. %var = OpVariable %ptr_uniform_array Uniform
  4177. %void_fn = OpTypeFunction %void
  4178. %main = OpFunction %void None %void_fn
  4179. %entry = OpLabel
  4180. %gep1 = OpAccessChain %ptr_uniform_int %var %int_0 %int_0 %int_0
  4181. %gep2 = OpCopyObject %ptr_uniform_int %gep1
  4182. OpStore %gep2 %int_0
  4183. OpReturn
  4184. OpFunctionEnd
  4185. )";
  4186. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4187. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4188. EXPECT_THAT(getDiagnosticString(),
  4189. AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
  4190. EXPECT_THAT(
  4191. getDiagnosticString(),
  4192. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  4193. }
  4194. // This test requires that the struct is not id 2.
  4195. TEST_F(ValidateMemory, StoreToUniformBlockVulkanArray2) {
  4196. const std::string spirv = R"(
  4197. OpCapability Shader
  4198. OpMemoryModel Logical GLSL450
  4199. OpEntryPoint GLCompute %main "main" %gid_var
  4200. OpExecutionMode %main LocalSize 1 1 1
  4201. OpDecorate %struct Block
  4202. OpMemberDecorate %struct 0 Offset 0
  4203. OpDecorate %var DescriptorSet 0
  4204. OpDecorate %var Binding 0
  4205. OpDecorate %gid_var BuiltIn GlobalInvocationId
  4206. %void = OpTypeVoid
  4207. %int = OpTypeInt 32 0
  4208. %int_0 = OpConstant %int 0
  4209. %int_1 = OpConstant %int 1
  4210. %int3 = OpTypeVector %int 3
  4211. %int4 = OpTypeVector %int 4
  4212. %struct = OpTypeStruct %int4
  4213. %array_struct = OpTypeArray %struct %int_1
  4214. %ptr_uniform_array = OpTypePointer Uniform %array_struct
  4215. %ptr_uniform_struct = OpTypePointer Uniform %struct
  4216. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4217. %ptr_uniform_int = OpTypePointer Uniform %int
  4218. %var = OpVariable %ptr_uniform_array Uniform
  4219. %ptr_input_int3 = OpTypePointer Input %int3
  4220. %gid_var = OpVariable %ptr_input_int3 Input
  4221. %void_fn = OpTypeFunction %void
  4222. %main = OpFunction %void None %void_fn
  4223. %entry = OpLabel
  4224. %gep1 = OpAccessChain %ptr_uniform_int %var %int_0 %int_0 %int_0
  4225. %gep2 = OpCopyObject %ptr_uniform_int %gep1
  4226. OpStore %gep2 %int_0
  4227. OpReturn
  4228. OpFunctionEnd
  4229. )";
  4230. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4231. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4232. EXPECT_THAT(getDiagnosticString(),
  4233. AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
  4234. EXPECT_THAT(
  4235. getDiagnosticString(),
  4236. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  4237. }
  4238. TEST_F(ValidateMemory, StoreToUniformBlockVulkanRuntimeArray) {
  4239. const std::string spirv = R"(
  4240. OpCapability Shader
  4241. OpCapability RuntimeDescriptorArrayEXT
  4242. OpExtension "SPV_EXT_descriptor_indexing"
  4243. OpMemoryModel Logical GLSL450
  4244. OpEntryPoint GLCompute %main "main"
  4245. OpExecutionMode %main LocalSize 1 1 1
  4246. OpDecorate %struct Block
  4247. OpMemberDecorate %struct 0 Offset 0
  4248. OpDecorate %var DescriptorSet 0
  4249. OpDecorate %var Binding 0
  4250. %void = OpTypeVoid
  4251. %int = OpTypeInt 32 0
  4252. %int_0 = OpConstant %int 0
  4253. %int4 = OpTypeVector %int 4
  4254. %struct = OpTypeStruct %int4
  4255. %array_struct = OpTypeRuntimeArray %struct
  4256. %ptr_uniform_array = OpTypePointer Uniform %array_struct
  4257. %ptr_uniform_struct = OpTypePointer Uniform %struct
  4258. %ptr_uniform_int4 = OpTypePointer Uniform %int4
  4259. %ptr_uniform_int = OpTypePointer Uniform %int
  4260. %var = OpVariable %ptr_uniform_array Uniform
  4261. %void_fn = OpTypeFunction %void
  4262. %main = OpFunction %void None %void_fn
  4263. %entry = OpLabel
  4264. %gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0 %int_0
  4265. %gep2 = OpInBoundsAccessChain %ptr_uniform_int %gep1 %int_0
  4266. OpStore %gep2 %int_0
  4267. OpReturn
  4268. OpFunctionEnd
  4269. )";
  4270. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  4271. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  4272. EXPECT_THAT(getDiagnosticString(),
  4273. AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
  4274. EXPECT_THAT(
  4275. getDiagnosticString(),
  4276. HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
  4277. }
  4278. using ValidateSizedVariable = spvtest::ValidateBase<
  4279. std::tuple<std::string, std::string, std::string, spv_target_env>>;
  4280. CodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) {
  4281. CodeGenerator generator;
  4282. generator.capabilities_ = "OpCapability Shader\nOpCapability Linkage\n";
  4283. generator.extensions_ =
  4284. "OpExtension \"SPV_KHR_16bit_storage\"\nOpExtension "
  4285. "\"SPV_KHR_8bit_storage\"\n";
  4286. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  4287. if (is_8bit) {
  4288. generator.before_types_ =
  4289. "OpMemberDecorate %char_buffer_block 0 Offset 0\n";
  4290. if (buffer_block)
  4291. generator.before_types_ += "OpDecorate %char_buffer_block BufferBlock\n";
  4292. generator.types_ = R"(%void = OpTypeVoid
  4293. %char = OpTypeInt 8 0
  4294. %char4 = OpTypeVector %char 4
  4295. %char_buffer_block = OpTypeStruct %char
  4296. )";
  4297. } else {
  4298. generator.before_types_ =
  4299. "OpMemberDecorate %half_buffer_block 0 Offset 0\n"
  4300. "OpMemberDecorate %short_buffer_block 0 Offset 0\n";
  4301. if (buffer_block) {
  4302. generator.before_types_ +=
  4303. "OpDecorate %half_buffer_block BufferBlock\n"
  4304. "OpDecorate %short_buffer_block BufferBlock\n";
  4305. }
  4306. generator.types_ = R"(%void = OpTypeVoid
  4307. %short = OpTypeInt 16 0
  4308. %half = OpTypeFloat 16
  4309. %short4 = OpTypeVector %short 4
  4310. %half4 = OpTypeVector %half 4
  4311. %mat4x4 = OpTypeMatrix %half4 4
  4312. %short_buffer_block = OpTypeStruct %short
  4313. %half_buffer_block = OpTypeStruct %half
  4314. )";
  4315. }
  4316. generator.after_types_ = R"(%void_fn = OpTypeFunction %void
  4317. %func = OpFunction %void None %void_fn
  4318. %entry = OpLabel
  4319. )";
  4320. generator.add_at_the_end_ = "OpReturn\nOpFunctionEnd\n";
  4321. return generator;
  4322. }
  4323. TEST_P(ValidateSizedVariable, Capability) {
  4324. const std::string storage_class = std::get<0>(GetParam());
  4325. const std::string capability = std::get<1>(GetParam());
  4326. const std::string var_type = std::get<2>(GetParam());
  4327. const spv_target_env target = std::get<3>(GetParam());
  4328. ASSERT_TRUE(target == SPV_ENV_UNIVERSAL_1_3 ||
  4329. target == SPV_ENV_UNIVERSAL_1_4);
  4330. bool type_8bit = false;
  4331. if (var_type == "%char" || var_type == "%char4" ||
  4332. var_type == "%char_buffer_block") {
  4333. type_8bit = true;
  4334. }
  4335. const bool buffer_block = var_type.find("buffer_block") != std::string::npos;
  4336. auto generator = GetSizedVariableCodeGenerator(type_8bit, buffer_block);
  4337. if (capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR" ||
  4338. capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR") {
  4339. generator.extensions_ +=
  4340. "OpExtension \"SPV_KHR_workgroup_memory_explicit_layout\"\n";
  4341. }
  4342. generator.types_ += "%ptr_type = OpTypePointer " + storage_class + " " +
  4343. var_type + "\n%var = OpVariable %ptr_type " +
  4344. storage_class + "\n";
  4345. generator.capabilities_ += "OpCapability " + capability + "\n";
  4346. bool capability_ok = false;
  4347. bool storage_class_ok = false;
  4348. if (storage_class == "Input" || storage_class == "Output") {
  4349. if (!type_8bit) {
  4350. capability_ok = capability == "StorageInputOutput16";
  4351. storage_class_ok = true;
  4352. }
  4353. } else if (storage_class == "StorageBuffer") {
  4354. if (type_8bit) {
  4355. capability_ok = capability == "StorageBuffer8BitAccess" ||
  4356. capability == "UniformAndStorageBuffer8BitAccess";
  4357. } else {
  4358. capability_ok = capability == "StorageBuffer16BitAccess" ||
  4359. capability == "UniformAndStorageBuffer16BitAccess";
  4360. }
  4361. storage_class_ok = true;
  4362. } else if (storage_class == "PushConstant") {
  4363. if (type_8bit) {
  4364. capability_ok = capability == "StoragePushConstant8";
  4365. } else {
  4366. capability_ok = capability == "StoragePushConstant16";
  4367. }
  4368. storage_class_ok = true;
  4369. } else if (storage_class == "Uniform") {
  4370. if (type_8bit) {
  4371. capability_ok = capability == "UniformAndStorageBuffer8BitAccess" ||
  4372. (capability == "StorageBuffer8BitAccess" && buffer_block);
  4373. } else {
  4374. capability_ok =
  4375. capability == "UniformAndStorageBuffer16BitAccess" ||
  4376. (capability == "StorageBuffer16BitAccess" && buffer_block);
  4377. }
  4378. storage_class_ok = true;
  4379. } else if (storage_class == "Workgroup") {
  4380. if (type_8bit) {
  4381. capability_ok =
  4382. capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR";
  4383. } else {
  4384. capability_ok =
  4385. capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR";
  4386. }
  4387. storage_class_ok = true;
  4388. }
  4389. CompileSuccessfully(generator.Build(), target);
  4390. spv_result_t result = ValidateInstructions(target);
  4391. if (target < SPV_ENV_UNIVERSAL_1_4 &&
  4392. (capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR" ||
  4393. capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR")) {
  4394. EXPECT_EQ(SPV_ERROR_WRONG_VERSION, result);
  4395. EXPECT_THAT(getDiagnosticString(),
  4396. HasSubstr("requires SPIR-V version 1.4 or later"));
  4397. } else if (buffer_block && target > SPV_ENV_UNIVERSAL_1_3) {
  4398. EXPECT_EQ(SPV_ERROR_WRONG_VERSION, result);
  4399. EXPECT_THAT(getDiagnosticString(),
  4400. HasSubstr("requires SPIR-V version 1.3 or earlier"));
  4401. } else if (capability_ok) {
  4402. EXPECT_EQ(SPV_SUCCESS, result);
  4403. } else {
  4404. EXPECT_EQ(SPV_ERROR_INVALID_ID, result);
  4405. if (storage_class_ok) {
  4406. std::string message = std::string("Allocating a variable containing a ") +
  4407. (type_8bit ? "8" : "16") + "-bit element in " +
  4408. storage_class +
  4409. " storage class requires an additional capability";
  4410. EXPECT_THAT(getDiagnosticString(), HasSubstr(message));
  4411. } else {
  4412. std::string message =
  4413. std::string("Cannot allocate a variable containing a ") +
  4414. (type_8bit ? "8" : "16") + "-bit type in " + storage_class +
  4415. " storage class";
  4416. EXPECT_THAT(getDiagnosticString(), HasSubstr(message));
  4417. }
  4418. }
  4419. }
  4420. INSTANTIATE_TEST_SUITE_P(
  4421. Storage8, ValidateSizedVariable,
  4422. Combine(Values("UniformConstant", "Input", "Output", "Workgroup",
  4423. "CrossWorkgroup", "Private", "StorageBuffer", "Uniform"),
  4424. Values("StorageBuffer8BitAccess",
  4425. "UniformAndStorageBuffer8BitAccess", "StoragePushConstant8",
  4426. "WorkgroupMemoryExplicitLayout8BitAccessKHR"),
  4427. Values("%char", "%char4", "%char_buffer_block"),
  4428. Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4)));
  4429. INSTANTIATE_TEST_SUITE_P(
  4430. Storage16, ValidateSizedVariable,
  4431. Combine(Values("UniformConstant", "Input", "Output", "Workgroup",
  4432. "CrossWorkgroup", "Private", "StorageBuffer", "Uniform"),
  4433. Values("StorageBuffer16BitAccess",
  4434. "UniformAndStorageBuffer16BitAccess",
  4435. "StoragePushConstant16", "StorageInputOutput16",
  4436. "WorkgroupMemoryExplicitLayout16BitAccessKHR"),
  4437. Values("%short", "%half", "%short4", "%half4", "%mat4x4",
  4438. "%short_buffer_block", "%half_buffer_block"),
  4439. Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4)));
  4440. using ValidateSizedLoadStore =
  4441. spvtest::ValidateBase<std::tuple<std::string, uint32_t, std::string>>;
  4442. CodeGenerator GetSizedLoadStoreCodeGenerator(const std::string& base_type,
  4443. uint32_t width) {
  4444. CodeGenerator generator;
  4445. generator.capabilities_ = "OpCapability Shader\nOpCapability Linkage\n";
  4446. if (width == 8) {
  4447. generator.capabilities_ +=
  4448. "OpCapability UniformAndStorageBuffer8BitAccess\n";
  4449. generator.extensions_ = "OpExtension \"SPV_KHR_8bit_storage\"\n";
  4450. } else {
  4451. generator.capabilities_ +=
  4452. "OpCapability UniformAndStorageBuffer16BitAccess\n";
  4453. generator.extensions_ = "OpExtension \"SPV_KHR_16bit_storage\"\n";
  4454. }
  4455. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  4456. generator.before_types_ = R"(OpDecorate %block Block
  4457. OpMemberDecorate %block 0 Offset 0
  4458. OpMemberDecorate %struct 0 Offset 0
  4459. )";
  4460. generator.types_ = R"(%void = OpTypeVoid
  4461. %int = OpTypeInt 32 0
  4462. %int_0 = OpConstant %int 0
  4463. %int_1 = OpConstant %int 1
  4464. %int_2 = OpConstant %int 2
  4465. %int_3 = OpConstant %int 3
  4466. )";
  4467. if (width == 8) {
  4468. generator.types_ += R"(%scalar = OpTypeInt 8 0
  4469. %vector = OpTypeVector %scalar 4
  4470. %struct = OpTypeStruct %vector
  4471. )";
  4472. } else if (base_type == "int") {
  4473. generator.types_ += R"(%scalar = OpTypeInt 16 0
  4474. %vector = OpTypeVector %scalar 4
  4475. %struct = OpTypeStruct %vector
  4476. )";
  4477. } else {
  4478. generator.types_ += R"(%scalar = OpTypeFloat 16
  4479. %vector = OpTypeVector %scalar 4
  4480. %matrix = OpTypeMatrix %vector 4
  4481. %struct = OpTypeStruct %matrix
  4482. %ptr_ssbo_matrix = OpTypePointer StorageBuffer %matrix
  4483. )";
  4484. generator.before_types_ += R"(OpMemberDecorate %struct 0 RowMajor
  4485. OpMemberDecorate %struct 0 MatrixStride 16
  4486. )";
  4487. }
  4488. generator.types_ += R"(%block = OpTypeStruct %struct
  4489. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  4490. %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
  4491. %ptr_ssbo_vector = OpTypePointer StorageBuffer %vector
  4492. %ptr_ssbo_scalar = OpTypePointer StorageBuffer %scalar
  4493. %ld_var = OpVariable %ptr_ssbo_block StorageBuffer
  4494. %st_var = OpVariable %ptr_ssbo_block StorageBuffer
  4495. )";
  4496. generator.after_types_ = R"(%void_fn = OpTypeFunction %void
  4497. %func = OpFunction %void None %void_fn
  4498. %entry = OpLabel
  4499. )";
  4500. generator.add_at_the_end_ = "OpReturn\nOpFunctionEnd\n";
  4501. return generator;
  4502. }
  4503. TEST_P(ValidateSizedLoadStore, Load) {
  4504. std::string base_type = std::get<0>(GetParam());
  4505. uint32_t width = std::get<1>(GetParam());
  4506. std::string mem_type = std::get<2>(GetParam());
  4507. CodeGenerator generator = GetSizedLoadStoreCodeGenerator(base_type, width);
  4508. generator.after_types_ +=
  4509. "%ld_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %ld_var %int_0";
  4510. if (mem_type != "struct") {
  4511. generator.after_types_ += " %int_0";
  4512. if (mem_type != "matrix" && base_type == "float") {
  4513. generator.after_types_ += " %int_0";
  4514. }
  4515. if (mem_type == "scalar") {
  4516. generator.after_types_ += " %int_0";
  4517. }
  4518. }
  4519. generator.after_types_ += "\n";
  4520. generator.after_types_ += "%ld = OpLoad %" + mem_type + " %ld_gep\n";
  4521. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  4522. if (mem_type == "struct") {
  4523. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4524. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4525. EXPECT_THAT(
  4526. getDiagnosticString(),
  4527. HasSubstr(
  4528. "8- or 16-bit loads must be a scalar, vector or matrix type"));
  4529. } else {
  4530. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4531. }
  4532. }
  4533. TEST_P(ValidateSizedLoadStore, Store) {
  4534. std::string base_type = std::get<0>(GetParam());
  4535. uint32_t width = std::get<1>(GetParam());
  4536. std::string mem_type = std::get<2>(GetParam());
  4537. CodeGenerator generator = GetSizedLoadStoreCodeGenerator(base_type, width);
  4538. generator.after_types_ +=
  4539. "%ld_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %ld_var %int_0";
  4540. if (mem_type != "struct") {
  4541. generator.after_types_ += " %int_0";
  4542. if (mem_type != "matrix" && base_type == "float") {
  4543. generator.after_types_ += " %int_0";
  4544. }
  4545. if (mem_type == "scalar") {
  4546. generator.after_types_ += " %int_0";
  4547. }
  4548. }
  4549. generator.after_types_ += "\n";
  4550. generator.after_types_ += "%ld = OpLoad %" + mem_type + " %ld_gep\n";
  4551. generator.after_types_ +=
  4552. "%st_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %st_var %int_0";
  4553. if (mem_type != "struct") {
  4554. generator.after_types_ += " %int_0";
  4555. if (mem_type != "matrix" && base_type == "float") {
  4556. generator.after_types_ += " %int_0";
  4557. }
  4558. if (mem_type == "scalar") {
  4559. generator.after_types_ += " %int_0";
  4560. }
  4561. }
  4562. generator.after_types_ += "\n";
  4563. generator.after_types_ += "OpStore %st_gep %ld\n";
  4564. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  4565. if (mem_type == "struct") {
  4566. EXPECT_EQ(SPV_ERROR_INVALID_ID,
  4567. ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4568. // Can only catch the load.
  4569. EXPECT_THAT(
  4570. getDiagnosticString(),
  4571. HasSubstr(
  4572. "8- or 16-bit loads must be a scalar, vector or matrix type"));
  4573. } else {
  4574. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4575. }
  4576. }
  4577. INSTANTIATE_TEST_SUITE_P(LoadStoreInt8, ValidateSizedLoadStore,
  4578. Combine(Values("int"), Values(8u),
  4579. Values("scalar", "vector", "struct")));
  4580. INSTANTIATE_TEST_SUITE_P(LoadStoreInt16, ValidateSizedLoadStore,
  4581. Combine(Values("int"), Values(16u),
  4582. Values("scalar", "vector", "struct")));
  4583. INSTANTIATE_TEST_SUITE_P(LoadStoreFloat16, ValidateSizedLoadStore,
  4584. Combine(Values("float"), Values(16u),
  4585. Values("scalar", "vector", "matrix",
  4586. "struct")));
  4587. TEST_F(ValidateMemory, SmallStorageCopyMemoryChar) {
  4588. const std::string spirv = R"(
  4589. OpCapability Shader
  4590. OpCapability Linkage
  4591. OpCapability UniformAndStorageBuffer8BitAccess
  4592. OpExtension "SPV_KHR_8bit_storage"
  4593. OpMemoryModel Logical GLSL450
  4594. OpDecorate %block Block
  4595. OpMemberDecorate %block 0 Offset 0
  4596. %void = OpTypeVoid
  4597. %int = OpTypeInt 32 0
  4598. %int_0 = OpConstant %int 0
  4599. %char = OpTypeInt 8 0
  4600. %block = OpTypeStruct %char
  4601. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  4602. %in = OpVariable %ptr_ssbo_block StorageBuffer
  4603. %out = OpVariable %ptr_ssbo_block StorageBuffer
  4604. %void_fn = OpTypeFunction %void
  4605. %func = OpFunction %void None %void_fn
  4606. %entry = OpLabel
  4607. OpCopyMemory %out %in
  4608. OpReturn
  4609. OpFunctionEnd
  4610. )";
  4611. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4612. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4613. EXPECT_THAT(
  4614. getDiagnosticString(),
  4615. HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
  4616. }
  4617. TEST_F(ValidateMemory, SmallStorageCopyMemoryShort) {
  4618. const std::string spirv = R"(
  4619. OpCapability Shader
  4620. OpCapability Linkage
  4621. OpCapability UniformAndStorageBuffer16BitAccess
  4622. OpExtension "SPV_KHR_16bit_storage"
  4623. OpMemoryModel Logical GLSL450
  4624. OpDecorate %block Block
  4625. OpMemberDecorate %block 0 Offset 0
  4626. %void = OpTypeVoid
  4627. %int = OpTypeInt 32 0
  4628. %int_0 = OpConstant %int 0
  4629. %short = OpTypeInt 16 0
  4630. %block = OpTypeStruct %short
  4631. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  4632. %in = OpVariable %ptr_ssbo_block StorageBuffer
  4633. %out = OpVariable %ptr_ssbo_block StorageBuffer
  4634. %void_fn = OpTypeFunction %void
  4635. %func = OpFunction %void None %void_fn
  4636. %entry = OpLabel
  4637. OpCopyMemory %out %in
  4638. OpReturn
  4639. OpFunctionEnd
  4640. )";
  4641. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4642. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4643. EXPECT_THAT(
  4644. getDiagnosticString(),
  4645. HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
  4646. }
  4647. TEST_F(ValidateMemory, SmallStorageCopyMemoryHalf) {
  4648. const std::string spirv = R"(
  4649. OpCapability Shader
  4650. OpCapability Linkage
  4651. OpCapability UniformAndStorageBuffer16BitAccess
  4652. OpExtension "SPV_KHR_16bit_storage"
  4653. OpMemoryModel Logical GLSL450
  4654. OpDecorate %block Block
  4655. OpMemberDecorate %block 0 Offset 0
  4656. %void = OpTypeVoid
  4657. %int = OpTypeInt 32 0
  4658. %int_0 = OpConstant %int 0
  4659. %half = OpTypeFloat 16
  4660. %block = OpTypeStruct %half
  4661. %ptr_ssbo_block = OpTypePointer StorageBuffer %block
  4662. %in = OpVariable %ptr_ssbo_block StorageBuffer
  4663. %out = OpVariable %ptr_ssbo_block StorageBuffer
  4664. %void_fn = OpTypeFunction %void
  4665. %func = OpFunction %void None %void_fn
  4666. %entry = OpLabel
  4667. OpCopyMemory %out %in
  4668. OpReturn
  4669. OpFunctionEnd
  4670. )";
  4671. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4672. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4673. EXPECT_THAT(
  4674. getDiagnosticString(),
  4675. HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
  4676. }
  4677. TEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockShort) {
  4678. const std::string spirv = R"(
  4679. OpCapability Shader
  4680. OpCapability Linkage
  4681. OpCapability StorageBuffer16BitAccess
  4682. OpExtension "SPV_KHR_16bit_storage"
  4683. OpMemoryModel Logical GLSL450
  4684. OpDecorate %block BufferBlock
  4685. OpMemberDecorate %block 0 Offset 0
  4686. %void = OpTypeVoid
  4687. %short = OpTypeInt 16 0
  4688. %int = OpTypeInt 32 0
  4689. %int_4 = OpConstant %int 4
  4690. %block = OpTypeStruct %short
  4691. %block_array = OpTypeArray %block %int_4
  4692. %ptr_block_array = OpTypePointer Uniform %block_array
  4693. %var = OpVariable %ptr_block_array Uniform
  4694. )";
  4695. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4696. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4697. }
  4698. TEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockChar) {
  4699. const std::string spirv = R"(
  4700. OpCapability Shader
  4701. OpCapability Linkage
  4702. OpCapability StorageBuffer8BitAccess
  4703. OpExtension "SPV_KHR_8bit_storage"
  4704. OpMemoryModel Logical GLSL450
  4705. OpDecorate %block BufferBlock
  4706. OpMemberDecorate %block 0 Offset 0
  4707. %void = OpTypeVoid
  4708. %char = OpTypeInt 8 0
  4709. %int = OpTypeInt 32 0
  4710. %int_4 = OpConstant %int 4
  4711. %block = OpTypeStruct %char
  4712. %block_array = OpTypeArray %block %int_4
  4713. %ptr_block_array = OpTypePointer Uniform %block_array
  4714. %var = OpVariable %ptr_block_array Uniform
  4715. )";
  4716. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4717. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4718. }
  4719. TEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockHalf) {
  4720. const std::string spirv = R"(
  4721. OpCapability Shader
  4722. OpCapability Linkage
  4723. OpCapability StorageBuffer16BitAccess
  4724. OpExtension "SPV_KHR_16bit_storage"
  4725. OpMemoryModel Logical GLSL450
  4726. OpDecorate %block BufferBlock
  4727. OpMemberDecorate %block 0 Offset 0
  4728. %void = OpTypeVoid
  4729. %half = OpTypeFloat 16
  4730. %int = OpTypeInt 32 0
  4731. %int_4 = OpConstant %int 4
  4732. %block = OpTypeStruct %half
  4733. %block_array = OpTypeArray %block %int_4
  4734. %ptr_block_array = OpTypePointer Uniform %block_array
  4735. %var = OpVariable %ptr_block_array Uniform
  4736. )";
  4737. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  4738. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  4739. }
  4740. TEST_F(ValidateMemory, VulkanStorageBufferNotAStruct) {
  4741. const std::string spirv = R"(
  4742. OpCapability Shader
  4743. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4744. OpMemoryModel Logical GLSL450
  4745. OpEntryPoint GLCompute %main "main"
  4746. OpExecutionMode %main LocalSize 1 1 1
  4747. %void = OpTypeVoid
  4748. %uint = OpTypeInt 32 0
  4749. %ptr_ssbo = OpTypePointer StorageBuffer %uint
  4750. %var = OpVariable %ptr_ssbo StorageBuffer
  4751. %void_fn = OpTypeFunction %void
  4752. %main = OpFunction %void None %void_fn
  4753. %entry = OpLabel
  4754. OpReturn
  4755. OpFunctionEnd
  4756. )";
  4757. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4758. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4759. EXPECT_THAT(getDiagnosticString(),
  4760. AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
  4761. EXPECT_THAT(
  4762. getDiagnosticString(),
  4763. HasSubstr("From Vulkan spec:\nVariables identified with "
  4764. "the StorageBuffer storage class are used to access "
  4765. "transparent buffer backed resources. Such variables must be "
  4766. "typed as OpTypeStruct, or an array of this type"));
  4767. }
  4768. TEST_F(ValidateMemory, VulkanStorageBufferRuntimeArrayNotAStruct) {
  4769. const std::string spirv = R"(
  4770. OpCapability Shader
  4771. OpCapability RuntimeDescriptorArrayEXT
  4772. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4773. OpExtension "SPV_EXT_descriptor_indexing"
  4774. OpMemoryModel Logical GLSL450
  4775. OpEntryPoint GLCompute %main "main"
  4776. OpExecutionMode %main LocalSize 1 1 1
  4777. %void = OpTypeVoid
  4778. %uint = OpTypeInt 32 0
  4779. %array = OpTypeRuntimeArray %uint
  4780. %ptr_ssbo = OpTypePointer StorageBuffer %array
  4781. %var = OpVariable %ptr_ssbo StorageBuffer
  4782. %void_fn = OpTypeFunction %void
  4783. %main = OpFunction %void None %void_fn
  4784. %entry = OpLabel
  4785. OpReturn
  4786. OpFunctionEnd
  4787. )";
  4788. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4789. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4790. EXPECT_THAT(getDiagnosticString(),
  4791. AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
  4792. EXPECT_THAT(
  4793. getDiagnosticString(),
  4794. HasSubstr("From Vulkan spec:\nVariables identified with "
  4795. "the StorageBuffer storage class are used to access "
  4796. "transparent buffer backed resources. Such variables must be "
  4797. "typed as OpTypeStruct, or an array of this type"));
  4798. }
  4799. TEST_F(ValidateMemory, VulkanStorageBufferArrayNotAStruct) {
  4800. const std::string spirv = R"(
  4801. OpCapability Shader
  4802. OpExtension "SPV_KHR_storage_buffer_storage_class"
  4803. OpMemoryModel Logical GLSL450
  4804. OpEntryPoint GLCompute %main "main"
  4805. OpExecutionMode %main LocalSize 1 1 1
  4806. %void = OpTypeVoid
  4807. %uint = OpTypeInt 32 0
  4808. %uint_4 = OpConstant %uint 4
  4809. %array = OpTypeArray %uint %uint_4
  4810. %ptr_ssbo = OpTypePointer StorageBuffer %array
  4811. %var = OpVariable %ptr_ssbo StorageBuffer
  4812. %void_fn = OpTypeFunction %void
  4813. %main = OpFunction %void None %void_fn
  4814. %entry = OpLabel
  4815. OpReturn
  4816. OpFunctionEnd
  4817. )";
  4818. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4819. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4820. EXPECT_THAT(getDiagnosticString(),
  4821. AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
  4822. EXPECT_THAT(
  4823. getDiagnosticString(),
  4824. HasSubstr("From Vulkan spec:\nVariables identified with "
  4825. "the StorageBuffer storage class are used to access "
  4826. "transparent buffer backed resources. Such variables must be "
  4827. "typed as OpTypeStruct, or an array of this type"));
  4828. }
  4829. TEST_F(ValidateMemory, VulkanInvariantOutputSuccess) {
  4830. const std::string spirv = R"(
  4831. OpCapability Shader
  4832. OpMemoryModel Logical GLSL450
  4833. OpEntryPoint Vertex %main "main" %var
  4834. OpDecorate %var Location 0
  4835. OpDecorate %var Invariant
  4836. %void = OpTypeVoid
  4837. %f32 = OpTypeFloat 32
  4838. %ptr_output = OpTypePointer Output %f32
  4839. %var = OpVariable %ptr_output Output
  4840. %void_fn = OpTypeFunction %void
  4841. %main = OpFunction %void None %void_fn
  4842. %entry = OpLabel
  4843. OpReturn
  4844. OpFunctionEnd
  4845. )";
  4846. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4847. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4848. }
  4849. TEST_F(ValidateMemory, VulkanInvariantInputStructSuccess) {
  4850. const std::string spirv = R"(
  4851. OpCapability Shader
  4852. OpMemoryModel Logical GLSL450
  4853. OpEntryPoint Fragment %main "main" %var
  4854. OpExecutionMode %main OriginUpperLeft
  4855. OpDecorate %var Location 0
  4856. OpMemberDecorate %struct 1 Invariant
  4857. %void = OpTypeVoid
  4858. %f32 = OpTypeFloat 32
  4859. %struct = OpTypeStruct %f32 %f32
  4860. %ptr_input = OpTypePointer Input %struct
  4861. %var = OpVariable %ptr_input Input
  4862. %void_fn = OpTypeFunction %void
  4863. %main = OpFunction %void None %void_fn
  4864. %entry = OpLabel
  4865. OpReturn
  4866. OpFunctionEnd
  4867. )";
  4868. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4869. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4870. }
  4871. TEST_F(ValidateMemory, VulkanInvariantWrongStorageClass) {
  4872. const std::string spirv = R"(
  4873. OpCapability Shader
  4874. OpMemoryModel Logical GLSL450
  4875. OpEntryPoint Vertex %main "main"
  4876. OpDecorate %var Invariant
  4877. %void = OpTypeVoid
  4878. %f32 = OpTypeFloat 32
  4879. %ptr_private = OpTypePointer Private %f32
  4880. %var = OpVariable %ptr_private Private
  4881. %void_fn = OpTypeFunction %void
  4882. %main = OpFunction %void None %void_fn
  4883. %entry = OpLabel
  4884. OpReturn
  4885. OpFunctionEnd
  4886. )";
  4887. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4888. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4889. EXPECT_THAT(getDiagnosticString(),
  4890. AnyVUID("VUID-StandaloneSpirv-Invariant-04677"));
  4891. EXPECT_THAT(
  4892. getDiagnosticString(),
  4893. HasSubstr(
  4894. "Variable decorated with Invariant must only be identified with the "
  4895. "Input or Output storage class in Vulkan environment."));
  4896. }
  4897. TEST_F(ValidateMemory, VulkanInvariantMemberWrongStorageClass) {
  4898. const std::string spirv = R"(
  4899. OpCapability Shader
  4900. OpMemoryModel Logical GLSL450
  4901. OpEntryPoint Fragment %main "main"
  4902. OpExecutionMode %main OriginUpperLeft
  4903. OpMemberDecorate %struct 1 Invariant
  4904. %void = OpTypeVoid
  4905. %f32 = OpTypeFloat 32
  4906. %struct = OpTypeStruct %f32 %f32
  4907. %ptr_private = OpTypePointer Private %struct
  4908. %var = OpVariable %ptr_private Private
  4909. %void_fn = OpTypeFunction %void
  4910. %main = OpFunction %void None %void_fn
  4911. %entry = OpLabel
  4912. OpReturn
  4913. OpFunctionEnd
  4914. )";
  4915. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  4916. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  4917. EXPECT_THAT(getDiagnosticString(),
  4918. AnyVUID("VUID-StandaloneSpirv-Invariant-04677"));
  4919. EXPECT_THAT(getDiagnosticString(),
  4920. HasSubstr("Variable struct member decorated with Invariant must "
  4921. "only be identified with the Input or Output storage "
  4922. "class in Vulkan environment."));
  4923. }
  4924. TEST_F(ValidateMemory, PhysicalStorageBufferPtrEqual) {
  4925. const std::string spirv = R"(
  4926. OpCapability Shader
  4927. OpCapability Int64
  4928. OpCapability PhysicalStorageBufferAddresses
  4929. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  4930. OpEntryPoint GLCompute %main "main"
  4931. OpExecutionMode %main LocalSize 1 1 1
  4932. %void = OpTypeVoid
  4933. %bool = OpTypeBool
  4934. %long = OpTypeInt 64 0
  4935. %long_0 = OpConstant %long 0
  4936. %ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
  4937. %void_fn = OpTypeFunction %void
  4938. %main = OpFunction %void None %void_fn
  4939. %entry = OpLabel
  4940. %conv = OpConvertUToPtr %ptr_pssbo_long %long_0
  4941. %eq = OpPtrEqual %bool %conv %conv
  4942. OpReturn
  4943. OpFunctionEnd
  4944. )";
  4945. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  4946. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  4947. EXPECT_THAT(
  4948. getDiagnosticString(),
  4949. HasSubstr(
  4950. "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
  4951. }
  4952. TEST_F(ValidateMemory, PhysicalStorageBufferPtrNotEqual) {
  4953. const std::string spirv = R"(
  4954. OpCapability Shader
  4955. OpCapability Int64
  4956. OpCapability PhysicalStorageBufferAddresses
  4957. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  4958. OpEntryPoint GLCompute %main "main"
  4959. OpExecutionMode %main LocalSize 1 1 1
  4960. %void = OpTypeVoid
  4961. %bool = OpTypeBool
  4962. %long = OpTypeInt 64 0
  4963. %long_0 = OpConstant %long 0
  4964. %ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
  4965. %void_fn = OpTypeFunction %void
  4966. %main = OpFunction %void None %void_fn
  4967. %entry = OpLabel
  4968. %conv = OpConvertUToPtr %ptr_pssbo_long %long_0
  4969. %neq = OpPtrNotEqual %bool %conv %conv
  4970. OpReturn
  4971. OpFunctionEnd
  4972. )";
  4973. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  4974. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  4975. EXPECT_THAT(
  4976. getDiagnosticString(),
  4977. HasSubstr(
  4978. "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
  4979. }
  4980. TEST_F(ValidateMemory, PhysicalStorageBufferPtrDiff) {
  4981. const std::string spirv = R"(
  4982. OpCapability Shader
  4983. OpCapability Int64
  4984. OpCapability PhysicalStorageBufferAddresses
  4985. OpCapability VariablePointers
  4986. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  4987. OpEntryPoint GLCompute %main "main"
  4988. OpExecutionMode %main LocalSize 1 1 1
  4989. %void = OpTypeVoid
  4990. %long = OpTypeInt 64 0
  4991. %long_0 = OpConstant %long 0
  4992. %ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
  4993. %void_fn = OpTypeFunction %void
  4994. %main = OpFunction %void None %void_fn
  4995. %entry = OpLabel
  4996. %conv = OpConvertUToPtr %ptr_pssbo_long %long_0
  4997. %diff = OpPtrDiff %long %conv %conv
  4998. OpReturn
  4999. OpFunctionEnd
  5000. )";
  5001. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  5002. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  5003. EXPECT_THAT(
  5004. getDiagnosticString(),
  5005. HasSubstr(
  5006. "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
  5007. }
  5008. TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassBad) {
  5009. std::string spirv = R"(
  5010. OpCapability Shader
  5011. OpCapability VulkanMemoryModelKHR
  5012. OpExtension "SPV_KHR_vulkan_memory_model"
  5013. OpMemoryModel Logical VulkanKHR
  5014. OpEntryPoint Fragment %func "func"
  5015. OpExecutionMode %func OriginUpperLeft
  5016. %float = OpTypeFloat 32
  5017. %float_ptr = OpTypePointer Workgroup %float
  5018. %init_val = OpConstant %float 1.0
  5019. %1 = OpVariable %float_ptr Workgroup %init_val
  5020. %void = OpTypeVoid
  5021. %functy = OpTypeFunction %void
  5022. %func = OpFunction %void None %functy
  5023. %2 = OpLabel
  5024. OpReturn
  5025. OpFunctionEnd
  5026. )";
  5027. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  5028. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  5029. EXPECT_THAT(getDiagnosticString(),
  5030. AnyVUID(" VUID-StandaloneSpirv-OpVariable-04734"));
  5031. EXPECT_THAT(getDiagnosticString(),
  5032. HasSubstr("OpVariable, <id> '5[%5]', initializers are limited to "
  5033. "OpConstantNull in Workgroup storage class"));
  5034. }
  5035. TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassGood) {
  5036. std::string spirv = R"(
  5037. OpCapability Shader
  5038. OpCapability VulkanMemoryModelKHR
  5039. OpExtension "SPV_KHR_vulkan_memory_model"
  5040. OpMemoryModel Logical VulkanKHR
  5041. OpEntryPoint Fragment %func "func"
  5042. OpExecutionMode %func OriginUpperLeft
  5043. %float = OpTypeFloat 32
  5044. %float_ptr = OpTypePointer Workgroup %float
  5045. %init_val = OpConstantNull %float
  5046. %1 = OpVariable %float_ptr Workgroup %init_val
  5047. %void = OpTypeVoid
  5048. %functy = OpTypeFunction %void
  5049. %func = OpFunction %void None %functy
  5050. %2 = OpLabel
  5051. OpReturn
  5052. OpFunctionEnd
  5053. )";
  5054. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
  5055. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  5056. }
  5057. TEST_F(ValidateMemory, LoadRuntimeArray) {
  5058. const std::string spirv = R"(
  5059. OpCapability Shader
  5060. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5061. OpMemoryModel Logical GLSL450
  5062. OpEntryPoint GLCompute %main "main"
  5063. %void = OpTypeVoid
  5064. %int = OpTypeInt 32 0
  5065. %int_0 = OpConstant %int 0
  5066. %rta = OpTypeRuntimeArray %int
  5067. %block = OpTypeStruct %rta
  5068. %ptr_rta = OpTypePointer StorageBuffer %rta
  5069. %ptr_block = OpTypePointer StorageBuffer %block
  5070. %var = OpVariable %ptr_block StorageBuffer
  5071. %void_fn = OpTypeFunction %void
  5072. %main = OpFunction %void None %void_fn
  5073. %entry = OpLabel
  5074. %gep = OpAccessChain %ptr_rta %var %int_0
  5075. %ld = OpLoad %rta %gep
  5076. OpReturn
  5077. OpFunctionEnd
  5078. )";
  5079. CompileSuccessfully(spirv);
  5080. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5081. EXPECT_THAT(getDiagnosticString(),
  5082. HasSubstr("Cannot load a runtime-sized array"));
  5083. }
  5084. TEST_F(ValidateMemory, LoadRuntimeArrayInStruct) {
  5085. const std::string spirv = R"(
  5086. OpCapability Shader
  5087. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5088. OpMemoryModel Logical GLSL450
  5089. OpEntryPoint GLCompute %main "main"
  5090. %void = OpTypeVoid
  5091. %int = OpTypeInt 32 0
  5092. %int_0 = OpConstant %int 0
  5093. %rta = OpTypeRuntimeArray %int
  5094. %block = OpTypeStruct %rta
  5095. %ptr_rta = OpTypePointer StorageBuffer %rta
  5096. %ptr_block = OpTypePointer StorageBuffer %block
  5097. %var = OpVariable %ptr_block StorageBuffer
  5098. %void_fn = OpTypeFunction %void
  5099. %main = OpFunction %void None %void_fn
  5100. %entry = OpLabel
  5101. %ld = OpLoad %block %var
  5102. OpReturn
  5103. OpFunctionEnd
  5104. )";
  5105. CompileSuccessfully(spirv);
  5106. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5107. EXPECT_THAT(getDiagnosticString(),
  5108. HasSubstr("Cannot load a runtime-sized array"));
  5109. }
  5110. TEST_F(ValidateMemory, LoadRuntimeArrayInArray) {
  5111. const std::string spirv = R"(
  5112. OpCapability Shader
  5113. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5114. OpMemoryModel Logical GLSL450
  5115. OpEntryPoint GLCompute %main "main"
  5116. %void = OpTypeVoid
  5117. %int = OpTypeInt 32 0
  5118. %int_0 = OpConstant %int 0
  5119. %int_4 = OpConstant %int 4
  5120. %rta = OpTypeRuntimeArray %int
  5121. %block = OpTypeStruct %rta
  5122. %array = OpTypeArray %block %int_4
  5123. %ptr_rta = OpTypePointer StorageBuffer %rta
  5124. %ptr_block = OpTypePointer StorageBuffer %block
  5125. %ptr_array = OpTypePointer StorageBuffer %array
  5126. %var = OpVariable %ptr_array StorageBuffer
  5127. %void_fn = OpTypeFunction %void
  5128. %main = OpFunction %void None %void_fn
  5129. %entry = OpLabel
  5130. %ld = OpLoad %array %var
  5131. OpReturn
  5132. OpFunctionEnd
  5133. )";
  5134. CompileSuccessfully(spirv);
  5135. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5136. EXPECT_THAT(getDiagnosticString(),
  5137. HasSubstr("Cannot load a runtime-sized array"));
  5138. }
  5139. TEST_F(ValidateMemory, Pre1p4WorkgroupMemoryBadLayoutOk) {
  5140. const std::string spirv = R"(
  5141. OpCapability Shader
  5142. OpMemoryModel Logical GLSL450
  5143. OpEntryPoint GLCompute %main "main"
  5144. OpDecorate %struct Block
  5145. OpMemberDecorate %struct 0 Offset 0
  5146. %void = OpTypeVoid
  5147. %bool = OpTypeBool
  5148. %struct = OpTypeStruct %bool
  5149. %ptr = OpTypePointer Workgroup %struct
  5150. %var = OpVariable %ptr Workgroup
  5151. %void_fn = OpTypeFunction %void
  5152. %main = OpFunction %void None %void_fn
  5153. %entry = OpLabel
  5154. OpReturn
  5155. OpFunctionEnd
  5156. )";
  5157. CompileSuccessfully(spirv);
  5158. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5159. }
  5160. TEST_F(ValidateMemory, UntypedVariableGood) {
  5161. const std::string spirv = R"(
  5162. OpCapability Shader
  5163. OpCapability Linkage
  5164. OpCapability UntypedPointersKHR
  5165. OpExtension "SPV_KHR_untyped_pointers"
  5166. OpMemoryModel Logical GLSL450
  5167. %int = OpTypeInt 32 0
  5168. %int_0 = OpConstant %int 0
  5169. %ptr = OpTypeUntypedPointerKHR Private
  5170. %var = OpUntypedVariableKHR %ptr Private %int %int_0
  5171. )";
  5172. CompileSuccessfully(spirv);
  5173. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5174. }
  5175. TEST_F(ValidateMemory, UntypedVariableNoDataType) {
  5176. const std::string spirv = R"(
  5177. OpCapability Shader
  5178. OpCapability Linkage
  5179. OpCapability UntypedPointersKHR
  5180. OpExtension "SPV_KHR_untyped_pointers"
  5181. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5182. OpMemoryModel Logical GLSL450
  5183. %int = OpTypeInt 32 0
  5184. %int_0 = OpConstant %int 0
  5185. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5186. %var = OpUntypedVariableKHR %ptr StorageBuffer
  5187. )";
  5188. CompileSuccessfully(spirv);
  5189. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5190. }
  5191. TEST_F(ValidateMemory, UntypedVariableNoDataTypeFunction) {
  5192. const std::string spirv = R"(
  5193. OpCapability Shader
  5194. OpCapability Linkage
  5195. OpCapability UntypedPointersKHR
  5196. OpExtension "SPV_KHR_untyped_pointers"
  5197. OpMemoryModel Logical GLSL450
  5198. %int = OpTypeInt 32 0
  5199. %int_0 = OpConstant %int 0
  5200. %ptr = OpTypeUntypedPointerKHR Function
  5201. %var = OpUntypedVariableKHR %ptr Function
  5202. )";
  5203. CompileSuccessfully(spirv);
  5204. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5205. EXPECT_THAT(getDiagnosticString(),
  5206. HasSubstr("Data type must be specified for Function, "
  5207. "Private, and Workgroup storage classes"));
  5208. }
  5209. TEST_F(ValidateMemory, UntypedVariableNoDataTypePrivate) {
  5210. const std::string spirv = R"(
  5211. OpCapability Shader
  5212. OpCapability Linkage
  5213. OpCapability UntypedPointersKHR
  5214. OpExtension "SPV_KHR_untyped_pointers"
  5215. OpMemoryModel Logical GLSL450
  5216. %int = OpTypeInt 32 0
  5217. %int_0 = OpConstant %int 0
  5218. %ptr = OpTypeUntypedPointerKHR Private
  5219. %var = OpUntypedVariableKHR %ptr Private
  5220. )";
  5221. CompileSuccessfully(spirv);
  5222. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5223. EXPECT_THAT(getDiagnosticString(),
  5224. HasSubstr("Data type must be specified for Function, "
  5225. "Private, and Workgroup storage classes"));
  5226. }
  5227. TEST_F(ValidateMemory, UntypedVariableNoDataTypeWorkgroup) {
  5228. const std::string spirv = R"(
  5229. OpCapability Shader
  5230. OpCapability Linkage
  5231. OpCapability UntypedPointersKHR
  5232. OpExtension "SPV_KHR_untyped_pointers"
  5233. OpMemoryModel Logical GLSL450
  5234. %int = OpTypeInt 32 0
  5235. %int_0 = OpConstant %int 0
  5236. %ptr = OpTypeUntypedPointerKHR Workgroup
  5237. %var = OpUntypedVariableKHR %ptr Workgroup
  5238. )";
  5239. CompileSuccessfully(spirv);
  5240. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5241. EXPECT_THAT(getDiagnosticString(),
  5242. HasSubstr("Data type must be specified for Function, "
  5243. "Private, and Workgroup storage classes"));
  5244. }
  5245. TEST_F(ValidateMemory, UntypedVariableNoDataTypeVulkan) {
  5246. const std::string spirv = R"(
  5247. OpCapability Shader
  5248. OpCapability UntypedPointersKHR
  5249. OpExtension "SPV_KHR_untyped_pointers"
  5250. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5251. OpMemoryModel Logical GLSL450
  5252. OpEntryPoint GLCompute %main "main"
  5253. OpExecutionMode %main LocalSize 1 1 1
  5254. %int = OpTypeInt 32 0
  5255. %int_0 = OpConstant %int 0
  5256. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5257. %var = OpUntypedVariableKHR %ptr StorageBuffer
  5258. %void = OpTypeVoid
  5259. %void_fn = OpTypeFunction %void
  5260. %main = OpFunction %void None %void_fn
  5261. %entry = OpLabel
  5262. OpReturn
  5263. OpFunctionEnd
  5264. )";
  5265. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
  5266. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  5267. EXPECT_THAT(getDiagnosticString(),
  5268. HasSubstr("Vulkan requires that data type be specified"));
  5269. }
  5270. TEST_F(ValidateMemory, PtrAccessChainArrayStrideBad) {
  5271. const std::string spirv = R"(
  5272. OpCapability Shader
  5273. OpCapability VariablePointersStorageBuffer
  5274. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5275. OpExtension "SPV_KHR_variable_pointers"
  5276. OpMemoryModel Logical GLSL450
  5277. OpEntryPoint GLCompute %main "foo" %var
  5278. OpExecutionMode %main LocalSize 1 1 1
  5279. OpDecorate %var DescriptorSet 0
  5280. OpDecorate %var Binding 0
  5281. %uint = OpTypeInt 32 0
  5282. %uint_0 = OpConstant %uint 0
  5283. %uint_1 = OpConstant %uint 1
  5284. %ptr = OpTypePointer StorageBuffer %uint
  5285. %void = OpTypeVoid
  5286. %func = OpTypeFunction %void
  5287. %var = OpVariable %ptr StorageBuffer
  5288. %main = OpFunction %void None %func
  5289. %label = OpLabel
  5290. %access = OpAccessChain %ptr %var
  5291. %ptr_access = OpPtrAccessChain %ptr %access %uint_1
  5292. OpReturn
  5293. OpFunctionEnd
  5294. )";
  5295. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  5296. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  5297. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  5298. EXPECT_THAT(getDiagnosticString(),
  5299. HasSubstr("OpPtrAccessChain must have a Base whose type is "
  5300. "decorated with ArrayStride"));
  5301. }
  5302. TEST_F(ValidateMemory, PtrAccessChainArrayStrideSuccess) {
  5303. const std::string spirv = R"(
  5304. OpCapability Shader
  5305. OpCapability VariablePointersStorageBuffer
  5306. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5307. OpExtension "SPV_KHR_variable_pointers"
  5308. OpMemoryModel Logical GLSL450
  5309. OpEntryPoint GLCompute %main "foo" %var
  5310. OpExecutionMode %main LocalSize 1 1 1
  5311. OpDecorate %var DescriptorSet 0
  5312. OpDecorate %var Binding 00
  5313. OpDecorate %ptr ArrayStride 4
  5314. %uint = OpTypeInt 32 0
  5315. %uint_0 = OpConstant %uint 0
  5316. %uint_1 = OpConstant %uint 1
  5317. %ptr = OpTypePointer StorageBuffer %uint
  5318. %void = OpTypeVoid
  5319. %func = OpTypeFunction %void
  5320. %var = OpVariable %ptr StorageBuffer
  5321. %main = OpFunction %void None %func
  5322. %label = OpLabel
  5323. %access = OpAccessChain %ptr %var
  5324. %ptr_access = OpPtrAccessChain %ptr %access %uint_1
  5325. OpReturn
  5326. OpFunctionEnd
  5327. )";
  5328. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
  5329. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  5330. }
  5331. TEST_F(ValidateMemory, VulkanPtrAccessChainStorageBufferSuccess) {
  5332. const std::string spirv = R"(
  5333. OpCapability Shader
  5334. OpCapability VariablePointersStorageBuffer
  5335. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5336. OpExtension "SPV_KHR_variable_pointers"
  5337. OpMemoryModel Logical GLSL450
  5338. OpEntryPoint GLCompute %main "foo" %var
  5339. OpExecutionMode %main LocalSize 1 1 1
  5340. OpDecorate %_runtimearr_uint ArrayStride 4
  5341. OpMemberDecorate %_struct_10 0 Offset 0
  5342. OpDecorate %_struct_10 Block
  5343. OpDecorate %var DescriptorSet 0
  5344. OpDecorate %var Binding 0
  5345. OpDecorate %_ptr_StorageBuffer_uint ArrayStride 4
  5346. %uint = OpTypeInt 32 0
  5347. %uint_0 = OpConstant %uint 0
  5348. %uint_1 = OpConstant %uint 1
  5349. %_runtimearr_uint = OpTypeRuntimeArray %uint
  5350. %_struct_10 = OpTypeStruct %_runtimearr_uint
  5351. %_ptr_StorageBuffer__struct_10 = OpTypePointer StorageBuffer %_struct_10
  5352. %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
  5353. %void = OpTypeVoid
  5354. %func2 = OpTypeFunction %void %_ptr_StorageBuffer_uint
  5355. %func1 = OpTypeFunction %void
  5356. %var = OpVariable %_ptr_StorageBuffer__struct_10 StorageBuffer
  5357. %called = OpFunction %void None %func2
  5358. %param = OpFunctionParameter %_ptr_StorageBuffer_uint
  5359. %label2 = OpLabel
  5360. %ptr_access = OpPtrAccessChain %_ptr_StorageBuffer_uint %param %uint_1
  5361. OpReturn
  5362. OpFunctionEnd
  5363. %main = OpFunction %void None %func1
  5364. %label1 = OpLabel
  5365. %access = OpAccessChain %_ptr_StorageBuffer_uint %var %uint_0 %uint_0
  5366. %call = OpFunctionCall %void %called %access
  5367. OpReturn
  5368. OpFunctionEnd
  5369. )";
  5370. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  5371. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  5372. }
  5373. TEST_F(ValidateMemory, VulkanPtrAccessChainStorageBufferCapability) {
  5374. const std::string spirv = R"(
  5375. OpCapability Shader
  5376. OpCapability PhysicalStorageBufferAddresses
  5377. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5378. OpExtension "SPV_KHR_variable_pointers"
  5379. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5380. OpEntryPoint GLCompute %main "foo" %var
  5381. OpExecutionMode %main LocalSize 1 1 1
  5382. OpDecorate %_runtimearr_uint ArrayStride 4
  5383. OpMemberDecorate %_struct_10 0 Offset 0
  5384. OpDecorate %_struct_10 Block
  5385. OpDecorate %var DescriptorSet 0
  5386. OpDecorate %var Binding 0
  5387. OpDecorate %_ptr_StorageBuffer_uint ArrayStride 4
  5388. %uint = OpTypeInt 32 0
  5389. %uint_0 = OpConstant %uint 0
  5390. %uint_1 = OpConstant %uint 1
  5391. %_runtimearr_uint = OpTypeRuntimeArray %uint
  5392. %_struct_10 = OpTypeStruct %_runtimearr_uint
  5393. %_ptr_StorageBuffer__struct_10 = OpTypePointer StorageBuffer %_struct_10
  5394. %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
  5395. %void = OpTypeVoid
  5396. %func = OpTypeFunction %void
  5397. %var = OpVariable %_ptr_StorageBuffer__struct_10 StorageBuffer
  5398. %main = OpFunction %void None %func
  5399. %label = OpLabel
  5400. %access = OpAccessChain %_ptr_StorageBuffer_uint %var %uint_0 %uint_0
  5401. %ptr_access = OpPtrAccessChain %_ptr_StorageBuffer_uint %access %uint_1
  5402. OpReturn
  5403. OpFunctionEnd
  5404. )";
  5405. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  5406. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  5407. EXPECT_THAT(getDiagnosticString(),
  5408. AnyVUID("VUID-StandaloneSpirv-Base-07652"));
  5409. EXPECT_THAT(getDiagnosticString(),
  5410. HasSubstr("OpPtrAccessChain Base operand pointing to "
  5411. "StorageBuffer storage class must use VariablePointers "
  5412. "or VariablePointersStorageBuffer capability"));
  5413. }
  5414. TEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupCapability) {
  5415. const std::string spirv = R"(
  5416. OpCapability Shader
  5417. OpCapability VariablePointersStorageBuffer
  5418. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5419. OpExtension "SPV_KHR_variable_pointers"
  5420. OpMemoryModel Logical GLSL450
  5421. OpEntryPoint GLCompute %main "foo" %var
  5422. OpExecutionMode %main LocalSize 1 1 1
  5423. OpDecorate %_ptr_Workgroup_uint ArrayStride 4
  5424. %uint = OpTypeInt 32 0
  5425. %uint_0 = OpConstant %uint 0
  5426. %uint_1 = OpConstant %uint 1
  5427. %_arr_uint = OpTypeArray %uint %uint_1
  5428. %_ptr_Workgroup__arr_uint = OpTypePointer Workgroup %_arr_uint
  5429. %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  5430. %void = OpTypeVoid
  5431. %func = OpTypeFunction %void
  5432. %var = OpVariable %_ptr_Workgroup__arr_uint Workgroup
  5433. %main = OpFunction %void None %func
  5434. %label = OpLabel
  5435. %access = OpAccessChain %_ptr_Workgroup_uint %var %uint_0
  5436. %ptr_access = OpPtrAccessChain %_ptr_Workgroup_uint %access %uint_1
  5437. OpReturn
  5438. OpFunctionEnd
  5439. )";
  5440. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  5441. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  5442. EXPECT_THAT(getDiagnosticString(),
  5443. AnyVUID("VUID-StandaloneSpirv-Base-07651"));
  5444. EXPECT_THAT(getDiagnosticString(),
  5445. HasSubstr("OpPtrAccessChain Base operand pointing to Workgroup "
  5446. "storage class must use VariablePointers capability"));
  5447. }
  5448. TEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupNoArrayStrideSuccess) {
  5449. const std::string spirv = R"(
  5450. OpCapability Shader
  5451. OpCapability VariablePointers
  5452. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5453. OpExtension "SPV_KHR_variable_pointers"
  5454. OpMemoryModel Logical GLSL450
  5455. OpEntryPoint GLCompute %main "foo" %var
  5456. OpExecutionMode %main LocalSize 1 1 1
  5457. %uint = OpTypeInt 32 0
  5458. %uint_0 = OpConstant %uint 0
  5459. %uint_1 = OpConstant %uint 1
  5460. %_arr_uint = OpTypeArray %uint %uint_1
  5461. %_ptr_Workgroup__arr_uint = OpTypePointer Workgroup %_arr_uint
  5462. %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  5463. %void = OpTypeVoid
  5464. %func = OpTypeFunction %void
  5465. %var = OpVariable %_ptr_Workgroup__arr_uint Workgroup
  5466. %main = OpFunction %void None %func
  5467. %label = OpLabel
  5468. %access = OpAccessChain %_ptr_Workgroup_uint %var %uint_0
  5469. %ptr_access = OpPtrAccessChain %_ptr_Workgroup_uint %access %uint_1
  5470. OpReturn
  5471. OpFunctionEnd
  5472. )";
  5473. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
  5474. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  5475. }
  5476. TEST_F(ValidateMemory, AccessChainNegativeStructIndex32) {
  5477. const std::string spirv = R"(
  5478. OpCapability Shader
  5479. OpCapability Linkage
  5480. OpMemoryModel Logical GLSL450
  5481. %void = OpTypeVoid
  5482. %void_fn = OpTypeFunction %void
  5483. %int = OpTypeInt 32 1
  5484. %_struct_4 = OpTypeStruct %int %int %int
  5485. %_ptr_Function__struct_4 = OpTypePointer Function %_struct_4
  5486. %_ptr_Function_int = OpTypePointer Function %int
  5487. %int_n224 = OpConstant %int -224
  5488. %fn = OpFunction %void Inline %void_fn
  5489. %entry = OpLabel
  5490. %var = OpVariable %_ptr_Function__struct_4 Function
  5491. %gep = OpInBoundsAccessChain %_ptr_Function_int %var %int_n224
  5492. OpReturn
  5493. OpFunctionEnd
  5494. )";
  5495. CompileSuccessfully(spirv);
  5496. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5497. EXPECT_THAT(getDiagnosticString(), HasSubstr("is out of bounds"));
  5498. EXPECT_THAT(getDiagnosticString(), HasSubstr("cannot find index -224"));
  5499. }
  5500. TEST_F(ValidateMemory, AccessChainNegativeStructIndex64) {
  5501. const std::string spirv = R"(
  5502. OpCapability Shader
  5503. OpCapability Linkage
  5504. OpCapability Int64
  5505. OpMemoryModel Logical GLSL450
  5506. %void = OpTypeVoid
  5507. %void_fn = OpTypeFunction %void
  5508. %int = OpTypeInt 32 1
  5509. %long = OpTypeInt 64 1
  5510. %_struct_4 = OpTypeStruct %int %int %int
  5511. %_ptr_Function__struct_4 = OpTypePointer Function %_struct_4
  5512. %_ptr_Function_int = OpTypePointer Function %int
  5513. %long_n224 = OpConstant %long -224
  5514. %fn = OpFunction %void Inline %void_fn
  5515. %entry = OpLabel
  5516. %var = OpVariable %_ptr_Function__struct_4 Function
  5517. %gep = OpInBoundsAccessChain %_ptr_Function_int %var %long_n224
  5518. OpReturn
  5519. OpFunctionEnd
  5520. )";
  5521. CompileSuccessfully(spirv);
  5522. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5523. EXPECT_THAT(getDiagnosticString(), HasSubstr("is out of bounds"));
  5524. EXPECT_THAT(getDiagnosticString(), HasSubstr("cannot find index -224"));
  5525. }
  5526. TEST_F(ValidateMemory, UntypedVariableFunctionOutsideFunction) {
  5527. const std::string spirv = R"(
  5528. OpCapability Shader
  5529. OpCapability Linkage
  5530. OpCapability UntypedPointersKHR
  5531. OpExtension "SPV_KHR_untyped_pointers"
  5532. OpMemoryModel Logical GLSL450
  5533. %int = OpTypeInt 32 0
  5534. %int_0 = OpConstant %int 0
  5535. %ptr = OpTypeUntypedPointerKHR Function
  5536. %var = OpUntypedVariableKHR %ptr Function %int
  5537. )";
  5538. CompileSuccessfully(spirv);
  5539. EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
  5540. EXPECT_THAT(getDiagnosticString(),
  5541. HasSubstr("Variables can not have a function[7] storage class "
  5542. "outside of a function"));
  5543. }
  5544. TEST_F(ValidateMemory, UntypedVariableBadResultType) {
  5545. const std::string spirv = R"(
  5546. OpCapability Shader
  5547. OpCapability Linkage
  5548. OpCapability UntypedPointersKHR
  5549. OpExtension "SPV_KHR_untyped_pointers"
  5550. OpMemoryModel Logical GLSL450
  5551. %int = OpTypeInt 32 0
  5552. %int_0 = OpConstant %int 0
  5553. %ptr = OpTypeUntypedPointerKHR Workgroup
  5554. %var = OpUntypedVariableKHR %int Workgroup %int
  5555. )";
  5556. CompileSuccessfully(spirv);
  5557. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5558. EXPECT_THAT(getDiagnosticString(),
  5559. HasSubstr("Result type must be an untyped pointer"));
  5560. }
  5561. TEST_F(ValidateMemory, UntypedVariableBadDataType) {
  5562. const std::string spirv = R"(
  5563. OpCapability Shader
  5564. OpCapability Linkage
  5565. OpCapability UntypedPointersKHR
  5566. OpExtension "SPV_KHR_untyped_pointers"
  5567. OpMemoryModel Logical GLSL450
  5568. %int = OpTypeInt 32 0
  5569. %int_0 = OpConstant %int 0
  5570. %ptr = OpTypeUntypedPointerKHR Workgroup
  5571. %var = OpUntypedVariableKHR %ptr Workgroup %int_0
  5572. )";
  5573. CompileSuccessfully(spirv);
  5574. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5575. EXPECT_THAT(getDiagnosticString(),
  5576. HasSubstr("Data type must be a type instruction"));
  5577. }
  5578. TEST_F(ValidateMemory, UntypedVariableBadStorageClass) {
  5579. const std::string spirv = R"(
  5580. OpCapability Kernel
  5581. OpCapability GenericPointer
  5582. OpCapability Linkage
  5583. OpCapability UntypedPointersKHR
  5584. OpExtension "SPV_KHR_untyped_pointers"
  5585. OpMemoryModel Logical OpenCL
  5586. %int = OpTypeInt 32 0
  5587. %int_0 = OpConstant %int 0
  5588. %ptr = OpTypeUntypedPointerKHR Generic
  5589. %var = OpUntypedVariableKHR %ptr Generic %int
  5590. )";
  5591. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_2);
  5592. EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
  5593. ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
  5594. EXPECT_THAT(getDiagnosticString(),
  5595. HasSubstr("Variable storage class cannot be Generic"));
  5596. }
  5597. TEST_F(ValidateMemory, UntypedVariableMismatchedStorageClass) {
  5598. const std::string spirv = R"(
  5599. OpCapability Shader
  5600. OpCapability Linkage
  5601. OpCapability UntypedPointersKHR
  5602. OpExtension "SPV_KHR_untyped_pointers"
  5603. OpMemoryModel Logical GLSL450
  5604. %int = OpTypeInt 32 0
  5605. %int_0 = OpConstant %int 0
  5606. %ptr = OpTypeUntypedPointerKHR Workgroup
  5607. %var = OpUntypedVariableKHR %ptr Private %int
  5608. )";
  5609. CompileSuccessfully(spirv);
  5610. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5611. EXPECT_THAT(getDiagnosticString(),
  5612. HasSubstr("Storage class must match result type storage class"));
  5613. }
  5614. TEST_F(ValidateMemory, UntypedVariableBadInitializer) {
  5615. const std::string spirv = R"(
  5616. OpCapability Shader
  5617. OpCapability Linkage
  5618. OpCapability UntypedPointersKHR
  5619. OpExtension "SPV_KHR_untyped_pointers"
  5620. OpMemoryModel Logical GLSL450
  5621. %int = OpTypeInt 32 0
  5622. %float = OpTypeFloat 32
  5623. %float_0 = OpConstant %float 0
  5624. %ptr = OpTypeUntypedPointerKHR Private
  5625. %var = OpUntypedVariableKHR %ptr Private %int %float_0
  5626. )";
  5627. CompileSuccessfully(spirv);
  5628. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5629. EXPECT_THAT(getDiagnosticString(),
  5630. HasSubstr("Initializer type must match the data type"));
  5631. }
  5632. TEST_F(ValidateMemory, AccessChainBaseUntypedPointer) {
  5633. const std::string spirv = R"(
  5634. OpCapability Shader
  5635. OpCapability UntypedPointersKHR
  5636. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5637. OpExtension "SPV_KHR_untyped_pointers"
  5638. OpMemoryModel Logical GLSL450
  5639. OpEntryPoint GLCompute %main "main"
  5640. OpName %var "var"
  5641. %void = OpTypeVoid
  5642. %int = OpTypeInt 32 0
  5643. %int_0 = OpConstant %int 0
  5644. %block = OpTypeStruct %int
  5645. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5646. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  5647. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5648. %var = OpUntypedVariableKHR %ptr StorageBuffer %int
  5649. %void_fn = OpTypeFunction %void
  5650. %main = OpFunction %void None %void_fn
  5651. %entry = OpLabel
  5652. %gep = OpAccessChain %ptr_ssbo_int %var %int_0
  5653. OpReturn
  5654. OpFunctionEnd
  5655. )";
  5656. CompileSuccessfully(spirv);
  5657. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5658. EXPECT_THAT(getDiagnosticString(),
  5659. HasSubstr("The Base <id> '2[%var]' in OpAccessChain "
  5660. "instruction must be a pointer"));
  5661. }
  5662. using ValidateMemoryUntypedAccessChain = spvtest::ValidateBase<std::string>;
  5663. TEST_P(ValidateMemoryUntypedAccessChain, GoodTypedPointerBase) {
  5664. const std::string opcode = GetParam();
  5665. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5666. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5667. const std::string extra_param = ptr ? "%int_0" : "";
  5668. const std::string spirv = R"(
  5669. OpCapability Shader
  5670. OpCapability UntypedPointersKHR
  5671. OpCapability VariablePointers
  5672. OpExtension "SPV_KHR_variable_pointers"
  5673. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5674. OpExtension "SPV_KHR_untyped_pointers"
  5675. OpMemoryModel Logical GLSL450
  5676. OpEntryPoint GLCompute %main "main"
  5677. %void = OpTypeVoid
  5678. %int = OpTypeInt 32 0
  5679. %int_0 = OpConstant %int 0
  5680. %block = OpTypeStruct %int
  5681. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5682. %var = OpVariable %ptr_ssbo StorageBuffer
  5683. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5684. %void_fn = OpTypeFunction %void
  5685. %main = OpFunction %void None %void_fn
  5686. %entry = OpLabel
  5687. %gep = )" + opcode + R"( %ptr %block %var )" +
  5688. extra_param + R"( %int_0
  5689. OpReturn
  5690. OpFunctionEnd
  5691. )";
  5692. CompileSuccessfully(spirv);
  5693. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5694. }
  5695. TEST_P(ValidateMemoryUntypedAccessChain, GoodUntypedPointerBase) {
  5696. const std::string opcode = GetParam();
  5697. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5698. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5699. const std::string extra_param = ptr ? "%int_0" : "";
  5700. const std::string spirv = R"(
  5701. OpCapability Shader
  5702. OpCapability UntypedPointersKHR
  5703. OpCapability VariablePointers
  5704. OpExtension "SPV_KHR_variable_pointers"
  5705. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5706. OpExtension "SPV_KHR_untyped_pointers"
  5707. OpMemoryModel Logical GLSL450
  5708. OpEntryPoint GLCompute %main "main"
  5709. %void = OpTypeVoid
  5710. %int = OpTypeInt 32 0
  5711. %int_0 = OpConstant %int 0
  5712. %block = OpTypeStruct %int
  5713. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5714. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5715. %var = OpUntypedVariableKHR %ptr StorageBuffer %int
  5716. %void_fn = OpTypeFunction %void
  5717. %main = OpFunction %void None %void_fn
  5718. %entry = OpLabel
  5719. %gep = )" + opcode + R"( %ptr %block %var )" +
  5720. extra_param + R"( %int_0
  5721. OpReturn
  5722. OpFunctionEnd
  5723. )";
  5724. CompileSuccessfully(spirv);
  5725. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  5726. }
  5727. TEST_P(ValidateMemoryUntypedAccessChain, ResultTypedPointer) {
  5728. const std::string opcode = GetParam();
  5729. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5730. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5731. const std::string extra_param = ptr ? "%int_0" : "";
  5732. const std::string spirv = R"(
  5733. OpCapability Shader
  5734. OpCapability UntypedPointersKHR
  5735. OpCapability VariablePointers
  5736. OpExtension "SPV_KHR_variable_pointers"
  5737. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5738. OpExtension "SPV_KHR_untyped_pointers"
  5739. OpMemoryModel Logical GLSL450
  5740. OpEntryPoint GLCompute %main "main"
  5741. OpName %gep "gep"
  5742. %void = OpTypeVoid
  5743. %int = OpTypeInt 32 0
  5744. %int_0 = OpConstant %int 0
  5745. %block = OpTypeStruct %int
  5746. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5747. %var = OpVariable %ptr_ssbo StorageBuffer
  5748. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5749. %ptr_int = OpTypePointer StorageBuffer %int
  5750. %void_fn = OpTypeFunction %void
  5751. %main = OpFunction %void None %void_fn
  5752. %entry = OpLabel
  5753. %gep = )" + opcode + R"( %ptr_int %block %var )" +
  5754. extra_param + R"( %int_0
  5755. OpReturn
  5756. OpFunctionEnd
  5757. )";
  5758. CompileSuccessfully(spirv);
  5759. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5760. EXPECT_THAT(getDiagnosticString(),
  5761. HasSubstr("The Result Type of " + opcode +
  5762. " <id> '2[%gep]' must be OpTypeUntypedPointer"));
  5763. }
  5764. TEST_P(ValidateMemoryUntypedAccessChain, BaseTypeNotAType) {
  5765. const std::string opcode = GetParam();
  5766. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5767. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5768. const std::string extra_param = ptr ? "%int_0" : "";
  5769. const std::string spirv = R"(
  5770. OpCapability Shader
  5771. OpCapability UntypedPointersKHR
  5772. OpCapability VariablePointers
  5773. OpExtension "SPV_KHR_variable_pointers"
  5774. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5775. OpExtension "SPV_KHR_untyped_pointers"
  5776. OpMemoryModel Logical GLSL450
  5777. OpEntryPoint GLCompute %main "main"
  5778. OpName %gep "gep"
  5779. %void = OpTypeVoid
  5780. %int = OpTypeInt 32 0
  5781. %int_0 = OpConstant %int 0
  5782. %block = OpTypeStruct %int
  5783. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5784. %var = OpVariable %ptr_ssbo StorageBuffer
  5785. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5786. %void_fn = OpTypeFunction %void
  5787. %main = OpFunction %void None %void_fn
  5788. %entry = OpLabel
  5789. %gep = )" + opcode + R"( %ptr %int_0 %var )" +
  5790. extra_param + R"( %int_0
  5791. OpReturn
  5792. OpFunctionEnd
  5793. )";
  5794. CompileSuccessfully(spirv);
  5795. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5796. EXPECT_THAT(getDiagnosticString(),
  5797. HasSubstr("Base type must be a non-pointer type"));
  5798. }
  5799. TEST_P(ValidateMemoryUntypedAccessChain, BaseTypedPointer) {
  5800. const std::string opcode = GetParam();
  5801. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5802. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5803. const std::string extra_param = ptr ? "%int_0" : "";
  5804. const std::string spirv = R"(
  5805. OpCapability Shader
  5806. OpCapability UntypedPointersKHR
  5807. OpCapability VariablePointers
  5808. OpExtension "SPV_KHR_variable_pointers"
  5809. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5810. OpExtension "SPV_KHR_untyped_pointers"
  5811. OpMemoryModel Logical GLSL450
  5812. OpEntryPoint GLCompute %main "main"
  5813. OpName %gep "gep"
  5814. %void = OpTypeVoid
  5815. %int = OpTypeInt 32 0
  5816. %int_0 = OpConstant %int 0
  5817. %block = OpTypeStruct %int
  5818. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5819. %var = OpVariable %ptr_ssbo StorageBuffer
  5820. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5821. %void_fn = OpTypeFunction %void
  5822. %main = OpFunction %void None %void_fn
  5823. %entry = OpLabel
  5824. %gep = )" + opcode + R"( %ptr %ptr_ssbo %var )" +
  5825. extra_param + R"( %int_0
  5826. OpReturn
  5827. OpFunctionEnd
  5828. )";
  5829. CompileSuccessfully(spirv);
  5830. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5831. EXPECT_THAT(getDiagnosticString(),
  5832. HasSubstr("Base type must be a non-pointer type"));
  5833. }
  5834. TEST_P(ValidateMemoryUntypedAccessChain, BaseUntypedPointer) {
  5835. const std::string opcode = GetParam();
  5836. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5837. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5838. const std::string extra_param = ptr ? "%int_0" : "";
  5839. const std::string spirv = R"(
  5840. OpCapability Shader
  5841. OpCapability UntypedPointersKHR
  5842. OpCapability VariablePointers
  5843. OpExtension "SPV_KHR_variable_pointers"
  5844. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5845. OpExtension "SPV_KHR_untyped_pointers"
  5846. OpMemoryModel Logical GLSL450
  5847. OpEntryPoint GLCompute %main "main"
  5848. OpName %gep "gep"
  5849. %void = OpTypeVoid
  5850. %int = OpTypeInt 32 0
  5851. %int_0 = OpConstant %int 0
  5852. %block = OpTypeStruct %int
  5853. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5854. %var = OpVariable %ptr_ssbo StorageBuffer
  5855. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5856. %void_fn = OpTypeFunction %void
  5857. %main = OpFunction %void None %void_fn
  5858. %entry = OpLabel
  5859. %gep = )" + opcode + R"( %ptr %ptr %var )" +
  5860. extra_param + R"( %int_0
  5861. OpReturn
  5862. OpFunctionEnd
  5863. )";
  5864. CompileSuccessfully(spirv);
  5865. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5866. EXPECT_THAT(getDiagnosticString(),
  5867. HasSubstr("Base type must be a non-pointer type"));
  5868. }
  5869. TEST_P(ValidateMemoryUntypedAccessChain, BaseNotAPointer) {
  5870. const std::string opcode = GetParam();
  5871. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5872. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5873. const std::string extra_param = ptr ? "%int_0" : "";
  5874. const std::string spirv = R"(
  5875. OpCapability Shader
  5876. OpCapability UntypedPointersKHR
  5877. OpCapability VariablePointers
  5878. OpExtension "SPV_KHR_variable_pointers"
  5879. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5880. OpExtension "SPV_KHR_untyped_pointers"
  5881. OpMemoryModel Logical GLSL450
  5882. OpEntryPoint GLCompute %main "main"
  5883. OpName %int_0 "int_0"
  5884. %void = OpTypeVoid
  5885. %int = OpTypeInt 32 0
  5886. %int_0 = OpConstant %int 0
  5887. %block = OpTypeStruct %int
  5888. %ptr_ssbo = OpTypePointer StorageBuffer %block
  5889. %var = OpVariable %ptr_ssbo StorageBuffer
  5890. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5891. %void_fn = OpTypeFunction %void
  5892. %main = OpFunction %void None %void_fn
  5893. %entry = OpLabel
  5894. %gep = )" + opcode + R"( %ptr %int %int_0 )" +
  5895. extra_param + R"( %int_0
  5896. OpReturn
  5897. OpFunctionEnd
  5898. )";
  5899. CompileSuccessfully(spirv);
  5900. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5901. EXPECT_THAT(getDiagnosticString(),
  5902. HasSubstr("The Base <id> '2[%int_0]' in " + opcode +
  5903. " instruction must be a pointer"));
  5904. }
  5905. TEST_P(ValidateMemoryUntypedAccessChain, StorageClassMismatch) {
  5906. const std::string opcode = GetParam();
  5907. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5908. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5909. const std::string extra_param = ptr ? "%int_0" : "";
  5910. const std::string spirv = R"(
  5911. OpCapability Shader
  5912. OpCapability UntypedPointersKHR
  5913. OpCapability VariablePointers
  5914. OpExtension "SPV_KHR_variable_pointers"
  5915. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5916. OpExtension "SPV_KHR_untyped_pointers"
  5917. OpMemoryModel Logical GLSL450
  5918. OpEntryPoint GLCompute %main "main"
  5919. OpName %int_0 "int_0"
  5920. %void = OpTypeVoid
  5921. %int = OpTypeInt 32 0
  5922. %int_0 = OpConstant %int 0
  5923. %block = OpTypeStruct %int
  5924. %ptr_wg = OpTypePointer Workgroup %block
  5925. %var = OpVariable %ptr_wg Workgroup
  5926. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5927. %void_fn = OpTypeFunction %void
  5928. %main = OpFunction %void None %void_fn
  5929. %entry = OpLabel
  5930. %gep = )" + opcode + R"( %ptr %block %var )" +
  5931. extra_param + R"( %int_0
  5932. OpReturn
  5933. OpFunctionEnd
  5934. )";
  5935. CompileSuccessfully(spirv);
  5936. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5937. EXPECT_THAT(
  5938. getDiagnosticString(),
  5939. HasSubstr("The result pointer storage class and base pointer storage "
  5940. "class in " +
  5941. opcode + " do not match"));
  5942. }
  5943. TEST_P(ValidateMemoryUntypedAccessChain, NonCompositeBase) {
  5944. const std::string opcode = GetParam();
  5945. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5946. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5947. const std::string extra_param = ptr ? "%int_0" : "";
  5948. const std::string spirv = R"(
  5949. OpCapability Shader
  5950. OpCapability UntypedPointersKHR
  5951. OpCapability VariablePointers
  5952. OpExtension "SPV_KHR_variable_pointers"
  5953. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5954. OpExtension "SPV_KHR_untyped_pointers"
  5955. OpMemoryModel Logical GLSL450
  5956. OpEntryPoint GLCompute %main "main"
  5957. OpName %int_0 "int_0"
  5958. %void = OpTypeVoid
  5959. %int = OpTypeInt 32 0
  5960. %int_0 = OpConstant %int 0
  5961. %block = OpTypeStruct %int
  5962. %ptr_wg = OpTypePointer StorageBuffer %block
  5963. %var = OpVariable %ptr_wg StorageBuffer
  5964. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  5965. %void_fn = OpTypeFunction %void
  5966. %main = OpFunction %void None %void_fn
  5967. %entry = OpLabel
  5968. %gep = )" + opcode + R"( %ptr %int %var )" +
  5969. extra_param + R"( %int_0
  5970. OpReturn
  5971. OpFunctionEnd
  5972. )";
  5973. CompileSuccessfully(spirv);
  5974. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5975. EXPECT_THAT(getDiagnosticString(),
  5976. HasSubstr(opcode + " reached non-composite type while indexes "
  5977. "still remain to be traversed"));
  5978. }
  5979. TEST_P(ValidateMemoryUntypedAccessChain, TooManyIndices) {
  5980. const std::string opcode = GetParam();
  5981. const bool ptr = opcode == "OpUntypedPtrAccessChainKHR" ||
  5982. opcode == "OpUntypedInBoundsPtrAccessChainKHR";
  5983. const std::string extra_param = ptr ? "%int_0" : "";
  5984. const std::string spirv = R"(
  5985. OpCapability Shader
  5986. OpCapability UntypedPointersKHR
  5987. OpCapability VariablePointers
  5988. OpExtension "SPV_KHR_variable_pointers"
  5989. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5990. OpExtension "SPV_KHR_untyped_pointers"
  5991. OpMemoryModel Logical GLSL450
  5992. OpEntryPoint GLCompute %main "main"
  5993. OpName %int_0 "int_0"
  5994. %void = OpTypeVoid
  5995. %int = OpTypeInt 32 0
  5996. %int_0 = OpConstant %int 0
  5997. %block = OpTypeStruct %int
  5998. %ptr_wg = OpTypePointer StorageBuffer %block
  5999. %var = OpVariable %ptr_wg StorageBuffer
  6000. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6001. %void_fn = OpTypeFunction %void
  6002. %main = OpFunction %void None %void_fn
  6003. %entry = OpLabel
  6004. %gep = )" + opcode + R"( %ptr %block %var )" +
  6005. extra_param + R"( %int_0 %int_0
  6006. OpReturn
  6007. OpFunctionEnd
  6008. )";
  6009. CompileSuccessfully(spirv);
  6010. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6011. EXPECT_THAT(getDiagnosticString(),
  6012. HasSubstr(opcode + " reached non-composite type while indexes "
  6013. "still remain to be traversed"));
  6014. }
  6015. INSTANTIATE_TEST_SUITE_P(
  6016. ValidateUntypedAccessChains, ValidateMemoryUntypedAccessChain,
  6017. Values("OpUntypedAccessChainKHR", "OpUntypedInBoundsAccessChainKHR",
  6018. "OpUntypedPtrAccessChainKHR", "OpUntypedInBoundsPtrAccessChainKHR"));
  6019. TEST_F(ValidateMemory, LoadUntypedPointerGood) {
  6020. const std::string spirv = R"(
  6021. OpCapability Shader
  6022. OpCapability UntypedPointersKHR
  6023. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6024. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6025. OpExtension "SPV_KHR_untyped_pointers"
  6026. OpMemoryModel Logical GLSL450
  6027. OpEntryPoint GLCompute %main "main" %var
  6028. OpDecorate %struct Block
  6029. OpMemberDecorate %struct 0 Offset 0
  6030. %void = OpTypeVoid
  6031. %int = OpTypeInt 32 0
  6032. %float = OpTypeFloat 32
  6033. %struct = OpTypeStruct %int
  6034. %ptr = OpTypeUntypedPointerKHR Workgroup
  6035. %var = OpUntypedVariableKHR %ptr Workgroup %struct
  6036. %void_fn = OpTypeFunction %void
  6037. %main = OpFunction %void None %void_fn
  6038. %entry = OpLabel
  6039. %load = OpLoad %float %var
  6040. OpReturn
  6041. OpFunctionEnd
  6042. )";
  6043. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6044. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6045. }
  6046. TEST_F(ValidateMemory, StoreUntypedPointerGood) {
  6047. const std::string spirv = R"(
  6048. OpCapability Shader
  6049. OpCapability UntypedPointersKHR
  6050. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6051. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6052. OpExtension "SPV_KHR_untyped_pointers"
  6053. OpMemoryModel Logical GLSL450
  6054. OpEntryPoint GLCompute %main "main" %var
  6055. OpDecorate %struct Block
  6056. OpMemberDecorate %struct 0 Offset 0
  6057. %void = OpTypeVoid
  6058. %int = OpTypeInt 32 0
  6059. %float = OpTypeFloat 32
  6060. %float_0 = OpConstant %float 0
  6061. %struct = OpTypeStruct %int
  6062. %ptr = OpTypeUntypedPointerKHR Workgroup
  6063. %var = OpUntypedVariableKHR %ptr Workgroup %struct
  6064. %void_fn = OpTypeFunction %void
  6065. %main = OpFunction %void None %void_fn
  6066. %entry = OpLabel
  6067. OpStore %var %float_0
  6068. OpReturn
  6069. OpFunctionEnd
  6070. )";
  6071. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6072. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6073. }
  6074. TEST_F(ValidateMemory, CopyMemoryUntypedPointerSourceGood) {
  6075. const std::string spirv = R"(
  6076. OpCapability Shader
  6077. OpCapability UntypedPointersKHR
  6078. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6079. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6080. OpExtension "SPV_KHR_untyped_pointers"
  6081. OpMemoryModel Logical GLSL450
  6082. OpEntryPoint GLCompute %main "main" %var1 %var2
  6083. OpName %var1 "var1"
  6084. OpDecorate %struct Block
  6085. OpMemberDecorate %struct 0 Offset 0
  6086. %void = OpTypeVoid
  6087. %int = OpTypeInt 32 0
  6088. %struct = OpTypeStruct %int
  6089. %ptr = OpTypeUntypedPointerKHR Workgroup
  6090. %var1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6091. %ptr_wg = OpTypePointer Workgroup %int
  6092. %var2 = OpVariable %ptr_wg Workgroup
  6093. %void_fn = OpTypeFunction %void
  6094. %main = OpFunction %void None %void_fn
  6095. %entry = OpLabel
  6096. OpCopyMemory %var2 %var1
  6097. OpReturn
  6098. OpFunctionEnd
  6099. )";
  6100. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6101. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6102. }
  6103. TEST_F(ValidateMemory, CopyMemoryUntypedPointerTargetGood) {
  6104. const std::string spirv = R"(
  6105. OpCapability Shader
  6106. OpCapability UntypedPointersKHR
  6107. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6108. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6109. OpExtension "SPV_KHR_untyped_pointers"
  6110. OpMemoryModel Logical GLSL450
  6111. OpEntryPoint GLCompute %main "main" %var1 %var2
  6112. OpName %var1 "var1"
  6113. OpDecorate %struct Block
  6114. OpMemberDecorate %struct 0 Offset 0
  6115. %void = OpTypeVoid
  6116. %int = OpTypeInt 32 0
  6117. %struct = OpTypeStruct %int
  6118. %ptr = OpTypeUntypedPointerKHR Workgroup
  6119. %var1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6120. %ptr_wg = OpTypePointer Workgroup %int
  6121. %var2 = OpVariable %ptr_wg Workgroup
  6122. %void_fn = OpTypeFunction %void
  6123. %main = OpFunction %void None %void_fn
  6124. %entry = OpLabel
  6125. OpCopyMemory %var1 %var2
  6126. OpReturn
  6127. OpFunctionEnd
  6128. )";
  6129. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6130. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6131. }
  6132. TEST_F(ValidateMemory, CopyMemoryUntypedPointerTargetAndSourceBad) {
  6133. const std::string spirv = R"(
  6134. OpCapability Shader
  6135. OpCapability UntypedPointersKHR
  6136. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6137. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6138. OpExtension "SPV_KHR_untyped_pointers"
  6139. OpMemoryModel Logical GLSL450
  6140. OpEntryPoint GLCompute %main "main" %var1 %var2
  6141. OpName %var1 "var1"
  6142. OpDecorate %struct Block
  6143. OpMemberDecorate %struct 0 Offset 0
  6144. %void = OpTypeVoid
  6145. %int = OpTypeInt 32 0
  6146. %struct = OpTypeStruct %int
  6147. %ptr = OpTypeUntypedPointerKHR Workgroup
  6148. %var1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6149. %var2 = OpUntypedVariableKHR %ptr Workgroup %struct
  6150. %void_fn = OpTypeFunction %void
  6151. %main = OpFunction %void None %void_fn
  6152. %entry = OpLabel
  6153. OpCopyMemory %var1 %var2
  6154. OpReturn
  6155. OpFunctionEnd
  6156. )";
  6157. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6158. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6159. EXPECT_THAT(getDiagnosticString(),
  6160. HasSubstr("One of Source or Target must be a typed pointer"));
  6161. }
  6162. TEST_F(ValidateMemory, CopyMemorySizedUntypedPointersGood) {
  6163. const std::string spirv = R"(
  6164. OpCapability Shader
  6165. OpCapability UntypedPointersKHR
  6166. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6167. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6168. OpExtension "SPV_KHR_untyped_pointers"
  6169. OpMemoryModel Logical GLSL450
  6170. OpEntryPoint GLCompute %main "main" %v1 %v2
  6171. OpDecorate %struct Block
  6172. OpMemberDecorate %struct 0 Offset 0
  6173. %void = OpTypeVoid
  6174. %int = OpTypeInt 32 0
  6175. %int_4 = OpConstant %int 4
  6176. %struct = OpTypeStruct %int
  6177. %ptr = OpTypeUntypedPointerKHR Workgroup
  6178. %v1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6179. %v2 = OpUntypedVariableKHR %ptr Workgroup %struct
  6180. %void_fn = OpTypeFunction %void
  6181. %main = OpFunction %void None %void_fn
  6182. %entry = OpLabel
  6183. OpCopyMemorySized %v2 %v1 %int_4
  6184. OpReturn
  6185. OpFunctionEnd
  6186. )";
  6187. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6188. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6189. }
  6190. TEST_F(ValidateMemory, CopyMemorySizedUntypedPointersSizeBad1) {
  6191. const std::string spirv = R"(
  6192. OpCapability Shader
  6193. OpCapability UntypedPointersKHR
  6194. OpCapability StorageBuffer16BitAccess
  6195. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6196. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6197. OpExtension "SPV_KHR_untyped_pointers"
  6198. OpMemoryModel Logical GLSL450
  6199. OpEntryPoint GLCompute %main "main" %var_wg %var_ssbo
  6200. OpDecorate %struct Block
  6201. OpMemberDecorate %struct 0 Offset 0
  6202. %void = OpTypeVoid
  6203. %int = OpTypeInt 32 0
  6204. %short = OpTypeInt 16 0
  6205. %int_2 = OpConstant %int 2
  6206. %struct = OpTypeStruct %int
  6207. %ptr_ssbo = OpTypeUntypedPointerKHR StorageBuffer
  6208. %ptr_wg = OpTypeUntypedPointerKHR Workgroup
  6209. %var_ssbo = OpUntypedVariableKHR %ptr_ssbo StorageBuffer %struct
  6210. %var_wg = OpUntypedVariableKHR %ptr_wg Workgroup %struct
  6211. %void_fn = OpTypeFunction %void
  6212. %main = OpFunction %void None %void_fn
  6213. %entry = OpLabel
  6214. OpCopyMemorySized %var_ssbo %var_wg %int_2
  6215. OpReturn
  6216. OpFunctionEnd
  6217. )";
  6218. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6219. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6220. EXPECT_THAT(getDiagnosticString(), HasSubstr("Size must be a multiple of 4"));
  6221. }
  6222. TEST_F(ValidateMemory, CopyMemorySizedUntypedPointersSizeBad2) {
  6223. const std::string spirv = R"(
  6224. OpCapability Shader
  6225. OpCapability UntypedPointersKHR
  6226. OpCapability StorageBuffer16BitAccess
  6227. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6228. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6229. OpExtension "SPV_KHR_untyped_pointers"
  6230. OpMemoryModel Logical GLSL450
  6231. OpEntryPoint GLCompute %main "main" %var_ssbo %var_wg
  6232. OpDecorate %struct Block
  6233. OpMemberDecorate %struct 0 Offset 0
  6234. %void = OpTypeVoid
  6235. %int = OpTypeInt 32 0
  6236. %short = OpTypeInt 16 0
  6237. %int_2 = OpConstant %int 2
  6238. %struct = OpTypeStruct %int
  6239. %ptr_ssbo = OpTypeUntypedPointerKHR StorageBuffer
  6240. %ptr_wg = OpTypeUntypedPointerKHR Workgroup
  6241. %var_ssbo = OpUntypedVariableKHR %ptr_ssbo StorageBuffer %struct
  6242. %var_wg = OpUntypedVariableKHR %ptr_wg Workgroup %struct
  6243. %void_fn = OpTypeFunction %void
  6244. %main = OpFunction %void None %void_fn
  6245. %entry = OpLabel
  6246. OpCopyMemorySized %var_wg %var_ssbo %int_2
  6247. OpReturn
  6248. OpFunctionEnd
  6249. )";
  6250. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6251. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6252. EXPECT_THAT(getDiagnosticString(), HasSubstr("Size must be a multiple of 4"));
  6253. }
  6254. TEST_F(ValidateMemory, CopyMemorySizedUntypedPointersSizeBad3) {
  6255. const std::string spirv = R"(
  6256. OpCapability Shader
  6257. OpCapability Int16
  6258. OpCapability UntypedPointersKHR
  6259. OpCapability StorageBuffer8BitAccess
  6260. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6261. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6262. OpExtension "SPV_KHR_8bit_storage"
  6263. OpExtension "SPV_KHR_untyped_pointers"
  6264. OpMemoryModel Logical GLSL450
  6265. OpEntryPoint GLCompute %main "main" %var_ssbo %var_wg
  6266. OpDecorate %struct Block
  6267. OpMemberDecorate %struct 0 Offset 0
  6268. %void = OpTypeVoid
  6269. %int = OpTypeInt 32 0
  6270. %short = OpTypeInt 16 0
  6271. %int_1 = OpConstant %int 1
  6272. %struct = OpTypeStruct %int
  6273. %ptr_ssbo = OpTypeUntypedPointerKHR StorageBuffer
  6274. %ptr_wg = OpTypeUntypedPointerKHR Workgroup
  6275. %var_ssbo = OpUntypedVariableKHR %ptr_ssbo StorageBuffer %struct
  6276. %var_wg = OpUntypedVariableKHR %ptr_wg Workgroup %struct
  6277. %void_fn = OpTypeFunction %void
  6278. %main = OpFunction %void None %void_fn
  6279. %entry = OpLabel
  6280. OpCopyMemorySized %var_ssbo %var_wg %int_1
  6281. OpReturn
  6282. OpFunctionEnd
  6283. )";
  6284. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6285. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6286. EXPECT_THAT(getDiagnosticString(), HasSubstr("Size must be a multiple of 2"));
  6287. }
  6288. TEST_F(ValidateMemory, CopyMemorySizedUntypedPointersSizeBad4) {
  6289. const std::string spirv = R"(
  6290. OpCapability Shader
  6291. OpCapability Int16
  6292. OpCapability UntypedPointersKHR
  6293. OpCapability StorageBuffer8BitAccess
  6294. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6295. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6296. OpExtension "SPV_KHR_8bit_storage"
  6297. OpExtension "SPV_KHR_untyped_pointers"
  6298. OpMemoryModel Logical GLSL450
  6299. OpEntryPoint GLCompute %main "main" %var_ssbo %var_wg
  6300. OpDecorate %struct Block
  6301. OpMemberDecorate %struct 0 Offset 0
  6302. %void = OpTypeVoid
  6303. %int = OpTypeInt 32 0
  6304. %short = OpTypeInt 16 0
  6305. %int_1 = OpConstant %int 1
  6306. %struct = OpTypeStruct %int
  6307. %ptr_ssbo = OpTypeUntypedPointerKHR StorageBuffer
  6308. %ptr_wg = OpTypeUntypedPointerKHR Workgroup
  6309. %var_ssbo = OpUntypedVariableKHR %ptr_ssbo StorageBuffer %struct
  6310. %var_wg = OpUntypedVariableKHR %ptr_wg Workgroup %struct
  6311. %void_fn = OpTypeFunction %void
  6312. %main = OpFunction %void None %void_fn
  6313. %entry = OpLabel
  6314. OpCopyMemorySized %var_wg %var_ssbo %int_1
  6315. OpReturn
  6316. OpFunctionEnd
  6317. )";
  6318. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6319. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6320. EXPECT_THAT(getDiagnosticString(), HasSubstr("Size must be a multiple of 2"));
  6321. }
  6322. TEST_F(ValidateMemory, PtrEqualUntypedPointersGood) {
  6323. const std::string spirv = R"(
  6324. OpCapability Shader
  6325. OpCapability VariablePointers
  6326. OpCapability UntypedPointersKHR
  6327. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6328. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6329. OpExtension "SPV_KHR_untyped_pointers"
  6330. OpMemoryModel Logical GLSL450
  6331. OpEntryPoint GLCompute %main "main" %v1 %v2
  6332. OpDecorate %struct Block
  6333. OpMemberDecorate %struct 0 Offset 0
  6334. %void = OpTypeVoid
  6335. %bool = OpTypeBool
  6336. %int = OpTypeInt 32 0
  6337. %struct = OpTypeStruct %int
  6338. %ptr = OpTypeUntypedPointerKHR Workgroup
  6339. %v1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6340. %v2 = OpUntypedVariableKHR %ptr Workgroup %struct
  6341. %void_fn = OpTypeFunction %void
  6342. %main = OpFunction %void None %void_fn
  6343. %entry = OpLabel
  6344. %res = OpPtrEqual %bool %v1 %v2
  6345. OpReturn
  6346. OpFunctionEnd
  6347. )";
  6348. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6349. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6350. }
  6351. TEST_F(ValidateMemory, PtrNotEqualUntypedPointersGood) {
  6352. const std::string spirv = R"(
  6353. OpCapability Shader
  6354. OpCapability VariablePointers
  6355. OpCapability UntypedPointersKHR
  6356. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6357. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6358. OpExtension "SPV_KHR_untyped_pointers"
  6359. OpMemoryModel Logical GLSL450
  6360. OpEntryPoint GLCompute %main "main" %v1 %v2
  6361. OpDecorate %struct Block
  6362. OpMemberDecorate %struct 0 Offset 0
  6363. %void = OpTypeVoid
  6364. %bool = OpTypeBool
  6365. %int = OpTypeInt 32 0
  6366. %struct = OpTypeStruct %int
  6367. %ptr = OpTypeUntypedPointerKHR Workgroup
  6368. %v1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6369. %v2 = OpUntypedVariableKHR %ptr Workgroup %struct
  6370. %void_fn = OpTypeFunction %void
  6371. %main = OpFunction %void None %void_fn
  6372. %entry = OpLabel
  6373. %res = OpPtrNotEqual %bool %v1 %v2
  6374. OpReturn
  6375. OpFunctionEnd
  6376. )";
  6377. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6378. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6379. }
  6380. TEST_F(ValidateMemory, PtrDiffUntypedPointersGood) {
  6381. const std::string spirv = R"(
  6382. OpCapability Shader
  6383. OpCapability VariablePointers
  6384. OpCapability UntypedPointersKHR
  6385. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6386. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6387. OpExtension "SPV_KHR_untyped_pointers"
  6388. OpMemoryModel Logical GLSL450
  6389. OpEntryPoint GLCompute %main "main" %v1
  6390. OpDecorate %struct Block
  6391. OpMemberDecorate %struct 0 Offset 0
  6392. %void = OpTypeVoid
  6393. %int = OpTypeInt 32 0
  6394. %struct = OpTypeStruct %int
  6395. %ptr = OpTypeUntypedPointerKHR Workgroup
  6396. %v1 = OpUntypedVariableKHR %ptr Workgroup %struct
  6397. %void_fn = OpTypeFunction %void
  6398. %main = OpFunction %void None %void_fn
  6399. %entry = OpLabel
  6400. %res = OpPtrDiff %int %v1 %v1
  6401. OpReturn
  6402. OpFunctionEnd
  6403. )";
  6404. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
  6405. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  6406. }
  6407. TEST_F(ValidateMemory, UntypedVariableVulkanPushConstantGood) {
  6408. const std::string spirv = R"(
  6409. OpCapability Shader
  6410. OpCapability UntypedPointersKHR
  6411. OpExtension "SPV_KHR_untyped_pointers"
  6412. OpMemoryModel Logical GLSL450
  6413. OpEntryPoint GLCompute %main "main"
  6414. OpExecutionMode %main LocalSize 1 1 1
  6415. OpDecorate %struct Block
  6416. OpMemberDecorate %struct 0 Offset 0
  6417. %void = OpTypeVoid
  6418. %int = OpTypeInt 32 0
  6419. %struct = OpTypeStruct %int
  6420. %ptr = OpTypeUntypedPointerKHR PushConstant
  6421. %var = OpUntypedVariableKHR %ptr PushConstant %struct
  6422. %void_fn = OpTypeFunction %void
  6423. %main = OpFunction %void None %void_fn
  6424. %entry = OpLabel
  6425. OpReturn
  6426. OpFunctionEnd
  6427. )";
  6428. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6429. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6430. }
  6431. TEST_F(ValidateMemory, UntypedVariableVulkanStorageBufferGood) {
  6432. const std::string spirv = R"(
  6433. OpCapability Shader
  6434. OpCapability UntypedPointersKHR
  6435. OpExtension "SPV_KHR_untyped_pointers"
  6436. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6437. OpMemoryModel Logical GLSL450
  6438. OpEntryPoint GLCompute %main "main"
  6439. OpExecutionMode %main LocalSize 1 1 1
  6440. OpDecorate %struct Block
  6441. OpMemberDecorate %struct 0 Offset 0
  6442. OpDecorate %var DescriptorSet 0
  6443. OpDecorate %var Binding 0
  6444. %void = OpTypeVoid
  6445. %int = OpTypeInt 32 0
  6446. %struct = OpTypeStruct %int
  6447. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6448. %var = OpUntypedVariableKHR %ptr StorageBuffer %struct
  6449. %void_fn = OpTypeFunction %void
  6450. %main = OpFunction %void None %void_fn
  6451. %entry = OpLabel
  6452. OpReturn
  6453. OpFunctionEnd
  6454. )";
  6455. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6456. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6457. }
  6458. TEST_F(ValidateMemory, UntypedVariableVulkanUniformGood) {
  6459. const std::string spirv = R"(
  6460. OpCapability Shader
  6461. OpCapability UntypedPointersKHR
  6462. OpExtension "SPV_KHR_untyped_pointers"
  6463. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6464. OpMemoryModel Logical GLSL450
  6465. OpEntryPoint GLCompute %main "main"
  6466. OpExecutionMode %main LocalSize 1 1 1
  6467. OpDecorate %struct Block
  6468. OpMemberDecorate %struct 0 Offset 0
  6469. OpDecorate %var DescriptorSet 0
  6470. OpDecorate %var Binding 0
  6471. %void = OpTypeVoid
  6472. %int = OpTypeInt 32 0
  6473. %struct = OpTypeStruct %int
  6474. %ptr = OpTypeUntypedPointerKHR Uniform
  6475. %var = OpUntypedVariableKHR %ptr Uniform %struct
  6476. %void_fn = OpTypeFunction %void
  6477. %main = OpFunction %void None %void_fn
  6478. %entry = OpLabel
  6479. OpReturn
  6480. OpFunctionEnd
  6481. )";
  6482. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
  6483. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  6484. }
  6485. TEST_F(ValidateMemory, UntypedVariableVulkanWorkgroupGood) {
  6486. const std::string spirv = R"(
  6487. OpCapability Shader
  6488. OpCapability UntypedPointersKHR
  6489. OpCapability WorkgroupMemoryExplicitLayoutKHR
  6490. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  6491. OpExtension "SPV_KHR_untyped_pointers"
  6492. OpMemoryModel Logical GLSL450
  6493. OpEntryPoint GLCompute %main "main"
  6494. OpExecutionMode %main LocalSize 1 1 1
  6495. OpDecorate %struct Block
  6496. OpMemberDecorate %struct 0 Offset 0
  6497. %void = OpTypeVoid
  6498. %int = OpTypeInt 32 0
  6499. %struct = OpTypeStruct %int
  6500. %ptr = OpTypeUntypedPointerKHR Workgroup
  6501. %var = OpUntypedVariableKHR %ptr Workgroup %struct
  6502. %void_fn = OpTypeFunction %void
  6503. %main = OpFunction %void None %void_fn
  6504. %entry = OpLabel
  6505. OpReturn
  6506. OpFunctionEnd
  6507. )";
  6508. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  6509. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  6510. }
  6511. TEST_F(ValidateMemory, UntypedPointerAsVariableType) {
  6512. const std::string spirv = R"(
  6513. OpCapability Shader
  6514. OpCapability Linkage
  6515. OpCapability VariablePointers
  6516. OpCapability UntypedPointersKHR
  6517. OpExtension "SPV_KHR_untyped_pointers"
  6518. OpMemoryModel Logical GLSL450
  6519. %void = OpTypeVoid
  6520. %float = OpTypeFloat 32
  6521. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6522. %priv_ptr = OpTypePointer Private %ptr
  6523. %var = OpVariable %priv_ptr Private
  6524. )";
  6525. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6526. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6527. }
  6528. TEST_F(ValidateMemory, UntypedArrayLengthGood) {
  6529. const std::string spirv = R"(
  6530. OpCapability Shader
  6531. OpCapability UntypedPointersKHR
  6532. OpExtension "SPV_KHR_untyped_pointers"
  6533. OpMemoryModel Logical GLSL450
  6534. OpEntryPoint GLCompute %main "main"
  6535. OpExecutionMode %main LocalSize 1 1 1
  6536. OpDecorate %var DescriptorSet 0
  6537. OpDecorate %var Binding 0
  6538. OpDecorate %block Block
  6539. OpMemberDecorate %block 0 Offset 0
  6540. OpDecorate %array ArrayStride 4
  6541. %void = OpTypeVoid
  6542. %int = OpTypeInt 32 0
  6543. %array = OpTypeRuntimeArray %int
  6544. %block = OpTypeStruct %array
  6545. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6546. %var = OpUntypedVariableKHR %ptr StorageBuffer %block
  6547. %void_fn = OpTypeFunction %void
  6548. %main = OpFunction %void None %void_fn
  6549. %entry = OpLabel
  6550. %length = OpUntypedArrayLengthKHR %int %block %var 0
  6551. OpReturn
  6552. OpFunctionEnd
  6553. )";
  6554. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6555. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6556. }
  6557. TEST_F(ValidateMemory, UntypedArrayLengthBadResultType) {
  6558. const std::string spirv = R"(
  6559. OpCapability Shader
  6560. OpCapability UntypedPointersKHR
  6561. OpExtension "SPV_KHR_untyped_pointers"
  6562. OpMemoryModel Logical GLSL450
  6563. OpEntryPoint GLCompute %main "main"
  6564. OpExecutionMode %main LocalSize 1 1 1
  6565. OpDecorate %var DescriptorSet 0
  6566. OpDecorate %var Binding 0
  6567. OpDecorate %block Block
  6568. OpMemberDecorate %block 0 Offset 0
  6569. OpDecorate %array ArrayStride 4
  6570. %void = OpTypeVoid
  6571. %int = OpTypeInt 32 0
  6572. %float = OpTypeFloat 32
  6573. %array = OpTypeRuntimeArray %int
  6574. %block = OpTypeStruct %array
  6575. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6576. %var = OpUntypedVariableKHR %ptr StorageBuffer %block
  6577. %void_fn = OpTypeFunction %void
  6578. %main = OpFunction %void None %void_fn
  6579. %entry = OpLabel
  6580. %length = OpUntypedArrayLengthKHR %float %block %var 0
  6581. OpReturn
  6582. OpFunctionEnd
  6583. )";
  6584. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6585. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6586. EXPECT_THAT(getDiagnosticString(),
  6587. HasSubstr("must be OpTypeInt with width 32 and signedness 0"));
  6588. }
  6589. TEST_F(ValidateMemory, UntypedArrayLengthBadPointer) {
  6590. const std::string spirv = R"(
  6591. OpCapability Shader
  6592. OpCapability UntypedPointersKHR
  6593. OpExtension "SPV_KHR_untyped_pointers"
  6594. OpMemoryModel Logical GLSL450
  6595. OpEntryPoint GLCompute %main "main"
  6596. OpExecutionMode %main LocalSize 1 1 1
  6597. OpDecorate %var DescriptorSet 0
  6598. OpDecorate %var Binding 0
  6599. OpDecorate %block Block
  6600. OpMemberDecorate %block 0 Offset 0
  6601. OpDecorate %array ArrayStride 4
  6602. %void = OpTypeVoid
  6603. %int = OpTypeInt 32 0
  6604. %array = OpTypeRuntimeArray %int
  6605. %block = OpTypeStruct %array
  6606. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6607. %typed_ptr = OpTypePointer StorageBuffer %block
  6608. %var = OpVariable %typed_ptr StorageBuffer
  6609. %void_fn = OpTypeFunction %void
  6610. %main = OpFunction %void None %void_fn
  6611. %entry = OpLabel
  6612. %length = OpUntypedArrayLengthKHR %int %block %var 0
  6613. OpReturn
  6614. OpFunctionEnd
  6615. )";
  6616. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6617. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6618. EXPECT_THAT(getDiagnosticString(),
  6619. HasSubstr("Pointer must be an untyped pointer"));
  6620. }
  6621. TEST_F(ValidateMemory, UntypedArrayLengtBadStruct) {
  6622. const std::string spirv = R"(
  6623. OpCapability Shader
  6624. OpCapability UntypedPointersKHR
  6625. OpExtension "SPV_KHR_untyped_pointers"
  6626. OpMemoryModel Logical GLSL450
  6627. OpEntryPoint GLCompute %main "main"
  6628. OpExecutionMode %main LocalSize 1 1 1
  6629. OpDecorate %var DescriptorSet 0
  6630. OpDecorate %var Binding 0
  6631. OpDecorate %block Block
  6632. OpMemberDecorate %block 0 Offset 0
  6633. OpDecorate %array ArrayStride 4
  6634. %void = OpTypeVoid
  6635. %int = OpTypeInt 32 0
  6636. %array = OpTypeRuntimeArray %int
  6637. %block = OpTypeStruct %array
  6638. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6639. %var = OpUntypedVariableKHR %ptr StorageBuffer %block
  6640. %void_fn = OpTypeFunction %void
  6641. %main = OpFunction %void None %void_fn
  6642. %entry = OpLabel
  6643. %length = OpUntypedArrayLengthKHR %int %int %var 0
  6644. OpReturn
  6645. OpFunctionEnd
  6646. )";
  6647. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6648. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6649. EXPECT_THAT(getDiagnosticString(), HasSubstr("to an OpTypeStruct"));
  6650. }
  6651. TEST_F(ValidateMemory, UntypedArrayLengthLastMemberNotArray) {
  6652. const std::string spirv = R"(
  6653. OpCapability Shader
  6654. OpCapability UntypedPointersKHR
  6655. OpExtension "SPV_KHR_untyped_pointers"
  6656. OpMemoryModel Logical GLSL450
  6657. OpEntryPoint GLCompute %main "main"
  6658. OpExecutionMode %main LocalSize 1 1 1
  6659. OpDecorate %var DescriptorSet 0
  6660. OpDecorate %var Binding 0
  6661. OpDecorate %block Block
  6662. OpMemberDecorate %block 0 Offset 0
  6663. OpDecorate %array ArrayStride 4
  6664. %void = OpTypeVoid
  6665. %int = OpTypeInt 32 0
  6666. %array = OpTypeRuntimeArray %int
  6667. %block = OpTypeStruct %int
  6668. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6669. %var = OpUntypedVariableKHR %ptr StorageBuffer %block
  6670. %void_fn = OpTypeFunction %void
  6671. %main = OpFunction %void None %void_fn
  6672. %entry = OpLabel
  6673. %length = OpUntypedArrayLengthKHR %int %block %var 0
  6674. OpReturn
  6675. OpFunctionEnd
  6676. )";
  6677. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6678. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6679. EXPECT_THAT(getDiagnosticString(),
  6680. HasSubstr("must be an OpTypeRuntimeArray"));
  6681. }
  6682. TEST_F(ValidateMemory, UntypedArrayLengthBadIndex) {
  6683. const std::string spirv = R"(
  6684. OpCapability Shader
  6685. OpCapability UntypedPointersKHR
  6686. OpExtension "SPV_KHR_untyped_pointers"
  6687. OpMemoryModel Logical GLSL450
  6688. OpEntryPoint GLCompute %main "main"
  6689. OpExecutionMode %main LocalSize 1 1 1
  6690. OpDecorate %var DescriptorSet 0
  6691. OpDecorate %var Binding 0
  6692. OpDecorate %block Block
  6693. OpMemberDecorate %block 0 Offset 0
  6694. OpDecorate %array ArrayStride 4
  6695. %void = OpTypeVoid
  6696. %int = OpTypeInt 32 0
  6697. %array = OpTypeRuntimeArray %int
  6698. %block = OpTypeStruct %array
  6699. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  6700. %var = OpUntypedVariableKHR %ptr StorageBuffer %block
  6701. %void_fn = OpTypeFunction %void
  6702. %main = OpFunction %void None %void_fn
  6703. %entry = OpLabel
  6704. %length = OpUntypedArrayLengthKHR %int %block %var 1
  6705. OpReturn
  6706. OpFunctionEnd
  6707. )";
  6708. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  6709. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  6710. EXPECT_THAT(getDiagnosticString(),
  6711. HasSubstr("must be the last member of the struct"));
  6712. }
  6713. TEST_F(ValidateMemory, UntypedCooperativeMatrixLoad) {
  6714. const std::string spirv = R"(
  6715. OpCapability Shader
  6716. OpCapability UntypedPointersKHR
  6717. OpCapability CooperativeMatrixKHR
  6718. OpCapability VulkanMemoryModel
  6719. OpExtension "SPV_KHR_untyped_pointers"
  6720. OpExtension "SPV_KHR_cooperative_matrix"
  6721. OpMemoryModel Logical Vulkan
  6722. OpEntryPoint GLCompute %main "main" %var
  6723. OpExecutionMode %main LocalSize 1 1 1
  6724. OpDecorate %var DescriptorSet 0
  6725. OpDecorate %var Binding 0
  6726. OpDecorate %block Block
  6727. OpMemberDecorate %block 0 Offset 0
  6728. OpDecorate %array ArrayStride 4
  6729. %void = OpTypeVoid
  6730. %void_fn = OpTypeFunction %void
  6731. %untyped = OpTypeUntypedPointerKHR StorageBuffer
  6732. %float = OpTypeFloat 32
  6733. %array = OpTypeRuntimeArray %float
  6734. %block = OpTypeStruct %array
  6735. %int = OpTypeInt 32 0
  6736. %int_0 = OpConstant %int 0
  6737. %subgroup = OpConstant %int 3
  6738. %rows = OpSpecConstant %int 1
  6739. %cols = OpSpecConstant %int 1
  6740. %matrix_a = OpConstant %int 1
  6741. %stride = OpConstant %int 42
  6742. %matrix = OpTypeCooperativeMatrixKHR %float %subgroup %rows %cols %matrix_a
  6743. %var = OpUntypedVariableKHR %untyped StorageBuffer %block
  6744. %main = OpFunction %void None %void_fn
  6745. %entry = OpLabel
  6746. %ld = OpCooperativeMatrixLoadKHR %matrix %var %int_0 %stride
  6747. OpReturn
  6748. OpFunctionEnd
  6749. )";
  6750. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  6751. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  6752. }
  6753. TEST_F(ValidateMemory, UntypedCooperativeMatrixLoad2) {
  6754. const std::string spirv = R"(
  6755. OpCapability Shader
  6756. OpCapability UntypedPointersKHR
  6757. OpCapability CooperativeMatrixKHR
  6758. OpCapability VulkanMemoryModel
  6759. OpExtension "SPV_KHR_untyped_pointers"
  6760. OpExtension "SPV_KHR_cooperative_matrix"
  6761. OpMemoryModel Logical Vulkan
  6762. OpEntryPoint GLCompute %main "main" %var
  6763. OpExecutionMode %main LocalSize 1 1 1
  6764. OpDecorate %var DescriptorSet 0
  6765. OpDecorate %var Binding 0
  6766. OpDecorate %block Block
  6767. OpMemberDecorate %block 0 Offset 0
  6768. OpDecorate %array ArrayStride 4
  6769. %void = OpTypeVoid
  6770. %void_fn = OpTypeFunction %void
  6771. %untyped = OpTypeUntypedPointerKHR StorageBuffer
  6772. %float = OpTypeFloat 32
  6773. %array = OpTypeRuntimeArray %float
  6774. %block = OpTypeStruct %array
  6775. %int = OpTypeInt 32 0
  6776. %int_0 = OpConstant %int 0
  6777. %subgroup = OpConstant %int 3
  6778. %rows = OpSpecConstant %int 1
  6779. %cols = OpSpecConstant %int 1
  6780. %matrix_a = OpConstant %int 1
  6781. %stride = OpConstant %int 42
  6782. %matrix = OpTypeCooperativeMatrixKHR %float %subgroup %rows %cols %matrix_a
  6783. %var = OpUntypedVariableKHR %untyped StorageBuffer %block
  6784. %main = OpFunction %void None %void_fn
  6785. %entry = OpLabel
  6786. %gep = OpUntypedAccessChainKHR %untyped %block %var %int_0 %int_0
  6787. %ld = OpCooperativeMatrixLoadKHR %matrix %gep %int_0 %stride
  6788. OpReturn
  6789. OpFunctionEnd
  6790. )";
  6791. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  6792. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  6793. }
  6794. TEST_F(ValidateMemory, UntypedCooperativeMatrixStore) {
  6795. const std::string spirv = R"(
  6796. OpCapability Shader
  6797. OpCapability UntypedPointersKHR
  6798. OpCapability CooperativeMatrixKHR
  6799. OpCapability VulkanMemoryModel
  6800. OpExtension "SPV_KHR_untyped_pointers"
  6801. OpExtension "SPV_KHR_cooperative_matrix"
  6802. OpMemoryModel Logical Vulkan
  6803. OpEntryPoint GLCompute %main "main" %var1 %var2
  6804. OpExecutionMode %main LocalSize 1 1 1
  6805. OpDecorate %var1 DescriptorSet 0
  6806. OpDecorate %var1 Binding 0
  6807. OpDecorate %var2 DescriptorSet 0
  6808. OpDecorate %var2 Binding 1
  6809. OpDecorate %block Block
  6810. OpMemberDecorate %block 0 Offset 0
  6811. OpDecorate %array ArrayStride 4
  6812. %void = OpTypeVoid
  6813. %void_fn = OpTypeFunction %void
  6814. %untyped = OpTypeUntypedPointerKHR StorageBuffer
  6815. %float = OpTypeFloat 32
  6816. %array = OpTypeRuntimeArray %float
  6817. %block = OpTypeStruct %array
  6818. %ptr = OpTypePointer StorageBuffer %block
  6819. %ptr_float = OpTypePointer StorageBuffer %float
  6820. %int = OpTypeInt 32 0
  6821. %int_0 = OpConstant %int 0
  6822. %subgroup = OpConstant %int 3
  6823. %rows = OpSpecConstant %int 1
  6824. %cols = OpSpecConstant %int 1
  6825. %matrix_a = OpConstant %int 1
  6826. %stride = OpConstant %int 42
  6827. %matrix = OpTypeCooperativeMatrixKHR %float %subgroup %rows %cols %matrix_a
  6828. %var1 = OpVariable %ptr StorageBuffer
  6829. %var2 = OpUntypedVariableKHR %untyped StorageBuffer %block
  6830. %main = OpFunction %void None %void_fn
  6831. %entry = OpLabel
  6832. %gep = OpAccessChain %ptr_float %var1 %int_0 %int_0
  6833. %ld = OpCooperativeMatrixLoadKHR %matrix %gep %int_0 %stride
  6834. OpCooperativeMatrixStoreKHR %var2 %ld %int_0 %stride
  6835. OpReturn
  6836. OpFunctionEnd
  6837. )";
  6838. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  6839. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  6840. }
  6841. TEST_F(ValidateMemory, UntypedCooperativeMatrixStore2) {
  6842. const std::string spirv = R"(
  6843. OpCapability Shader
  6844. OpCapability UntypedPointersKHR
  6845. OpCapability CooperativeMatrixKHR
  6846. OpCapability VulkanMemoryModel
  6847. OpExtension "SPV_KHR_untyped_pointers"
  6848. OpExtension "SPV_KHR_cooperative_matrix"
  6849. OpMemoryModel Logical Vulkan
  6850. OpEntryPoint GLCompute %main "main" %var1 %var2
  6851. OpExecutionMode %main LocalSize 1 1 1
  6852. OpDecorate %var1 DescriptorSet 0
  6853. OpDecorate %var1 Binding 0
  6854. OpDecorate %var2 DescriptorSet 0
  6855. OpDecorate %var2 Binding 1
  6856. OpDecorate %block Block
  6857. OpMemberDecorate %block 0 Offset 0
  6858. OpDecorate %array ArrayStride 4
  6859. %void = OpTypeVoid
  6860. %void_fn = OpTypeFunction %void
  6861. %untyped = OpTypeUntypedPointerKHR StorageBuffer
  6862. %float = OpTypeFloat 32
  6863. %array = OpTypeRuntimeArray %float
  6864. %block = OpTypeStruct %array
  6865. %ptr = OpTypePointer StorageBuffer %block
  6866. %ptr_float = OpTypePointer StorageBuffer %float
  6867. %int = OpTypeInt 32 0
  6868. %int_0 = OpConstant %int 0
  6869. %subgroup = OpConstant %int 3
  6870. %rows = OpSpecConstant %int 1
  6871. %cols = OpSpecConstant %int 1
  6872. %matrix_a = OpConstant %int 1
  6873. %stride = OpConstant %int 42
  6874. %matrix = OpTypeCooperativeMatrixKHR %float %subgroup %rows %cols %matrix_a
  6875. %var1 = OpVariable %ptr StorageBuffer
  6876. %var2 = OpUntypedVariableKHR %untyped StorageBuffer %block
  6877. %main = OpFunction %void None %void_fn
  6878. %entry = OpLabel
  6879. %gep = OpAccessChain %ptr_float %var1 %int_0 %int_0
  6880. %ld = OpCooperativeMatrixLoadKHR %matrix %gep %int_0 %stride
  6881. %gep2 = OpUntypedAccessChainKHR %untyped %block %var2 %int_0 %int_0
  6882. OpCooperativeMatrixStoreKHR %gep2 %ld %int_0 %stride
  6883. OpReturn
  6884. OpFunctionEnd
  6885. )";
  6886. CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
  6887. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  6888. }
  6889. std::string GenCoopMat2Shader(const std::string& extra_types,
  6890. const std::string& main_body,
  6891. const std::string& after_main = "",
  6892. const std::string& extra_decorations = "") {
  6893. const std::string prefix = R"(
  6894. OpCapability Shader
  6895. OpCapability Float16
  6896. OpCapability PhysicalStorageBufferAddresses
  6897. OpCapability VulkanMemoryModel
  6898. OpCapability CooperativeMatrixKHR
  6899. OpCapability TensorAddressingNV
  6900. OpCapability CooperativeMatrixTensorAddressingNV
  6901. OpCapability CooperativeMatrixBlockLoadsNV
  6902. OpExtension "SPV_KHR_physical_storage_buffer"
  6903. OpExtension "SPV_KHR_storage_buffer_storage_class"
  6904. OpExtension "SPV_NV_tensor_addressing"
  6905. OpExtension "SPV_NV_cooperative_matrix2"
  6906. OpExtension "SPV_KHR_cooperative_matrix"
  6907. OpExtension "SPV_KHR_vulkan_memory_model"
  6908. OpMemoryModel Logical VulkanKHR
  6909. OpEntryPoint GLCompute %main "main"
  6910. OpExecutionMode %main LocalSize 1 1 1
  6911. OpDecorate %f16_arr ArrayStride 2
  6912. OpDecorate %46 Block
  6913. OpMemberDecorate %46 0 Offset 0
  6914. OpDecorate %48 Binding 0
  6915. OpDecorate %48 DescriptorSet 0
  6916. OpDecorate %psb Restrict
  6917. )" + extra_decorations + R"(
  6918. %void = OpTypeVoid
  6919. %bool = OpTypeBool
  6920. %func = OpTypeFunction %void
  6921. %f16 = OpTypeFloat 16
  6922. %f32 = OpTypeFloat 32
  6923. %u32 = OpTypeInt 32 0
  6924. %s32 = OpTypeInt 32 1
  6925. %s32_0 = OpConstant %s32 0
  6926. %f16_0 = OpConstant %f16 0
  6927. %u32_2 = OpConstant %u32 2
  6928. %u32_8 = OpConstant %u32 8
  6929. %use_A = OpConstant %u32 0
  6930. %workgroup = OpConstant %u32 2
  6931. %subgroup = OpConstant %u32 3
  6932. %f16_arr = OpTypeRuntimeArray %f16
  6933. %46 = OpTypeStruct %f16_arr
  6934. %47 = OpTypePointer StorageBuffer %46
  6935. %48 = OpVariable %47 StorageBuffer
  6936. %51 = OpTypePointer StorageBuffer %f16_arr
  6937. %psbptr = OpTypePointer PhysicalStorageBuffer %f16_arr
  6938. %f16mat = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_8 %u32_8 %use_A
  6939. %f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A
  6940. %arr2 = OpTypeArray %u32 %u32_2
  6941. %functy = OpTypeFunction %f16 %psbptr %arr2 %arr2
  6942. )";
  6943. const std::string decode_func =
  6944. R"(
  6945. %decodefunc = OpFunction %f16 None %functy
  6946. %psb = OpFunctionParameter %psbptr
  6947. %c0 = OpFunctionParameter %arr2
  6948. %c1 = OpFunctionParameter %arr2
  6949. %entry2 = OpLabel
  6950. OpReturnValue %f16_0
  6951. OpFunctionEnd
  6952. )";
  6953. const std::string func_begin =
  6954. R"(
  6955. %main = OpFunction %void None %func
  6956. %main_entry = OpLabel
  6957. %array_ptr = OpAccessChain %51 %48 %s32_0
  6958. )";
  6959. const std::string suffix =
  6960. R"(
  6961. OpReturn
  6962. OpFunctionEnd)";
  6963. return prefix + extra_types + func_begin + main_body + suffix + decode_func +
  6964. after_main;
  6965. }
  6966. TEST_F(ValidateMemory, CoopMat2TensorLayoutAndViewSuccess) {
  6967. std::string spirv = GenCoopMat2Shader(
  6968. R"(
  6969. %clamp = OpConstant %u32 0
  6970. %dim = OpConstant %u32 2
  6971. %p0 = OpConstant %u32 0
  6972. %p1 = OpConstant %u32 1
  6973. %hasdim = OpConstantFalse %bool
  6974. %layout = OpTypeTensorLayoutNV %dim %clamp
  6975. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  6976. )",
  6977. R"(
  6978. )");
  6979. CompileSuccessfully(spirv.c_str());
  6980. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  6981. }
  6982. TEST_F(ValidateMemory, CoopMat2TensorLayoutInvalidDimFail) {
  6983. std::string spirv = GenCoopMat2Shader(
  6984. R"(
  6985. %clamp = OpConstant %u32 0
  6986. %dim = OpConstant %u32 6
  6987. %layout = OpTypeTensorLayoutNV %dim %clamp
  6988. )",
  6989. R"(
  6990. )");
  6991. CompileSuccessfully(spirv.c_str());
  6992. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6993. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be between 1 and 5"));
  6994. }
  6995. TEST_F(ValidateMemory, CoopMat2TensorLayoutInvalidClampFail) {
  6996. std::string spirv = GenCoopMat2Shader(
  6997. R"(
  6998. %clamp = OpConstant %u32 6
  6999. %dim = OpConstant %u32 2
  7000. %layout = OpTypeTensorLayoutNV %dim %clamp
  7001. )",
  7002. R"(
  7003. )");
  7004. CompileSuccessfully(spirv.c_str());
  7005. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7006. EXPECT_THAT(getDiagnosticString(),
  7007. HasSubstr("must be a valid TensorClampMode"));
  7008. }
  7009. TEST_F(ValidateMemory, CoopMat2TensorViewInvalidDimFail) {
  7010. std::string spirv = GenCoopMat2Shader(
  7011. R"(
  7012. %dim = OpConstant %u32 6
  7013. %p0 = OpConstant %u32 0
  7014. %p1 = OpConstant %u32 1
  7015. %hasdim = OpConstantFalse %bool
  7016. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7017. )",
  7018. R"(
  7019. )");
  7020. CompileSuccessfully(spirv.c_str());
  7021. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7022. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be between 1 and 5"));
  7023. }
  7024. TEST_F(ValidateMemory, CoopMat2TensorViewInvalidPermutationFail) {
  7025. std::string spirv = GenCoopMat2Shader(
  7026. R"(
  7027. %dim = OpConstant %u32 3
  7028. %p0 = OpConstant %u32 0
  7029. %p1 = OpConstant %u32 1
  7030. %hasdim = OpConstantFalse %bool
  7031. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p1
  7032. )",
  7033. R"(
  7034. )");
  7035. CompileSuccessfully(spirv.c_str());
  7036. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7037. EXPECT_THAT(getDiagnosticString(),
  7038. HasSubstr("Permutation values don't form a valid permutation"));
  7039. }
  7040. TEST_F(ValidateMemory, CoopMat2TensorViewInvalidPermutation2Fail) {
  7041. std::string spirv = GenCoopMat2Shader(
  7042. R"(
  7043. %dim = OpConstant %u32 3
  7044. %p0 = OpConstant %u32 0
  7045. %p1 = OpConstant %u32 1
  7046. %hasdim = OpConstantFalse %bool
  7047. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7048. )",
  7049. R"(
  7050. )");
  7051. CompileSuccessfully(spirv.c_str());
  7052. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7053. EXPECT_THAT(getDiagnosticString(),
  7054. HasSubstr("Incorrect number of permutation values."));
  7055. }
  7056. TEST_F(ValidateMemory, CoopMat2TensorLayoutBlockSizePass) {
  7057. std::string spirv = GenCoopMat2Shader(
  7058. R"(
  7059. %clamp = OpConstant %u32 0
  7060. %dim = OpConstant %u32 3
  7061. %b = OpConstant %u32 1
  7062. %layout = OpTypeTensorLayoutNV %dim %clamp
  7063. )",
  7064. R"(
  7065. %tl = OpCreateTensorLayoutNV %layout
  7066. %tl2 = OpTensorLayoutSetBlockSizeNV %layout %tl %b %b %b
  7067. )");
  7068. CompileSuccessfully(spirv.c_str());
  7069. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7070. }
  7071. TEST_F(ValidateMemory, CoopMat2TensorLayoutBlockSizeFail) {
  7072. std::string spirv = GenCoopMat2Shader(
  7073. R"(
  7074. %clamp = OpConstant %u32 0
  7075. %dim = OpConstant %u32 3
  7076. %b = OpConstant %u32 1
  7077. %layout = OpTypeTensorLayoutNV %dim %clamp
  7078. )",
  7079. R"(
  7080. %tl = OpCreateTensorLayoutNV %layout
  7081. %tl2 = OpTensorLayoutSetBlockSizeNV %layout %tl %b %b %b %b
  7082. )");
  7083. CompileSuccessfully(spirv.c_str());
  7084. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7085. EXPECT_THAT(getDiagnosticString(),
  7086. HasSubstr("unexpected number of operands"));
  7087. }
  7088. TEST_F(ValidateMemory, CoopMat2TensorLayoutDimensionPass) {
  7089. std::string spirv = GenCoopMat2Shader(
  7090. R"(
  7091. %clamp = OpConstant %u32 0
  7092. %dim = OpConstant %u32 3
  7093. %b = OpConstant %u32 1
  7094. %layout = OpTypeTensorLayoutNV %dim %clamp
  7095. )",
  7096. R"(
  7097. %tl = OpCreateTensorLayoutNV %layout
  7098. %tl2 = OpTensorLayoutSetDimensionNV %layout %tl %b %b %b
  7099. )");
  7100. CompileSuccessfully(spirv.c_str());
  7101. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7102. }
  7103. TEST_F(ValidateMemory, CoopMat2TensorLayoutDimensionFail) {
  7104. std::string spirv = GenCoopMat2Shader(
  7105. R"(
  7106. %clamp = OpConstant %u32 0
  7107. %dim = OpConstant %u32 3
  7108. %b = OpConstant %u32 1
  7109. %layout = OpTypeTensorLayoutNV %dim %clamp
  7110. )",
  7111. R"(
  7112. %tl = OpCreateTensorLayoutNV %layout
  7113. %tl2 = OpTensorLayoutSetDimensionNV %layout %tl %b %b %b %b
  7114. )");
  7115. CompileSuccessfully(spirv.c_str());
  7116. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7117. EXPECT_THAT(getDiagnosticString(),
  7118. HasSubstr("unexpected number of operands"));
  7119. }
  7120. TEST_F(ValidateMemory, CoopMat2TensorLayoutStridePass) {
  7121. std::string spirv = GenCoopMat2Shader(
  7122. R"(
  7123. %clamp = OpConstant %u32 0
  7124. %dim = OpConstant %u32 3
  7125. %b = OpConstant %u32 1
  7126. %layout = OpTypeTensorLayoutNV %dim %clamp
  7127. )",
  7128. R"(
  7129. %tl = OpCreateTensorLayoutNV %layout
  7130. %tl2 = OpTensorLayoutSetStrideNV %layout %tl %b %b %b
  7131. )");
  7132. CompileSuccessfully(spirv.c_str());
  7133. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7134. }
  7135. TEST_F(ValidateMemory, CoopMat2TensorLayoutStrideFail) {
  7136. std::string spirv = GenCoopMat2Shader(
  7137. R"(
  7138. %clamp = OpConstant %u32 0
  7139. %dim = OpConstant %u32 3
  7140. %b = OpConstant %u32 1
  7141. %layout = OpTypeTensorLayoutNV %dim %clamp
  7142. )",
  7143. R"(
  7144. %tl = OpCreateTensorLayoutNV %layout
  7145. %tl2 = OpTensorLayoutSetStrideNV %layout %tl %b %b %b %b
  7146. )");
  7147. CompileSuccessfully(spirv.c_str());
  7148. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7149. EXPECT_THAT(getDiagnosticString(),
  7150. HasSubstr("unexpected number of operands"));
  7151. }
  7152. TEST_F(ValidateMemory, CoopMat2TensorLayoutSlicePass) {
  7153. std::string spirv = GenCoopMat2Shader(
  7154. R"(
  7155. %clamp = OpConstant %u32 0
  7156. %dim = OpConstant %u32 3
  7157. %b = OpConstant %u32 1
  7158. %layout = OpTypeTensorLayoutNV %dim %clamp
  7159. )",
  7160. R"(
  7161. %tl = OpCreateTensorLayoutNV %layout
  7162. %tl2 = OpTensorLayoutSliceNV %layout %tl %b %b %b %b %b %b
  7163. )");
  7164. CompileSuccessfully(spirv.c_str());
  7165. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7166. }
  7167. TEST_F(ValidateMemory, CoopMat2TensorLayoutSliceFail) {
  7168. std::string spirv = GenCoopMat2Shader(
  7169. R"(
  7170. %clamp = OpConstant %u32 0
  7171. %dim = OpConstant %u32 3
  7172. %b = OpConstant %u32 1
  7173. %layout = OpTypeTensorLayoutNV %dim %clamp
  7174. )",
  7175. R"(
  7176. %tl = OpCreateTensorLayoutNV %layout
  7177. %tl2 = OpTensorLayoutSliceNV %layout %tl %b %b %b
  7178. )");
  7179. CompileSuccessfully(spirv.c_str());
  7180. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7181. EXPECT_THAT(getDiagnosticString(),
  7182. HasSubstr("unexpected number of operands"));
  7183. }
  7184. TEST_F(ValidateMemory, CoopMat2TensorLayoutSetClampValuePass) {
  7185. std::string spirv = GenCoopMat2Shader(
  7186. R"(
  7187. %clamp = OpConstant %u32 0
  7188. %dim = OpConstant %u32 3
  7189. %b = OpConstant %u32 1
  7190. %layout = OpTypeTensorLayoutNV %dim %clamp
  7191. )",
  7192. R"(
  7193. %tl = OpCreateTensorLayoutNV %layout
  7194. %tl2 = OpTensorLayoutSetClampValueNV %layout %tl %b
  7195. )");
  7196. CompileSuccessfully(spirv.c_str());
  7197. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7198. }
  7199. TEST_F(ValidateMemory, CoopMat2TensorViewDimensionPass) {
  7200. std::string spirv = GenCoopMat2Shader(
  7201. R"(
  7202. %dim = OpConstant %u32 3
  7203. %hasdim = OpConstantFalse %bool
  7204. %p0 = OpConstant %u32 0
  7205. %p1 = OpConstant %u32 1
  7206. %p2 = OpConstant %u32 2
  7207. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2
  7208. %b = OpConstant %u32 1
  7209. )",
  7210. R"(
  7211. %tv = OpCreateTensorViewNV %view
  7212. %tv2 = OpTensorViewSetDimensionNV %view %tv %b %b %b
  7213. )");
  7214. CompileSuccessfully(spirv.c_str());
  7215. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7216. }
  7217. TEST_F(ValidateMemory, CoopMat2TensorViewDimensionFail) {
  7218. std::string spirv = GenCoopMat2Shader(
  7219. R"(
  7220. %dim = OpConstant %u32 3
  7221. %hasdim = OpConstantFalse %bool
  7222. %p0 = OpConstant %u32 0
  7223. %p1 = OpConstant %u32 1
  7224. %p2 = OpConstant %u32 2
  7225. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2
  7226. %b = OpConstant %u32 1
  7227. )",
  7228. R"(
  7229. %tv = OpCreateTensorViewNV %view
  7230. %tv2 = OpTensorViewSetDimensionNV %view %tv %b %b %b %b
  7231. )");
  7232. CompileSuccessfully(spirv.c_str());
  7233. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7234. EXPECT_THAT(getDiagnosticString(),
  7235. HasSubstr("unexpected number of operands"));
  7236. }
  7237. TEST_F(ValidateMemory, CoopMat2TensorViewStridePass) {
  7238. std::string spirv = GenCoopMat2Shader(
  7239. R"(
  7240. %dim = OpConstant %u32 3
  7241. %hasdim = OpConstantFalse %bool
  7242. %p0 = OpConstant %u32 0
  7243. %p1 = OpConstant %u32 1
  7244. %p2 = OpConstant %u32 2
  7245. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2
  7246. %b = OpConstant %u32 1
  7247. )",
  7248. R"(
  7249. %tv = OpCreateTensorViewNV %view
  7250. %tv2 = OpTensorViewSetStrideNV %view %tv %b %b %b
  7251. )");
  7252. CompileSuccessfully(spirv.c_str());
  7253. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7254. }
  7255. TEST_F(ValidateMemory, CoopMat2TensorViewStrideFail) {
  7256. std::string spirv = GenCoopMat2Shader(
  7257. R"(
  7258. %dim = OpConstant %u32 3
  7259. %hasdim = OpConstantFalse %bool
  7260. %p0 = OpConstant %u32 0
  7261. %p1 = OpConstant %u32 1
  7262. %p2 = OpConstant %u32 2
  7263. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2
  7264. %b = OpConstant %u32 1
  7265. )",
  7266. R"(
  7267. %tv = OpCreateTensorViewNV %view
  7268. %tv2 = OpTensorViewSetStrideNV %view %tv %b %b %b %b
  7269. )");
  7270. CompileSuccessfully(spirv.c_str());
  7271. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7272. EXPECT_THAT(getDiagnosticString(),
  7273. HasSubstr("unexpected number of operands"));
  7274. }
  7275. TEST_F(ValidateMemory, CoopMat2TensorViewClipPass) {
  7276. std::string spirv = GenCoopMat2Shader(
  7277. R"(
  7278. %dim = OpConstant %u32 3
  7279. %hasdim = OpConstantFalse %bool
  7280. %p0 = OpConstant %u32 0
  7281. %p1 = OpConstant %u32 1
  7282. %p2 = OpConstant %u32 2
  7283. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2
  7284. %b = OpConstant %u32 1
  7285. )",
  7286. R"(
  7287. %tv = OpCreateTensorViewNV %view
  7288. %tv2 = OpTensorViewSetClipNV %view %tv %b %b %b %b
  7289. )");
  7290. CompileSuccessfully(spirv.c_str());
  7291. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7292. }
  7293. TEST_F(ValidateMemory, CoopMat2LoadStoreTensorPass) {
  7294. std::string spirv = GenCoopMat2Shader(
  7295. R"(
  7296. %clamp = OpConstant %u32 0
  7297. %dim = OpConstant %u32 2
  7298. %p0 = OpConstant %u32 0
  7299. %p1 = OpConstant %u32 1
  7300. %hasdim = OpConstantFalse %bool
  7301. %layout = OpTypeTensorLayoutNV %dim %clamp
  7302. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7303. )",
  7304. R"(
  7305. %mat = OpUndef %f16mat
  7306. %tl = OpCreateTensorLayoutNV %layout
  7307. %tv = OpCreateTensorViewNV %view
  7308. %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None None
  7309. %mat3 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl Aligned 4 None
  7310. %mat4 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None TensorView %tv
  7311. %mat5 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None DecodeFunc %decodefunc
  7312. %mat6 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None TensorView|DecodeFunc %tv %decodefunc
  7313. %mat7 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl Aligned 4 TensorView|DecodeFunc %tv %decodefunc
  7314. OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl None None
  7315. OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl Aligned 4 None
  7316. OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl None TensorView %tv
  7317. OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl Aligned 4 TensorView %tv
  7318. )");
  7319. CompileSuccessfully(spirv.c_str());
  7320. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  7321. }
  7322. TEST_F(ValidateMemory, CoopMat2LoadTensorWrongLayoutTypeFail) {
  7323. std::string spirv = GenCoopMat2Shader(
  7324. R"(
  7325. %clamp = OpConstant %u32 0
  7326. %dim = OpConstant %u32 2
  7327. %p0 = OpConstant %u32 0
  7328. %p1 = OpConstant %u32 1
  7329. %hasdim = OpConstantFalse %bool
  7330. %layout = OpTypeTensorLayoutNV %dim %clamp
  7331. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7332. )",
  7333. R"(
  7334. %mat = OpUndef %f16mat
  7335. %tl = OpCreateTensorLayoutNV %layout
  7336. %tv = OpCreateTensorViewNV %view
  7337. %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tv None None
  7338. )");
  7339. CompileSuccessfully(spirv.c_str());
  7340. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7341. EXPECT_THAT(getDiagnosticString(),
  7342. HasSubstr("does not have a tensor layout type"));
  7343. }
  7344. TEST_F(ValidateMemory, CoopMat2LoadTensorWrongObjectTypeFail) {
  7345. std::string spirv = GenCoopMat2Shader(
  7346. R"(
  7347. %clamp = OpConstant %u32 0
  7348. %dim = OpConstant %u32 2
  7349. %p0 = OpConstant %u32 0
  7350. %p1 = OpConstant %u32 1
  7351. %hasdim = OpConstantFalse %bool
  7352. %layout = OpTypeTensorLayoutNV %dim %clamp
  7353. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7354. )",
  7355. R"(
  7356. %mat = OpUndef %f32mat
  7357. %tl = OpCreateTensorLayoutNV %layout
  7358. %tv = OpCreateTensorViewNV %view
  7359. %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None None
  7360. )");
  7361. CompileSuccessfully(spirv.c_str());
  7362. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7363. EXPECT_THAT(getDiagnosticString(),
  7364. HasSubstr("type does not match Result Type"));
  7365. }
  7366. TEST_F(ValidateMemory, CoopMat2LoadTensorDecodeFuncTypeFail) {
  7367. std::string spirv = GenCoopMat2Shader(
  7368. R"(
  7369. %clamp = OpConstant %u32 0
  7370. %dim = OpConstant %u32 2
  7371. %p0 = OpConstant %u32 0
  7372. %p1 = OpConstant %u32 1
  7373. %hasdim = OpConstantFalse %bool
  7374. %layout = OpTypeTensorLayoutNV %dim %clamp
  7375. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7376. )",
  7377. R"(
  7378. %mat = OpUndef %f32mat
  7379. %tl = OpCreateTensorLayoutNV %layout
  7380. %tv = OpCreateTensorViewNV %view
  7381. %mat2 = OpCooperativeMatrixLoadTensorNV %f32mat %array_ptr %mat %tl None DecodeFunc %decodefunc
  7382. )");
  7383. CompileSuccessfully(spirv.c_str());
  7384. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7385. EXPECT_THAT(getDiagnosticString(),
  7386. HasSubstr("return type must match matrix component type"));
  7387. }
  7388. TEST_F(ValidateMemory, CoopMat2LoadTensorDecodeFuncArrayTypeFail) {
  7389. std::string spirv = GenCoopMat2Shader(
  7390. R"(
  7391. %clamp = OpConstant %u32 0
  7392. %dim = OpConstant %u32 2
  7393. %u32_3 = OpConstant %u32 3
  7394. %p0 = OpConstant %u32 0
  7395. %p1 = OpConstant %u32 1
  7396. %hasdim = OpConstantFalse %bool
  7397. %layout = OpTypeTensorLayoutNV %dim %clamp
  7398. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7399. %arr3 = OpTypeArray %u32 %u32_3
  7400. %functy2 = OpTypeFunction %f16 %psbptr %arr3 %arr3
  7401. )",
  7402. R"(
  7403. %mat = OpUndef %f16mat
  7404. %tl = OpCreateTensorLayoutNV %layout
  7405. %tv = OpCreateTensorViewNV %view
  7406. %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None DecodeFunc %decodefunc2
  7407. )",
  7408. R"(
  7409. %decodefunc2 = OpFunction %f16 None %functy2
  7410. %psb2 = OpFunctionParameter %psbptr
  7411. %c02 = OpFunctionParameter %arr3
  7412. %c12 = OpFunctionParameter %arr3
  7413. %entry3 = OpLabel
  7414. OpReturnValue %f16_0
  7415. OpFunctionEnd
  7416. )",
  7417. R"(
  7418. OpDecorate %psb2 Restrict
  7419. )");
  7420. CompileSuccessfully(spirv.c_str());
  7421. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7422. EXPECT_THAT(getDiagnosticString(),
  7423. HasSubstr("dimension equal to the tensor dimension"));
  7424. }
  7425. TEST_F(ValidateMemory, CoopMat2LoadTensorDecodeFuncPointerTypeFail) {
  7426. std::string spirv = GenCoopMat2Shader(
  7427. R"(
  7428. %clamp = OpConstant %u32 0
  7429. %dim = OpConstant %u32 2
  7430. %p0 = OpConstant %u32 0
  7431. %p1 = OpConstant %u32 1
  7432. %hasdim = OpConstantFalse %bool
  7433. %layout = OpTypeTensorLayoutNV %dim %clamp
  7434. %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1
  7435. %sbptr = OpTypePointer StorageBuffer %f16_arr
  7436. %functy2 = OpTypeFunction %f16 %sbptr %arr2 %arr2
  7437. )",
  7438. R"(
  7439. %mat = OpUndef %f16mat
  7440. %tl = OpCreateTensorLayoutNV %layout
  7441. %tv = OpCreateTensorViewNV %view
  7442. %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None DecodeFunc %decodefunc2
  7443. )",
  7444. R"(
  7445. %decodefunc2 = OpFunction %f16 None %functy2
  7446. %sb = OpFunctionParameter %sbptr
  7447. %c02 = OpFunctionParameter %arr2
  7448. %c12 = OpFunctionParameter %arr2
  7449. %entry3 = OpLabel
  7450. OpReturnValue %f16_0
  7451. OpFunctionEnd
  7452. )");
  7453. CompileSuccessfully(spirv.c_str());
  7454. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7455. EXPECT_THAT(
  7456. getDiagnosticString(),
  7457. HasSubstr("first parameter must be pointer to PhysicalStorageBuffer"));
  7458. }
  7459. TEST_F(ValidateMemory, PtrAccessChainNodePayloadArray) {
  7460. const std::string spirv = R"(
  7461. OpCapability Shader
  7462. OpCapability ShaderEnqueueAMDX
  7463. OpExtension "SPV_AMDX_shader_enqueue"
  7464. OpMemoryModel Logical GLSL450
  7465. OpEntryPoint GLCompute %main "main" %input
  7466. %uint = OpTypeInt 32 0
  7467. %uint_0 = OpConstant %uint 0
  7468. %uint_1 = OpConstant %uint 1
  7469. %node0 = OpConstantStringAMDX "node0"
  7470. %node1 = OpConstantStringAMDX "node1"
  7471. %node2 = OpConstantStringAMDX "node2"
  7472. %S = OpTypeStruct %uint
  7473. %_payloadarr_S = OpTypeNodePayloadArrayAMDX %S
  7474. %_ptr_NodePayloadAMDX__payloadarr_S = OpTypePointer NodePayloadAMDX %_payloadarr_S
  7475. %_ptr_NodePayloadAMDX_uint = OpTypePointer NodePayloadAMDX %uint
  7476. %void = OpTypeVoid
  7477. %void_fn = OpTypeFunction %void
  7478. %input = OpVariable %_ptr_NodePayloadAMDX__payloadarr_S NodePayloadAMDX
  7479. %main = OpFunction %void None %void_fn
  7480. %entry = OpLabel
  7481. %x = OpAccessChain %_ptr_NodePayloadAMDX_uint %input %uint_0 %uint_0
  7482. OpReturn
  7483. OpFunctionEnd
  7484. )";
  7485. spv_target_env env = SPV_ENV_UNIVERSAL_1_4;
  7486. CompileSuccessfully(spirv, env);
  7487. EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env));
  7488. }
  7489. std::string GenCoopVecLoadStoreShader(const std::string& storeMemoryAccess,
  7490. const std::string& loadMemoryAccess) {
  7491. std::string s = R"(
  7492. OpCapability Shader
  7493. OpCapability Float16
  7494. OpCapability StorageBuffer16BitAccess
  7495. OpCapability VulkanMemoryModel
  7496. OpCapability CooperativeVectorNV
  7497. OpCapability ReplicatedCompositesEXT
  7498. OpExtension "SPV_EXT_replicated_composites"
  7499. OpExtension "SPV_KHR_vulkan_memory_model"
  7500. OpExtension "SPV_NV_cooperative_vector"
  7501. %1 = OpExtInstImport "GLSL.std.450"
  7502. OpMemoryModel Logical Vulkan
  7503. OpEntryPoint GLCompute %4 "main" %48 %73
  7504. OpExecutionMode %4 LocalSize 1 1 1
  7505. OpDecorate %45 ArrayStride 2
  7506. OpDecorate %46 Block
  7507. OpMemberDecorate %46 0 Offset 0
  7508. OpDecorate %48 Binding 0
  7509. OpDecorate %48 DescriptorSet 0
  7510. %2 = OpTypeVoid
  7511. %3 = OpTypeFunction %2
  7512. %6 = OpTypeInt 32 0
  7513. %49 = OpTypeInt 32 1
  7514. %41 = OpTypeFloat 16
  7515. %14 = OpConstant %6 1
  7516. %50 = OpConstant %49 0
  7517. %82 = OpConstant %6 5
  7518. %42 = OpTypeCooperativeVectorNV %41 %14
  7519. %43 = OpTypePointer Function %42
  7520. %45 = OpTypeRuntimeArray %41
  7521. %46 = OpTypeStruct %45
  7522. %47 = OpTypePointer StorageBuffer %46
  7523. %48 = OpVariable %47 StorageBuffer
  7524. %51 = OpTypePointer StorageBuffer %45
  7525. %57 = OpTypePointer Private %42
  7526. %73 = OpVariable %57 Private
  7527. %4 = OpFunction %2 None %3
  7528. %5 = OpLabel
  7529. %52 = OpAccessChain %51 %48 %50
  7530. %56 = OpCooperativeVectorLoadNV %42 %52 %50 )" +
  7531. loadMemoryAccess + R"( %82
  7532. %77 = OpLoad %42 %73
  7533. OpCooperativeVectorStoreNV %52 %50 %77 )" + storeMemoryAccess + R"( %82
  7534. OpReturn
  7535. OpFunctionEnd
  7536. )";
  7537. return s;
  7538. }
  7539. TEST_F(ValidateMemory, CoopVecLoadStoreSuccess) {
  7540. std::string spirv =
  7541. GenCoopVecLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
  7542. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  7543. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7544. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7545. }
  7546. TEST_F(ValidateMemory, CoopVecStoreMemoryAccessFail) {
  7547. std::string spirv =
  7548. GenCoopVecLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR",
  7549. "MakePointerVisibleKHR|NonPrivatePointerKHR");
  7550. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7551. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7552. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7553. EXPECT_THAT(getDiagnosticString(),
  7554. HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
  7555. }
  7556. TEST_F(ValidateMemory, CoopVecLoadMemoryAccessFail) {
  7557. std::string spirv =
  7558. GenCoopVecLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
  7559. "MakePointerAvailableKHR|NonPrivatePointerKHR");
  7560. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7561. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7562. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7563. EXPECT_THAT(getDiagnosticString(),
  7564. HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
  7565. }
  7566. TEST_F(ValidateMemory, CoopVecInvalidStorageClassFail) {
  7567. const std::string body = R"(
  7568. OpCapability Shader
  7569. OpCapability Float16
  7570. OpCapability CooperativeVectorNV
  7571. OpCapability ReplicatedCompositesEXT
  7572. OpExtension "SPV_NV_cooperative_vector"
  7573. OpExtension "SPV_EXT_replicated_composites"
  7574. OpExtension "SPV_KHR_vulkan_memory_model"
  7575. OpMemoryModel Logical GLSL450
  7576. OpEntryPoint GLCompute %main "main"
  7577. %void = OpTypeVoid
  7578. %func = OpTypeFunction %void
  7579. %f16 = OpTypeFloat 16
  7580. %u32 = OpTypeInt 32 0
  7581. %u32_8 = OpConstant %u32 8
  7582. %use_A = OpConstant %u32 0
  7583. %subgroup = OpConstant %u32 3
  7584. %f16vec = OpTypeCooperativeVectorNV %f16 %u32_8
  7585. %str = OpTypeStruct %f16vec
  7586. %str_ptr = OpTypePointer Workgroup %str
  7587. %sh = OpVariable %str_ptr Workgroup
  7588. %main = OpFunction %void None %func
  7589. %main_entry = OpLabel
  7590. OpReturn
  7591. OpFunctionEnd)";
  7592. CompileSuccessfully(body.c_str());
  7593. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  7594. EXPECT_THAT(
  7595. getDiagnosticString(),
  7596. HasSubstr(
  7597. "Cooperative vector types (or types containing them) can only be "
  7598. "allocated in Function or Private storage classes or as function "
  7599. "parameters"));
  7600. }
  7601. std::string GenCoopVecShader(const std::string& extra_types,
  7602. const std::string& main_body) {
  7603. const std::string prefix =
  7604. R"(
  7605. OpCapability Shader
  7606. OpCapability Float16
  7607. OpCapability Int64
  7608. OpCapability StorageBuffer16BitAccess
  7609. OpCapability VulkanMemoryModel
  7610. OpCapability CooperativeVectorNV
  7611. OpCapability CooperativeVectorTrainingNV
  7612. OpCapability ReplicatedCompositesEXT
  7613. OpExtension "SPV_EXT_replicated_composites"
  7614. OpExtension "SPV_KHR_vulkan_memory_model"
  7615. OpExtension "SPV_NV_cooperative_vector"
  7616. %1 = OpExtInstImport "GLSL.std.450"
  7617. OpMemoryModel Logical Vulkan
  7618. OpEntryPoint GLCompute %main "main" %48 %73
  7619. OpExecutionMode %main LocalSize 1 1 1
  7620. OpDecorate %f16_arr ArrayStride 2
  7621. OpDecorate %46 Block
  7622. OpMemberDecorate %46 0 Offset 0
  7623. OpDecorate %48 Binding 0
  7624. OpDecorate %48 DescriptorSet 0
  7625. %void = OpTypeVoid
  7626. %func = OpTypeFunction %void
  7627. %u32 = OpTypeInt 32 0
  7628. %s32 = OpTypeInt 32 1
  7629. %f16 = OpTypeFloat 16
  7630. %bool = OpTypeBool
  7631. %false = OpConstantFalse %bool
  7632. %u32_4 = OpConstant %u32 4
  7633. %u32_8 = OpConstant %u32 8
  7634. %s32_0 = OpConstant %s32 0
  7635. %f16_0 = OpConstant %f16 0
  7636. %f16vec4 = OpTypeCooperativeVectorNV %f16 %u32_4
  7637. %f16vec8 = OpTypeCooperativeVectorNV %f16 %u32_8
  7638. %f16_arr = OpTypeRuntimeArray %f16
  7639. %46 = OpTypeStruct %f16_arr
  7640. %47 = OpTypePointer StorageBuffer %46
  7641. %48 = OpVariable %47 StorageBuffer
  7642. %51 = OpTypePointer StorageBuffer %f16_arr
  7643. %57 = OpTypePointer Private %f16vec4
  7644. %73 = OpVariable %57 Private
  7645. %u32ptr = OpTypePointer Function %u32
  7646. %input4 = OpConstantCompositeReplicateEXT %f16vec4 %f16_0
  7647. %input8 = OpConstantCompositeReplicateEXT %f16vec8 %f16_0
  7648. %interp = OpConstant %u32 0
  7649. %offset = OpConstant %u32 0
  7650. )";
  7651. const std::string func_begin =
  7652. R"(
  7653. %main = OpFunction %void None %func
  7654. %main_entry = OpLabel
  7655. %u32var = OpVariable %u32ptr Function
  7656. %array_ptr = OpAccessChain %51 %48 %s32_0
  7657. )";
  7658. const std::string suffix =
  7659. R"(
  7660. OpReturn
  7661. OpFunctionEnd)";
  7662. return prefix + extra_types + func_begin + main_body + suffix;
  7663. }
  7664. TEST_F(ValidateMemory, CoopVecMatMulSuccess) {
  7665. std::string spirv = GenCoopVecShader("",
  7666. R"(
  7667. %result0 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input4 %interp %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7668. %result1 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input8 %interp %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_8 %s32_0 %false
  7669. %result2 = OpCooperativeVectorMatrixMulAddNV %f16vec8 %input4 %interp %array_ptr %offset %interp %array_ptr %offset %interp %u32_8 %u32_4 %s32_0 %false
  7670. %result3 = OpCooperativeVectorMatrixMulNV %f16vec4 %input4 %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7671. %result4 = OpCooperativeVectorMatrixMulNV %f16vec4 %input8 %interp %array_ptr %offset %interp %u32_4 %u32_8 %s32_0 %false
  7672. %result5 = OpCooperativeVectorMatrixMulNV %f16vec8 %input4 %interp %array_ptr %offset %interp %u32_8 %u32_4 %s32_0 %false
  7673. OpCooperativeVectorReduceSumAccumulateNV %array_ptr %offset %input4
  7674. OpCooperativeVectorOuterProductAccumulateNV %array_ptr %offset %input4 %input8 %interp %interp
  7675. )");
  7676. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7677. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7678. }
  7679. TEST_F(ValidateMemory, CoopVecMatMulKMismatchFail) {
  7680. std::string spirv = GenCoopVecShader(R"()",
  7681. R"(
  7682. %result1 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input8 %interp %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7683. )");
  7684. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7685. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7686. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7687. EXPECT_THAT(getDiagnosticString(),
  7688. HasSubstr("OpCooperativeVectorMatrixMulAddNV input number of "
  7689. "components 8 does not match K 4"));
  7690. }
  7691. TEST_F(ValidateMemory, CoopVecMatMulPackedKMismatchPass) {
  7692. std::string spirv = GenCoopVecShader(
  7693. R"(
  7694. %packed = OpConstant %u32 1000491001
  7695. )",
  7696. R"(
  7697. %result1 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input8 %packed %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7698. )");
  7699. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7700. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7701. }
  7702. TEST_F(ValidateMemory, CoopVecMatMulMMismatchFail) {
  7703. std::string spirv = GenCoopVecShader(R"()",
  7704. R"(
  7705. %result1 = OpCooperativeVectorMatrixMulAddNV %f16vec8 %input8 %interp %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_8 %s32_0 %false
  7706. )");
  7707. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7708. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7709. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7710. EXPECT_THAT(getDiagnosticString(),
  7711. HasSubstr("OpCooperativeVectorMatrixMulAddNV result type number "
  7712. "of components 8 does not match M 4"));
  7713. }
  7714. TEST_F(ValidateMemory, CoopVecMatMulTransposeTypeFail) {
  7715. std::string spirv = GenCoopVecShader(R"()",
  7716. R"(
  7717. %result0 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input4 %interp %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %s32_0
  7718. )");
  7719. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7720. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7721. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7722. EXPECT_THAT(getDiagnosticString(),
  7723. HasSubstr("OpCooperativeVectorMatrixMulAddNV Transpose <id> "
  7724. "'16[%int_0]' is not a scalar boolean"));
  7725. }
  7726. TEST_F(ValidateMemory, CoopVecMatMulInputInterpretationNotConstantFail) {
  7727. std::string spirv = GenCoopVecShader(
  7728. R"(
  7729. )",
  7730. R"(
  7731. %u32val = OpLoad %u32 %u32var
  7732. %result0 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input4 %u32val %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7733. )");
  7734. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7735. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7736. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7737. EXPECT_THAT(getDiagnosticString(),
  7738. HasSubstr("OpCooperativeVectorMatrixMulAddNV InputInterpretation "
  7739. "<id> '31[%31]' is not a constant instruction"));
  7740. }
  7741. TEST_F(ValidateMemory, CoopVecMatMulMatrixInterpretationNotConstantFail) {
  7742. std::string spirv = GenCoopVecShader(
  7743. R"(
  7744. )",
  7745. R"(
  7746. %u32val = OpLoad %u32 %u32var
  7747. %result0 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input4 %interp %array_ptr %offset %u32val %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7748. )");
  7749. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7750. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7751. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7752. EXPECT_THAT(
  7753. getDiagnosticString(),
  7754. HasSubstr("OpCooperativeVectorMatrixMulAddNV MatrixInterpretation <id> "
  7755. "'31[%31]' is not a constant instruction"));
  7756. }
  7757. TEST_F(ValidateMemory, CoopVecMatMulBiasInterpretationNotConstantFail) {
  7758. std::string spirv = GenCoopVecShader(
  7759. R"(
  7760. )",
  7761. R"(
  7762. %u32val = OpLoad %u32 %u32var
  7763. %result0 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input4 %interp %array_ptr %offset %interp %array_ptr %offset %u32val %u32_4 %u32_4 %s32_0 %false
  7764. )");
  7765. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7766. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7767. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7768. EXPECT_THAT(getDiagnosticString(),
  7769. HasSubstr("OpCooperativeVectorMatrixMulAddNV BiasInterpretation "
  7770. "<id> '31[%31]' is not a constant instruction"));
  7771. }
  7772. TEST_F(ValidateMemory, CoopVecMatMulInputInterpretationNotInt32Fail) {
  7773. std::string spirv = GenCoopVecShader(
  7774. R"(
  7775. )",
  7776. R"(
  7777. %result0 = OpCooperativeVectorMatrixMulAddNV %f16vec4 %input4 %false %array_ptr %offset %interp %array_ptr %offset %interp %u32_4 %u32_4 %s32_0 %false
  7778. )");
  7779. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7780. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7781. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7782. EXPECT_THAT(getDiagnosticString(),
  7783. HasSubstr("OpCooperativeVectorMatrixMulAddNV InputInterpretation "
  7784. "type <id> '12[%bool]' is not a 32 bit integer"));
  7785. }
  7786. TEST_F(ValidateMemory, CoopVecOuterProductABMismatchFail) {
  7787. std::string spirv = GenCoopVecShader(
  7788. R"(
  7789. %f32 = OpTypeFloat 32
  7790. %f32vec8 = OpTypeCooperativeVectorNV %f32 %u32_8
  7791. %f32_0 = OpConstant %f32 0
  7792. %input8f32 = OpConstantCompositeReplicateEXT %f32vec8 %f32_0
  7793. )",
  7794. R"(
  7795. OpCooperativeVectorOuterProductAccumulateNV %array_ptr %offset %input4 %input8f32 %interp %interp
  7796. )");
  7797. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7798. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7799. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7800. EXPECT_THAT(
  7801. getDiagnosticString(),
  7802. HasSubstr("OpCooperativeVectorOuterProductAccumulateNV A and B component "
  7803. "types '11[%half]' and '28[%float]' do not match"));
  7804. }
  7805. TEST_F(ValidateMemory, CoopVecOuterProductInt32OffsetFail) {
  7806. std::string spirv = GenCoopVecShader(
  7807. R"(
  7808. %u64 = OpTypeInt 64 0
  7809. %u64_0 = OpConstant %u64 0
  7810. )",
  7811. R"(
  7812. OpCooperativeVectorOuterProductAccumulateNV %array_ptr %u64_0 %input4 %input8 %interp %interp
  7813. )");
  7814. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7815. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7816. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7817. EXPECT_THAT(getDiagnosticString(),
  7818. HasSubstr("OpCooperativeVectorOuterProductAccumulateNV Offset "
  7819. "type <id> '28[%ulong]' is not a 32 bit integer"));
  7820. }
  7821. TEST_F(ValidateMemory, CoopVecOuterProductInt32MatrixStrideFail) {
  7822. std::string spirv = GenCoopVecShader(
  7823. R"(
  7824. %u64 = OpTypeInt 64 0
  7825. %u64_0 = OpConstant %u64 0
  7826. )",
  7827. R"(
  7828. OpCooperativeVectorOuterProductAccumulateNV %array_ptr %offset %input4 %input8 %interp %interp %u64_0
  7829. )");
  7830. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7831. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7832. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7833. EXPECT_THAT(
  7834. getDiagnosticString(),
  7835. HasSubstr("OpCooperativeVectorOuterProductAccumulateNV MatrixStride type "
  7836. "<id> '28[%ulong]' is not a 32 bit integer"));
  7837. }
  7838. TEST_F(ValidateMemory, CoopVecOuterProductVectorTypeFail) {
  7839. std::string spirv = GenCoopVecShader(
  7840. R"(
  7841. %f16v4 = OpTypeVector %f16 4
  7842. %f16c = OpConstantCompositeReplicateEXT %f16v4 %f16_0
  7843. )",
  7844. R"(
  7845. OpCooperativeVectorOuterProductAccumulateNV %array_ptr %offset %f16c %input8 %interp %interp
  7846. )");
  7847. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7848. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7849. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7850. EXPECT_THAT(getDiagnosticString(),
  7851. HasSubstr("OpCooperativeVectorOuterProductAccumulateNV A type "
  7852. "<id> '28[%v4half]' is not a cooperative vector type"));
  7853. }
  7854. TEST_F(ValidateMemory, CoopVecReduceSumInt32OffsetFail) {
  7855. std::string spirv = GenCoopVecShader(
  7856. R"(
  7857. %u64 = OpTypeInt 64 0
  7858. %u64_0 = OpConstant %u64 0
  7859. )",
  7860. R"(
  7861. OpCooperativeVectorReduceSumAccumulateNV %array_ptr %u64_0 %input4
  7862. )");
  7863. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7864. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7865. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7866. EXPECT_THAT(getDiagnosticString(),
  7867. HasSubstr("OpCooperativeVectorReduceSumAccumulateNV Offset type "
  7868. "<id> '28[%ulong]' is not a 32 bit integer"));
  7869. }
  7870. TEST_F(ValidateMemory, CoopVecReduceSumVectorTypeFail) {
  7871. std::string spirv = GenCoopVecShader(
  7872. R"(
  7873. %f16v4 = OpTypeVector %f16 4
  7874. %f16c = OpConstantCompositeReplicateEXT %f16v4 %f16_0
  7875. )",
  7876. R"(
  7877. OpCooperativeVectorReduceSumAccumulateNV %array_ptr %offset %f16c
  7878. )");
  7879. CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1_SPIRV_1_4);
  7880. ASSERT_EQ(SPV_ERROR_INVALID_ID,
  7881. ValidateInstructions(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
  7882. EXPECT_THAT(getDiagnosticString(),
  7883. HasSubstr("OpCooperativeVectorReduceSumAccumulateNV V type <id> "
  7884. "'28[%v4half]' is not a cooperative vector type."));
  7885. }
  7886. } // namespace
  7887. } // namespace val
  7888. } // namespace spvtools