val_id_test.cpp 223 KB

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