val_id_test.cpp 232 KB

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