| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183 |
- // Copyright (c) 2015-2016 The Khronos Group Inc.
- // Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
- // reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include <sstream>
- #include <string>
- #include <vector>
- #include "gmock/gmock.h"
- #include "test/test_fixture.h"
- #include "test/unit_spirv.h"
- #include "test/val/val_fixtures.h"
- // NOTE: The tests in this file are ONLY testing ID usage, there for the input
- // SPIR-V does not follow the logical layout rules from the spec in all cases in
- // order to makes the tests smaller. Validation of the whole module is handled
- // in stages, ID validation is only one of these stages. All validation stages
- // are stand alone.
- namespace spvtools {
- namespace val {
- namespace {
- using spvtest::ScopedContext;
- using ::testing::HasSubstr;
- using ::testing::ValuesIn;
- class ValidateIdWithMessage : public spvtest::ValidateBase<bool> {
- public:
- ValidateIdWithMessage() {
- const bool use_friendly_names = GetParam();
- spvValidatorOptionsSetFriendlyNames(options_, use_friendly_names);
- }
- std::string make_message(const char* msg);
- };
- std::string kOpCapabilitySetupWithoutVector16 = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability Float64
- OpCapability LiteralSampler
- OpCapability Pipes
- OpCapability DeviceEnqueue
- )";
- std::string kOpCapabilitySetup = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability Float64
- OpCapability LiteralSampler
- OpCapability Pipes
- OpCapability DeviceEnqueue
- OpCapability Vector16
- )";
- std::string kOpVariablePtrSetUp = R"(
- OpCapability VariablePointers
- OpExtension "SPV_KHR_variable_pointers"
- )";
- std::string kGLSL450MemoryModel =
- kOpCapabilitySetup + kOpVariablePtrSetUp + R"(
- OpMemoryModel Logical GLSL450
- )";
- std::string kGLSL450MemoryModelWithoutVector16 =
- kOpCapabilitySetupWithoutVector16 + kOpVariablePtrSetUp + R"(
- OpMemoryModel Logical GLSL450
- )";
- std::string kNoKernelGLSL450MemoryModel = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability Float64
- OpMemoryModel Logical GLSL450
- )";
- std::string kOpenCLMemoryModel32 = R"(
- OpCapability Addresses
- OpCapability Linkage
- OpCapability Kernel
- %1 = OpExtInstImport "OpenCL.std"
- OpMemoryModel Physical32 OpenCL
- )";
- std::string kOpenCLMemoryModel64 = R"(
- OpCapability Addresses
- OpCapability Linkage
- OpCapability Kernel
- OpCapability Int64
- %1 = OpExtInstImport "OpenCL.std"
- OpMemoryModel Physical64 OpenCL
- )";
- std::string sampledImageSetup = R"(
- %void = OpTypeVoid
- %typeFuncVoid = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %image_type = OpTypeImage %float 2D 0 0 0 1 Unknown
- %_ptr_UniformConstant_img = OpTypePointer UniformConstant %image_type
- %tex = OpVariable %_ptr_UniformConstant_img UniformConstant
- %sampler_type = OpTypeSampler
- %_ptr_UniformConstant_sam = OpTypePointer UniformConstant %sampler_type
- %s = OpVariable %_ptr_UniformConstant_sam UniformConstant
- %sampled_image_type = OpTypeSampledImage %image_type
- %v2float = OpTypeVector %float 2
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %const_vec_1_1 = OpConstantComposite %v2float %float_1 %float_1
- %const_vec_2_2 = OpConstantComposite %v2float %float_2 %float_2
- %bool_type = OpTypeBool
- %spec_true = OpSpecConstantTrue %bool_type
- %main = OpFunction %void None %typeFuncVoid
- %label_1 = OpLabel
- %image_inst = OpLoad %image_type %tex
- %sampler_inst = OpLoad %sampler_type %s
- )";
- std::string BranchConditionalSetup = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- ; type definitions
- %bool = OpTypeBool
- %uint = OpTypeInt 32 0
- %int = OpTypeInt 32 1
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- ; constants
- %true = OpConstantTrue %bool
- %i0 = OpConstant %int 0
- %i1 = OpConstant %int 1
- %f0 = OpConstant %float 0
- %f1 = OpConstant %float 1
- ; main function header
- %void = OpTypeVoid
- %voidfunc = OpTypeFunction %void
- %main = OpFunction %void None %voidfunc
- %lmain = OpLabel
- )";
- std::string BranchConditionalTail = R"(
- %target_t = OpLabel
- OpNop
- OpBranch %end
- %target_f = OpLabel
- OpNop
- OpBranch %end
- %end = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- // Transform an expected validation message to either use friendly names (as
- // provided in the message) or replace the friendly names by the corresponding
- // id. The same flag used to configure the validator to output friendly names
- // or not is used here.
- std::string ValidateIdWithMessage::make_message(const char* msg) {
- const bool use_friendly_names = GetParam();
- if (use_friendly_names) {
- return msg;
- }
- std::string message(msg);
- std::ostringstream result;
- size_t next = 0;
- while (next < message.size()) {
- // Parse 'num[%name]'
- size_t open_quote = message.find('\'', next);
- if (open_quote == std::string::npos) {
- break;
- }
- // Copy up to the first quote
- result.write(msg + next, open_quote - next);
- // Handle apostrophes
- if (!isdigit(message[open_quote + 1])) {
- result << '\'';
- next = open_quote + 1;
- continue;
- }
- size_t open_bracket = message.find('[', open_quote + 1);
- assert(open_bracket != std::string::npos);
- size_t close_bracket = message.find(']', open_bracket + 1);
- assert(close_bracket != std::string::npos);
- size_t close_quote = close_bracket + 1;
- assert(close_quote < message.size() && message[close_quote] == '\'');
- // Change to 'num[%num]' because friendly names are not being used.
- result.write(msg + open_quote, open_bracket - open_quote + 1);
- result << '%';
- result.write(msg + open_quote + 1, open_bracket - open_quote - 1);
- result << "]'";
- // Continue to the next id, or end of string.
- next = close_quote + 1;
- }
- return result.str();
- }
- // TODO: OpUndef
- TEST_P(ValidateIdWithMessage, OpName) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpName %2 "name"
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer UniformConstant %1
- %3 = OpVariable %2 UniformConstant)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpMemberNameGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberName %2 0 "foo"
- %1 = OpTypeInt 32 0
- %2 = OpTypeStruct %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpMemberNameTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberName %1 0 "foo"
- %1 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpMemberName Type <id> '1[%uint]' is not a struct type.")));
- }
- TEST_P(ValidateIdWithMessage, OpMemberNameMemberBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberName %1 1 "foo"
- %2 = OpTypeInt 32 0
- %1 = OpTypeStruct %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpMemberName Member <id> '1[%_struct_1]' index is larger "
- "than Type <id> '1[%_struct_1]'s member count.")));
- }
- TEST_P(ValidateIdWithMessage, OpLineGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpString "/path/to/source.file"
- OpLine %1 0 0
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Input %2
- %4 = OpVariable %3 Input)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpLineFileBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- OpLine %1 0 0
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpLine Target <id> '1[%uint]' is not an OpString.")));
- }
- TEST_P(ValidateIdWithMessage, OpDecorateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %2 GLSLShared
- %1 = OpTypeInt 64 0
- %2 = OpTypeStruct %1 %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpDecorateBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 GLSLShared)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("forward referenced IDs have not been defined")));
- }
- TEST_P(ValidateIdWithMessage, OpMemberDecorateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %2 0 RelaxedPrecision
- %1 = OpTypeInt 32 0
- %2 = OpTypeStruct %1 %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpMemberDecorateBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 RelaxedPrecision
- %1 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpMemberDecorate Structure type <id> '1[%uint]' is "
- "not a struct type.")));
- }
- TEST_P(ValidateIdWithMessage, OpMemberDecorateMemberBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 3 RelaxedPrecision
- %int = OpTypeInt 32 0
- %1 = OpTypeStruct %int %int)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Index 3 provided in OpMemberDecorate for struct <id> "
- "'1[%_struct_1]' is out of bounds. The structure has 2 "
- "members. Largest valid index is 1.")));
- }
- TEST_P(ValidateIdWithMessage, OpGroupDecorateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 GLSLShared
- OpGroupDecorate %1 %3 %4
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 42
- %4 = OpConstant %2 23)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpDecorationGroupBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 GLSLShared
- OpMemberDecorate %1 0 Constant
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Result id of OpDecorationGroup can only "
- "be targeted by OpName, OpGroupDecorate, "
- "OpDecorate, OpDecorateId, and OpGroupMemberDecorate")));
- }
- TEST_P(ValidateIdWithMessage, OpGroupDecorateDecorationGroupBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpGroupDecorate %1 %2 %3
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 42)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpGroupDecorate Decoration group <id> '1[%1]' is not "
- "a decoration group.")));
- }
- TEST_P(ValidateIdWithMessage, OpGroupDecorateTargetBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpDecorate %1 RelaxedPrecision
- OpDecorate %1 GLSLShared
- OpGroupDecorate %1 %3
- %2 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("forward referenced IDs have not been defined")));
- }
- TEST_P(ValidateIdWithMessage, OpGroupMemberDecorateDecorationGroupBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpGroupMemberDecorate %1 %2 0
- %2 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpGroupMemberDecorate Decoration group <id> '1[%1]' "
- "is not a decoration group.")));
- }
- TEST_P(ValidateIdWithMessage, OpGroupMemberDecorateIdNotStructBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %2 0
- %2 = OpTypeInt 32 0)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpGroupMemberDecorate Structure type <id> '2[%uint]' "
- "is not a struct type.")));
- }
- TEST_P(ValidateIdWithMessage, OpGroupMemberDecorateIndexOutOfBoundBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 Offset 0
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %struct 3
- %float = OpTypeFloat 32
- %struct = OpTypeStruct %float %float %float
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Index 3 provided in OpGroupMemberDecorate for struct "
- "<id> '2[%_struct_2]' is out of bounds. The structure "
- "has 3 members. Largest valid index is 2.")));
- }
- // TODO: OpExtInst
- TEST_P(ValidateIdWithMessage, OpEntryPointGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %3 ""
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointFunctionBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %1 ""
- %1 = OpTypeVoid)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpEntryPoint Entry Point <id> '1[%void]' is not a "
- "function.")));
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointParameterCountBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2 %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "parameter count is not zero")));
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointReturnTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeInt 32 0
- %ret = OpConstant %2 0
- %3 = OpTypeFunction %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturnValue %ret
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "return type is not void.")));
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointParameterCountBadInVulkan) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2 %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-None-04633"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "parameter count is not zero")));
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointReturnTypeBadInVulkan) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 ""
- %2 = OpTypeInt 32 0
- %ret = OpConstant %2 0
- %3 = OpTypeFunction %2
- %1 = OpFunction %2 None %3
- %4 = OpLabel
- OpReturnValue %ret
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-None-04633"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpEntryPoint Entry Point <id> '1[%1]'s function "
- "return type is not void.")));
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointInterfaceIsNotVariableTypeBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %ptr_builtin_1
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- OpMemberDecorate %struct_1 0 BuiltIn InvocationId
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %struct_1 = OpTypeStruct %int
- %ptr_builtin_1 = OpTypePointer Input %struct_1
- %main = OpFunction %void None %func
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Interfaces passed to OpEntryPoint must be variables. "
- "Found OpTypePointer."));
- }
- TEST_P(ValidateIdWithMessage, OpEntryPointInterfaceStorageClassBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Geometry
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %in_1
- OpExecutionMode %main InputPoints
- OpExecutionMode %main OutputPoints
- OpMemberDecorate %struct_1 0 BuiltIn InvocationId
- %int = OpTypeInt 32 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %struct_1 = OpTypeStruct %int
- %ptr_builtin_1 = OpTypePointer Uniform %struct_1
- %in_1 = OpVariable %ptr_builtin_1 Uniform
- %main = OpFunction %void None %func
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpEntryPoint interfaces must be OpVariables with "
- "Storage Class of Input(1) or Output(3). Found Storage "
- "Class 2 for Entry Point id 1.")));
- }
- TEST_P(ValidateIdWithMessage, OpExecutionModeGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %3 ""
- OpExecutionMode %3 LocalSize 1 1 1
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpExecutionModeEntryPointMissing) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpExecutionMode %3 LocalSize 1 1 1
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpExecutionMode Entry Point <id> '1[%1]' is not the "
- "Entry Point operand of an OpEntryPoint.")));
- }
- TEST_P(ValidateIdWithMessage, OpExecutionModeEntryPointBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpEntryPoint GLCompute %3 "" %a
- OpExecutionMode %a LocalSize 1 1 1
- %void = OpTypeVoid
- %ptr = OpTypePointer Input %void
- %a = OpVariable %ptr Input
- %2 = OpTypeFunction %void
- %3 = OpFunction %void None %2
- %4 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpExecutionMode Entry Point <id> '2[%2]' is not the "
- "Entry Point operand of an OpEntryPoint.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorFloat) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorInt) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorUInt) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 64 0
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorBool) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpTypeVector %1 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorComponentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypePointer UniformConstant %1
- %3 = OpTypeVector %2 4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeVector Component Type <id> "
- "'2[%_ptr_UniformConstant_float]' is not a scalar type.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorColumnCountLessThanTwoBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Illegal number of components (1) for TypeVector\n %v1float = "
- "OpTypeVector %float 1\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorColumnCountGreaterThanFourBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Illegal number of components (5) for TypeVector\n %v5float = "
- "OpTypeVector %float 5\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorColumnCountEightWithoutVector16Bad) {
- std::string spirv = kGLSL450MemoryModelWithoutVector16 + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Having 8 components for TypeVector requires the Vector16 "
- "capability\n %v8float = OpTypeVector %float 8\n")));
- }
- TEST_P(ValidateIdWithMessage,
- OpTypeVectorColumnCountSixteenWithoutVector16Bad) {
- std::string spirv = kGLSL450MemoryModelWithoutVector16 + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 16)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Having 16 components for TypeVector requires the Vector16 "
- "capability\n %v16float = OpTypeVector %float 16\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeVectorColumnCountOfEightWithVector16Good) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage,
- OpTypeVectorColumnCountOfSixteenWithVector16Good) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 16)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeMatrixGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeMatrixColumnTypeNonVectorBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeMatrix %1 3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "olumns in a matrix must be of type vector.\n %mat3float = "
- "OpTypeMatrix %float 3\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeMatrixVectorTypeNonFloatBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 16 0
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Matrix types can only be parameterized with floating-point "
- "types.\n %mat2v2ushort = OpTypeMatrix %v2ushort 2\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeMatrixColumnCountLessThanTwoBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Matrix types can only be parameterized as having only 2, 3, "
- "or 4 columns.\n %mat1v2float = OpTypeMatrix %v2float 1\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeMatrixColumnCountGreaterThanFourBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 2
- %3 = OpTypeMatrix %2 8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Matrix types can only be parameterized as having only 2, 3, "
- "or 4 columns.\n %mat8v2float = OpTypeMatrix %v2float 8\n")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeSamplerGood) {
- // In Rev31, OpTypeSampler takes no arguments.
- std::string spirv = kGLSL450MemoryModel + R"(
- %s = OpTypeSampler)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 1
- %3 = OpTypeArray %1 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeArrayElementTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 1
- %3 = OpTypeArray %2 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeArray Element Type <id> '2[%uint_1]' is not a "
- "type.")));
- }
- // Signed or unsigned.
- enum Signed { kSigned, kUnsigned };
- // Creates an assembly module declaring OpTypeArray with the given length.
- std::string MakeArrayLength(const std::string& len, Signed isSigned, int width,
- int max_int_width = 64,
- bool use_vulkan_memory_model = false) {
- std::ostringstream ss;
- ss << R"(
- OpCapability Shader
- )";
- if (use_vulkan_memory_model) {
- ss << " OpCapability VulkanMemoryModel\n";
- }
- if (width == 16) {
- ss << " OpCapability Int16\n";
- }
- if (max_int_width > 32) {
- ss << "\n OpCapability Int64\n";
- }
- if (use_vulkan_memory_model) {
- ss << " OpExtension \"SPV_KHR_vulkan_memory_model\"\n";
- ss << "OpMemoryModel Logical Vulkan\n";
- } else {
- ss << "OpMemoryModel Logical GLSL450\n";
- }
- ss << "OpEntryPoint GLCompute %main \"main\"\n";
- ss << "OpExecutionMode %main LocalSize 1 1 1\n";
- ss << " %t = OpTypeInt " << width << (isSigned == kSigned ? " 1" : " 0");
- ss << " %l = OpConstant %t " << len;
- ss << " %a = OpTypeArray %t %l";
- ss << " %void = OpTypeVoid \n"
- " %voidfn = OpTypeFunction %void \n"
- " %main = OpFunction %void None %voidfn \n"
- " %entry = OpLabel\n"
- " OpReturn\n"
- " OpFunctionEnd\n";
- return ss.str();
- }
- // Tests OpTypeArray. Parameter is the width (in bits) of the array-length's
- // type.
- class OpTypeArrayLengthTest
- : public spvtest::TextToBinaryTestBase<::testing::TestWithParam<int>> {
- protected:
- OpTypeArrayLengthTest()
- : env_(SPV_ENV_UNIVERSAL_1_0),
- position_(spv_position_t{0, 0, 0}),
- diagnostic_(spvDiagnosticCreate(&position_, "")) {}
- ~OpTypeArrayLengthTest() override { spvDiagnosticDestroy(diagnostic_); }
- // Runs spvValidate() on v, printing any errors via spvDiagnosticPrint().
- spv_result_t Val(const SpirvVector& v, const std::string& expected_err = "") {
- spv_const_binary_t cbinary{v.data(), v.size()};
- spvDiagnosticDestroy(diagnostic_);
- diagnostic_ = nullptr;
- const auto status =
- spvValidate(ScopedContext(env_).context, &cbinary, &diagnostic_);
- if (status != SPV_SUCCESS) {
- spvDiagnosticPrint(diagnostic_);
- EXPECT_THAT(std::string(diagnostic_->error),
- testing::ContainsRegex(expected_err));
- }
- return status;
- }
- protected:
- spv_target_env env_;
- private:
- spv_position_t position_; // For creating diagnostic_.
- spv_diagnostic diagnostic_;
- };
- TEST_P(OpTypeArrayLengthTest, LengthPositiveSmall) {
- const int width = GetParam();
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("1", kSigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("1", kUnsigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("2", kSigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("2", kUnsigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("55", kSigned, width))));
- EXPECT_EQ(SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("55", kUnsigned, width))));
- const std::string fpad(width / 4 - 1, 'F');
- EXPECT_EQ(
- SPV_SUCCESS,
- Val(CompileSuccessfully(MakeArrayLength("0x7" + fpad, kSigned, width))))
- << MakeArrayLength("0x7" + fpad, kSigned, width);
- }
- TEST_P(OpTypeArrayLengthTest, LengthZero) {
- const int width = GetParam();
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- }
- TEST_P(OpTypeArrayLengthTest, LengthNegative) {
- const int width = GetParam();
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- const std::string neg_max = "0x8" + std::string(width / 4 - 1, '0');
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width)),
- "OpTypeArray Length <id> '3\\[%.*\\]' default value must be at "
- "least 1."));
- }
- // Returns the string form of an integer of the form 0x80....0 of the
- // given bit width.
- std::string big_num_ending_0(int bit_width) {
- return "0x8" + std::string(bit_width / 4 - 1, '0');
- }
- // Returns the string form of an integer of the form 0x80..001 of the
- // given bit width.
- std::string big_num_ending_1(int bit_width) {
- return "0x8" + std::string(bit_width / 4 - 2, '0') + "1";
- }
- TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding0InVulkan) {
- env_ = SPV_ENV_VULKAN_1_0;
- const int width = GetParam();
- for (int max_int_width : {32, 64}) {
- if (width > max_int_width) {
- // Not valid to even make the OpConstant in this case.
- continue;
- }
- const auto module = CompileSuccessfully(MakeArrayLength(
- big_num_ending_0(width), kUnsigned, width, max_int_width));
- EXPECT_EQ(SPV_SUCCESS, Val(module));
- }
- }
- TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding1InVulkan) {
- env_ = SPV_ENV_VULKAN_1_0;
- const int width = GetParam();
- for (int max_int_width : {32, 64}) {
- if (width > max_int_width) {
- // Not valid to even make the OpConstant in this case.
- continue;
- }
- const auto module = CompileSuccessfully(MakeArrayLength(
- big_num_ending_1(width), kUnsigned, width, max_int_width));
- EXPECT_EQ(SPV_SUCCESS, Val(module));
- }
- }
- // The only valid widths for integers are 8, 16, 32, and 64.
- // Since the Int8 capability requires the Kernel capability, and the Kernel
- // capability prohibits usage of signed integers, we can skip 8-bit integers
- // here since the purpose of these tests is to check the validity of
- // OpTypeArray, not OpTypeInt.
- INSTANTIATE_TEST_SUITE_P(Widths, OpTypeArrayLengthTest,
- ValuesIn(std::vector<int>{16, 32, 64}));
- TEST_P(ValidateIdWithMessage, OpTypeArrayLengthNull) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %i32 = OpTypeInt 32 0
- %len = OpConstantNull %i32
- %ary = OpTypeArray %i32 %len)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("OpTypeArray Length <id> '2[%2]' default "
- "value must be at least 1: found 0")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeArrayLengthSpecConst) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %i32 = OpTypeInt 32 0
- %len = OpSpecConstant %i32 2
- %ary = OpTypeArray %i32 %len)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeArrayLengthSpecConstOp) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %i32 = OpTypeInt 32 0
- %c1 = OpConstant %i32 1
- %c2 = OpConstant %i32 2
- %len = OpSpecConstantOp %i32 IAdd %c1 %c2
- %ary = OpTypeArray %i32 %len)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeRuntimeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeRuntimeArray %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeRuntimeArrayBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 0
- %3 = OpTypeRuntimeArray %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeRuntimeArray Element Type <id> '2[%uint_0]' is not a "
- "type.")));
- }
- // TODO: Object of this type can only be created with OpVariable using the
- // Uniform Storage Class
- TEST_P(ValidateIdWithMessage, OpTypeStructGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 64
- %3 = OpTypePointer Input %1
- %4 = OpTypeStruct %1 %2 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeStructMemberTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 64
- %3 = OpConstant %2 0.0
- %4 = OpTypeStruct %1 %2 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeStruct Member Type <id> '3[%double_0]' is not "
- "a type.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeStructOpaqueTypeBad) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- %1 = OpTypeSampler
- %2 = OpTypeStruct %1
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-None-04667"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpTypeStruct must not contain an opaque type")));
- }
- TEST_P(ValidateIdWithMessage, OpTypePointerGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypePointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 0
- %3 = OpTypePointer Input %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpTypePointer Type <id> '2[%uint_0]' is not a "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypePointerCanHaveUntypedPointer) {
- const std::string spirv = R"(
- OpCapability Kernel
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical OpenCL
- %ptr = OpTypeUntypedPointerKHR Workgroup
- %ptr2 = OpTypePointer Private %ptr
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerWorkgroupGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpCapability WorkgroupMemoryExplicitLayoutKHR
- OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- %ptr = OpTypeUntypedPointerKHR Workgroup
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- }
- TEST_P(ValidateIdWithMessage,
- OpTypeUntypedPointerWorkgroupMissingExplicitLayout) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %ptr = OpTypeUntypedPointerKHR Workgroup
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("Workgroup storage class untyped pointers in Vulkan require "
- "WorkgroupMemoryExplicitLayoutKHR be declared"));
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerWorkgroupGoodAll) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- %ptr = OpTypeUntypedPointerKHR Workgroup
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerStorageBufferGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- %ptr = OpTypeUntypedPointerKHR StorageBuffer
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerUniformGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- %ptr = OpTypeUntypedPointerKHR Uniform
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerPushConstantGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- %ptr = OpTypeUntypedPointerKHR PushConstant
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerCrossWorkgroupGood) {
- const std::string spirv = R"(
- OpCapability Kernel
- OpCapability Linkage
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical OpenCL
- %ptr = OpTypeUntypedPointerKHR CrossWorkgroup
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeUntypedPointerVulkanInvalidStorageClass) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability UntypedPointersKHR
- OpExtension "SPV_KHR_untyped_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %void_fn = OpTypeFunction %void
- %ptr = OpTypeUntypedPointerKHR Private
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("In Vulkan, untyped pointers can only be used in an "
- "explicitly laid out storage class"));
- }
- TEST_P(ValidateIdWithMessage, OpTypeFunctionGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpTypeFunctionReturnTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 0
- %3 = OpTypeFunction %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeFunction Return Type <id> '2[%uint_0]' is not "
- "a type.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeFunctionParameterBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 0
- %4 = OpTypeFunction %1 %2 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeFunction Parameter Type <id> '3[%uint_0]' is not a "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeFunctionParameterTypeVoidBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %4 = OpTypeFunction %1 %2 %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpTypeFunction Parameter Type <id> '1[%void]' cannot "
- "be OpTypeVoid.")));
- }
- TEST_P(ValidateIdWithMessage, OpTypePipeGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 16
- %3 = OpTypePipe ReadOnly)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantTrueGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantTrueBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantTrue Result Type <id> '1[%void]' is not a boolean "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantFalseGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantFalseBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstantFalse %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantFalse Result Type <id> '1[%void]' is not a boolean "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstant !1 !0)";
- // The expected failure code is implementation dependent (currently
- // INVALID_BINARY because the binary parser catches these cases) and may
- // change over time, but this must always fail.
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeVectorGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpConstant %1 3.14
- %4 = OpConstantComposite %2 %3 %3 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeVectorWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpConstant %1 3.14
- %9 = OpUndef %1
- %4 = OpConstantComposite %2 %3 %3 %3 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeVectorResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpConstant %1 3.14
- %4 = OpConstantComposite %1 %3 %3 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Result Type <id> '1[%float]' is not a "
- "composite type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeVectorConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpConstant %1 3.14
- %5 = OpConstant %4 42 ; bad type for constant value
- %6 = OpConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> '5[%uint_42]'s type "
- "does not match Result Type <id> '2[%v4float]'s vector "
- "element type.")));
- }
- TEST_P(ValidateIdWithMessage,
- OpConstantCompositeVectorConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpConstant %1 3.14
- %5 = OpUndef %4 ; bad type for undef value
- %6 = OpConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> '5[%5]'s type does not "
- "match Result Type <id> '2[%v4float]'s vector element type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeMatrixGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpConstantComposite %2 %5 %5 %5 %4
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeMatrixUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpUndef %2
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeMatrixConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %11 = OpTypeVector %1 3
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpConstantComposite %11 %5 %5 %5
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> '10[%10]' vector "
- "component count does not match Result Type <id> "
- "'4[%mat4v4float]'s vector component count.")));
- }
- TEST_P(ValidateIdWithMessage,
- OpConstantCompositeMatrixConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %11 = OpTypeVector %1 3
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpConstantComposite %2 %4 %5 %5 %5
- %7 = OpConstantComposite %2 %5 %4 %5 %5
- %8 = OpConstantComposite %2 %5 %5 %4 %5
- %9 = OpUndef %11
- %10 = OpConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> '10[%10]' vector "
- "component count does not match Result Type <id> "
- "'4[%mat4v4float]'s vector component count.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpConstantComposite %3 %2 %2 %2 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeArrayWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %9 = OpUndef %1
- %3 = OpTypeArray %1 %2
- %4 = OpConstantComposite %3 %2 %2 %2 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpConstantComposite %3 %2 %2 %2 %1)"; // Uses a type as operand
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '1[%uint]' cannot be a "
- "type")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpTypePointer Uniform %1
- %5 = OpVariable %4 Uniform
- %6 = OpConstantComposite %3 %2 %2 %2 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> '5[%5]' is not a "
- "constant or undef.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeArrayConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %5 = OpTypeFloat 32
- %6 = OpConstant %5 3.14 ; bad type for const value
- %4 = OpConstantComposite %3 %2 %2 %2 %6)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> "
- "'5[%float_3_1400001]'s type does not match Result "
- "Type <id> '3[%_arr_uint_uint_4]'s array element "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeArrayConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %5 = OpTypeFloat 32
- %6 = OpUndef %5 ; bad type for undef
- %4 = OpConstantComposite %3 %2 %2 %2 %6)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpConstantComposite Constituent <id> "
- "'5[%5]'s type does not match Result "
- "Type <id> '3[%_arr_uint_uint_4]'s array element "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeStructGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpConstant %2 4300000000
- %6 = OpConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeStructUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpUndef %2
- %6 = OpConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeStructMemberTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpConstant %2 4300000000
- %6 = OpConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> "
- "'5[%ulong_4300000000]' type does not match the "
- "Result Type <id> '3[%_struct_3]'s member type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantCompositeStructMemberUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpUndef %2
- %6 = OpConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantComposite Constituent <id> '5[%5]' type "
- "does not match the Result Type <id> '3[%_struct_3]'s "
- "member type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantSamplerGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %samplerType = OpTypeSampler
- %3 = OpConstantSampler %samplerType ClampToEdge 0 Nearest)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantSamplerResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpConstantSampler %1 Clamp 0 Nearest)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantSampler Result Type <id> '1[%float]' is not a sampler "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantNullGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpConstantNull %1
- %3 = OpTypeInt 32 0
- %4 = OpConstantNull %3
- %5 = OpTypeFloat 32
- %6 = OpConstantNull %5
- %7 = OpTypePointer UniformConstant %3
- %8 = OpConstantNull %7
- %9 = OpTypeEvent
- %10 = OpConstantNull %9
- %11 = OpTypeDeviceEvent
- %12 = OpConstantNull %11
- %13 = OpTypeReserveId
- %14 = OpConstantNull %13
- %15 = OpTypeQueue
- %16 = OpConstantNull %15
- %17 = OpTypeVector %5 2
- %18 = OpConstantNull %17
- %19 = OpTypeMatrix %17 2
- %20 = OpConstantNull %19
- %25 = OpConstant %3 8
- %21 = OpTypeArray %3 %25
- %22 = OpConstantNull %21
- %23 = OpTypeStruct %3 %5 %1
- %24 = OpConstantNull %23
- %26 = OpTypeArray %17 %25
- %27 = OpConstantNull %26
- %28 = OpTypeStruct %7 %26 %26 %1
- %29 = OpConstantNull %28
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpConstantNullBasicBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpConstantNull %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantNull Result Type <id> '1[%void]' cannot have a null "
- "value.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantNullArrayBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %2 = OpTypeInt 32 0
- %3 = OpTypeSampler
- %4 = OpConstant %2 4
- %5 = OpTypeArray %3 %4
- %6 = OpConstantNull %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantNull Result Type <id> '4[%_arr_2_uint_4]' cannot have a "
- "null value.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantNullStructBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %2 = OpTypeSampler
- %3 = OpTypeStruct %2 %2
- %4 = OpConstantNull %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpConstantNull Result Type <id> '2[%_struct_2]' "
- "cannot have a null value.")));
- }
- TEST_P(ValidateIdWithMessage, OpConstantNullRuntimeArrayBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %array = OpTypeRuntimeArray %bool
- %null = OpConstantNull %array)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpConstantNull Result Type <id> '2[%_runtimearr_bool]' cannot have "
- "a null value.")));
- }
- TEST_P(ValidateIdWithMessage, OpSpecConstantTrueGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpSpecConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpSpecConstantTrueBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpSpecConstantTrue %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantTrue Result Type <id> '1[%void]' is not "
- "a boolean type")));
- }
- TEST_P(ValidateIdWithMessage, OpSpecConstantFalseGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeBool
- %2 = OpSpecConstantFalse %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpSpecConstantFalseBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpSpecConstantFalse %1)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantFalse Result Type <id> '1[%void]' is not "
- "a boolean type")));
- }
- TEST_P(ValidateIdWithMessage, OpSpecConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpSpecConstant %1 42)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpSpecConstantBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpSpecConstant !1 !4)";
- // The expected failure code is implementation dependent (currently
- // INVALID_BINARY because the binary parser catches these cases) and may
- // change over time, but this must always fail.
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Type Id 1 is not a scalar numeric type")));
- }
- // Valid: SpecConstantComposite specializes to a vector.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeVectorGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpSpecConstant %1 3.14
- %4 = OpConstant %1 3.14
- %5 = OpSpecConstantComposite %2 %3 %3 %4 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Vector of floats and Undefs.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeVectorWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpSpecConstant %1 3.14
- %5 = OpConstant %1 3.14
- %9 = OpUndef %1
- %4 = OpSpecConstantComposite %2 %3 %5 %3 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: result type is float.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeVectorResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpSpecConstant %1 3.14
- %4 = OpSpecConstantComposite %1 %3 %3 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("is not a composite type")));
- }
- // Invalid: Vector contains a mix of Int and Float.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeVectorConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpSpecConstant %1 3.14
- %5 = OpConstant %4 42 ; bad type for constant value
- %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> "
- "'5[%uint_42]'s type does not match Result Type <id> "
- "'2[%v4float]'s vector element type.")));
- }
- // Invalid: Constituent is not a constant
- TEST_P(ValidateIdWithMessage,
- OpSpecConstantCompositeVectorConstituentNotConstantBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeInt 32 0
- %4 = OpSpecConstant %1 3.14
- %5 = OpTypePointer Uniform %1
- %6 = OpVariable %5 Uniform
- %7 = OpSpecConstantComposite %2 %6 %4 %4 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '6[%6]' is "
- "not a constant or undef.")));
- }
- // Invalid: Vector contains a mix of Undef-int and Float.
- TEST_P(ValidateIdWithMessage,
- OpSpecConstantCompositeVectorConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %4 = OpTypeInt 32 0
- %3 = OpSpecConstant %1 3.14
- %5 = OpUndef %4 ; bad type for undef value
- %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '5[%5]'s "
- "type does not match Result Type <id> '2[%v4float]'s "
- "vector element type.")));
- }
- // Invalid: Vector expects 3 components, but 4 specified.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeVectorNumComponentsBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 3
- %3 = OpConstant %1 3.14
- %5 = OpSpecConstant %1 4.0
- %6 = OpSpecConstantComposite %2 %3 %5 %3 %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> count does "
- "not match Result Type <id> '2[%v3float]'s vector "
- "component count.")));
- }
- // Valid: 4x4 matrix of floats
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeMatrixGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpSpecConstant %1 0.0
- %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
- %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
- %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
- %9 = OpSpecConstantComposite %2 %5 %5 %5 %4
- %10 = OpSpecConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Matrix in which one column is Undef
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeMatrixUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpConstant %1 1.0
- %5 = OpSpecConstant %1 0.0
- %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
- %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
- %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
- %9 = OpUndef %2
- %10 = OpSpecConstantComposite %3 %6 %7 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Matrix in which the sizes of column vectors are not equal.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeMatrixConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeVector %1 3
- %4 = OpTypeMatrix %2 4
- %5 = OpSpecConstant %1 1.0
- %6 = OpConstant %1 0.0
- %7 = OpSpecConstantComposite %2 %5 %6 %6 %6
- %8 = OpSpecConstantComposite %2 %6 %5 %6 %6
- %9 = OpSpecConstantComposite %2 %6 %6 %5 %6
- %10 = OpSpecConstantComposite %3 %6 %6 %6
- %11 = OpSpecConstantComposite %4 %7 %8 %9 %10)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '10[%10]' "
- "vector component count does not match Result Type "
- "<id> '4[%mat4v4float]'s vector component count.")));
- }
- // Invalid: Matrix type expects 4 columns but only 3 specified.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeMatrixNumColsBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeMatrix %2 4
- %4 = OpSpecConstant %1 1.0
- %5 = OpConstant %1 0.0
- %6 = OpSpecConstantComposite %2 %4 %5 %5 %5
- %7 = OpSpecConstantComposite %2 %5 %4 %5 %5
- %8 = OpSpecConstantComposite %2 %5 %5 %4 %5
- %10 = OpSpecConstantComposite %3 %6 %7 %8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> count does "
- "not match Result Type <id> '3[%mat4v4float]'s matrix column "
- "count.")));
- }
- // Invalid: Composite contains a non-const/undef component
- TEST_P(ValidateIdWithMessage,
- OpSpecConstantCompositeMatrixConstituentNotConstBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpConstant %1 0.0
- %3 = OpTypeVector %1 4
- %4 = OpTypeMatrix %3 4
- %5 = OpSpecConstantComposite %3 %2 %2 %2 %2
- %6 = OpTypePointer Uniform %1
- %7 = OpVariable %6 Uniform
- %8 = OpSpecConstantComposite %4 %5 %5 %5 %7)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '7[%7]' is "
- "not a constant or undef.")));
- }
- // Invalid: Composite contains a column that is *not* a vector (it's an array)
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeMatrixColTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeInt 32 0
- %3 = OpSpecConstant %2 4
- %4 = OpConstant %1 0.0
- %5 = OpTypeVector %1 4
- %6 = OpTypeArray %2 %3
- %7 = OpTypeMatrix %5 4
- %8 = OpSpecConstantComposite %6 %3 %3 %3 %3
- %9 = OpSpecConstantComposite %5 %4 %4 %4 %4
- %10 = OpSpecConstantComposite %7 %9 %9 %9 %8)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '8[%8]' type "
- "does not match Result Type <id> '7[%mat4v4float]'s "
- "matrix column type.")));
- }
- // Invalid: Matrix with an Undef column of the wrong size.
- TEST_P(ValidateIdWithMessage,
- OpSpecConstantCompositeMatrixConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeVector %1 4
- %3 = OpTypeVector %1 3
- %4 = OpTypeMatrix %2 4
- %5 = OpSpecConstant %1 1.0
- %6 = OpSpecConstant %1 0.0
- %7 = OpSpecConstantComposite %2 %5 %6 %6 %6
- %8 = OpSpecConstantComposite %2 %6 %5 %6 %6
- %9 = OpSpecConstantComposite %2 %6 %6 %5 %6
- %10 = OpUndef %3
- %11 = OpSpecConstantComposite %4 %7 %8 %9 %10)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '10[%10]' "
- "vector component count does not match Result Type "
- "<id> '4[%mat4v4float]'s vector component count.")));
- }
- // Invalid: Matrix in which some columns are Int and some are Float.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeMatrixColumnTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 32
- %3 = OpTypeVector %1 2
- %4 = OpTypeVector %2 2
- %5 = OpTypeMatrix %4 2
- %6 = OpSpecConstant %1 42
- %7 = OpConstant %2 3.14
- %8 = OpSpecConstantComposite %3 %6 %6
- %9 = OpSpecConstantComposite %4 %7 %7
- %10 = OpSpecConstantComposite %5 %8 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '8[%8]' "
- "component type does not match Result Type <id> "
- "'5[%mat2v2float]'s matrix column component type.")));
- }
- // Valid: Array of integers
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeArrayGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpSpecConstant %1 4
- %5 = OpConstant %1 5
- %3 = OpTypeArray %1 %2
- %6 = OpTypeArray %1 %5
- %4 = OpSpecConstantComposite %3 %2 %2 %2 %2
- %7 = OpSpecConstantComposite %3 %5 %5 %5 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Expecting an array of 4 components, but 3 specified.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeArrayNumComponentsBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpSpecConstantComposite %3 %2 %2 %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent count does not "
- "match Result Type <id> '3[%_arr_uint_uint_4]'s array "
- "length.")));
- }
- // Valid: Array of Integers and Undef-int
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeArrayWithUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpSpecConstant %1 4
- %9 = OpUndef %1
- %3 = OpTypeArray %1 %2
- %4 = OpSpecConstantComposite %3 %2 %2 %2 %9)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Array uses a type as operand.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeArrayConstConstituentBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpTypePointer Uniform %1
- %5 = OpVariable %4 Uniform
- %6 = OpSpecConstantComposite %3 %2 %2 %2 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '5[%5]' is "
- "not a constant or undef.")));
- }
- // Invalid: Array has a mix of Int and Float components.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeArrayConstituentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpConstant %1 4
- %3 = OpTypeArray %1 %2
- %4 = OpTypeFloat 32
- %5 = OpSpecConstant %4 3.14 ; bad type for const value
- %6 = OpSpecConstantComposite %3 %2 %2 %2 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '5[%5]'s "
- "type does not match Result Type <id> "
- "'3[%_arr_uint_uint_4]'s array element type.")));
- }
- // Invalid: Array has a mix of Int and Undef-float.
- TEST_P(ValidateIdWithMessage,
- OpSpecConstantCompositeArrayConstituentUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpSpecConstant %1 4
- %3 = OpTypeArray %1 %2
- %5 = OpTypeFloat 32
- %6 = OpUndef %5 ; bad type for undef
- %4 = OpSpecConstantComposite %3 %2 %2 %2 %6)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '5[%5]'s "
- "type does not match Result Type <id> "
- "'3[%_arr_uint_2]'s array element type.")));
- }
- // Valid: Struct of {Int32,Int32,Int64}.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeStructGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpSpecConstant %2 4300000000
- %6 = OpSpecConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: missing one int32 struct member.
- TEST_P(ValidateIdWithMessage,
- OpSpecConstantCompositeStructMissingComponentBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %3 = OpTypeStruct %1 %1 %1
- %4 = OpConstant %1 42
- %5 = OpSpecConstant %1 430
- %6 = OpSpecConstantComposite %3 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpSpecConstantComposite Constituent <id> "
- "'2[%_struct_2]' count does not match Result Type "
- "<id> '2[%_struct_2]'s struct member count.")));
- }
- // Valid: Struct uses Undef-int64.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeStructUndefGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpSpecConstant %1 42
- %5 = OpUndef %2
- %6 = OpSpecConstantComposite %3 %4 %4 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Composite contains non-const/undef component.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeStructNonConstBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpSpecConstant %1 42
- %5 = OpUndef %2
- %6 = OpTypePointer Uniform %1
- %7 = OpVariable %6 Uniform
- %8 = OpSpecConstantComposite %3 %4 %7 %5)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '7[%7]' is "
- "not a constant or undef.")));
- }
- // Invalid: Struct component type does not match expected specialization type.
- // Second component was expected to be Int32, but got Int64.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeStructMemberTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpConstant %1 42
- %5 = OpSpecConstant %2 4300000000
- %6 = OpSpecConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '5[%5]' type "
- "does not match the Result Type <id> '3[%_struct_3]'s "
- "member type.")));
- }
- // Invalid: Undef-int64 used when Int32 was expected.
- TEST_P(ValidateIdWithMessage, OpSpecConstantCompositeStructMemberUndefTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeInt 64 0
- %3 = OpTypeStruct %1 %1 %2
- %4 = OpSpecConstant %1 42
- %5 = OpUndef %2
- %6 = OpSpecConstantComposite %3 %4 %5 %4)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpSpecConstantComposite Constituent <id> '5[%5]' type "
- "does not match the Result Type <id> '3[%_struct_3]'s "
- "member type.")));
- }
- // TODO: OpSpecConstantOp
- TEST_P(ValidateIdWithMessage, OpVariableGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1
- %3 = OpVariable %2 Input)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableInitializerConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Output %1
- %3 = OpConstant %1 42
- %4 = OpVariable %2 Output %3)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableInitializerGlobalVariableGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Uniform %1
- %3 = OpVariable %2 Uniform
- %4 = OpTypePointer Private %2 ; pointer to pointer
- %5 = OpVariable %4 Private %3
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // TODO: Positive test OpVariable with OpConstantNull of OpTypePointer
- TEST_P(ValidateIdWithMessage, OpVariableResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpVariable %1 Input)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpVariable Result Type <id> '1[%uint]' is not a pointer "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypePointer Input %1
- %3 = OpVariable %2 Input %2)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '2[%_ptr_Input_uint]' "
- "cannot be a type")));
- }
- TEST_P(ValidateIdWithMessage, OpVariableInitializerIsFunctionVarBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ptrint = OpTypePointer Function %int
- %ptrptrint = OpTypePointer Function %ptrint
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %var = OpVariable %ptrint Function
- %varinit = OpVariable %ptrptrint Function %var ; Can't initialize function variable.
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Variable Initializer <id> '8[%8]' is not a constant "
- "or module-scope variable"));
- }
- TEST_P(ValidateIdWithMessage, OpVariableInitializerIsModuleVarGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ptrint = OpTypePointer Uniform %int
- %mvar = OpVariable %ptrint Uniform
- %ptrptrint = OpTypePointer Function %ptrint
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %goodvar = OpVariable %ptrptrint Function %mvar ; This is ok
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsBoolBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %bool %int
- %_ptr_Uniform_block = OpTypePointer Uniform %block
- %var = OpVariable %_ptr_Uniform_block Uniform
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %block %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "If OpTypeBool is stored in conjunction with OpVariable, it can only "
- "be used with non-externally visible shader Storage Classes: "
- "Workgroup, CrossWorkgroup, Private, Function, Input, Output, "
- "RayPayloadKHR, IncomingRayPayloadKHR, HitAttributeKHR, "
- "CallableDataKHR, IncomingCallableDataKHR, NodePayloadAMDX, or "
- "UniformConstant")));
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPrivateGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %bool %int
- %_ptr_Private_block = OpTypePointer Private %block
- %var = OpVariable %_ptr_Private_block Private
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %block %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsBoolUniformConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %bool %int
- %_ptr_UniformConstant_block = OpTypePointer UniformConstant %block
- %var = OpVariable %_ptr_UniformConstant_block UniformConstant
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %block %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPointerGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %boolptr = OpTypePointer Uniform %bool
- %int = OpTypeInt 32 0
- %block = OpTypeStruct %boolptr %int
- %_ptr_Uniform_block = OpTypePointer Uniform %block
- %var = OpVariable %_ptr_Uniform_block Uniform
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %block %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsBuiltinBoolGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %input 0 BuiltIn FrontFacing
- %bool = OpTypeBool
- %input = OpTypeStruct %bool
- %_ptr_input = OpTypePointer Input %input
- %var = OpVariable %_ptr_input Input
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %input %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsNoBuiltinBoolBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %bool = OpTypeBool
- %input = OpTypeStruct %bool
- %_ptr_input = OpTypePointer Input %input
- %var = OpVariable %_ptr_input Input
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %input %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "If OpTypeBool is stored in conjunction with OpVariable using Input "
- "or Output Storage Classes it requires a BuiltIn decoration")));
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsNoBuiltinBoolBadVulkan) {
- std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %var
- OpExecutionMode %main OriginUpperLeft
- %bool = OpTypeBool
- %input = OpTypeStruct %bool
- %_ptr_input = OpTypePointer Input %input
- %var = OpVariable %_ptr_input Input
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %input %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Input-07290"));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "If OpTypeBool is stored in conjunction with OpVariable using Input "
- "or Output Storage Classes it requires a BuiltIn decoration")));
- }
- TEST_P(ValidateIdWithMessage, OpVariableContainsRayPayloadBoolGood) {
- std::string spirv = R"(
- OpCapability RayTracingNV
- OpCapability Shader
- OpCapability Linkage
- OpExtension "SPV_NV_ray_tracing"
- OpMemoryModel Logical GLSL450
- %bool = OpTypeBool
- %PerRayData = OpTypeStruct %bool
- %_ptr_PerRayData = OpTypePointer RayPayloadNV %PerRayData
- %var = OpVariable %_ptr_PerRayData RayPayloadNV
- %void = OpTypeVoid
- %fnty = OpTypeFunction %void
- %main = OpFunction %void None %fnty
- %entry = OpLabel
- %load = OpLoad %PerRayData %var
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariablePointerNoVariablePointersBad) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "In Logical addressing, variables may not allocate a pointer type")));
- }
- TEST_P(ValidateIdWithMessage,
- OpVariablePointerNoVariablePointersRelaxedLogicalGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- auto options = getValidatorOptions();
- options->relax_logical_pointer = true;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpFunctionWithNonMemoryObject) {
- // DXC generates code that looks like when given something like:
- // T t;
- // t.s.fn_1();
- // This needs to be accepted before legalization takes place, so we
- // will include it with the relaxed logical pointer.
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main"
- OpSource HLSL 600
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %_struct_5 = OpTypeStruct
- %_struct_6 = OpTypeStruct %_struct_5
- %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
- %_ptr_Function__struct_5 = OpTypePointer Function %_struct_5
- %23 = OpTypeFunction %void %_ptr_Function__struct_5
- %1 = OpFunction %void None %9
- %10 = OpLabel
- %11 = OpVariable %_ptr_Function__struct_6 Function
- %20 = OpAccessChain %_ptr_Function__struct_5 %11 %int_0
- %21 = OpFunctionCall %void %12 %20
- OpReturn
- OpFunctionEnd
- %12 = OpFunction %void None %23
- %13 = OpFunctionParameter %_ptr_Function__struct_5
- %14 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- auto options = getValidatorOptions();
- options->relax_logical_pointer = true;
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage,
- OpVariablePointerVariablePointersStorageBufferGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VariablePointersStorageBuffer
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariablePointerVariablePointersGood) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VariablePointers
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_function_ptr = OpTypePointer Function %_ptr_workgroup_int
- %voidfn = OpTypeFunction %void
- %func = OpFunction %void None %voidfn
- %entry = OpLabel
- %var = OpVariable %_ptr_function_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVariablePointerVariablePointersBad) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability VariablePointers
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %_ptr_workgroup_int = OpTypePointer Workgroup %int
- %_ptr_uniform_ptr = OpTypePointer Uniform %_ptr_workgroup_int
- %var = OpVariable %_ptr_uniform_ptr Uniform
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "In Logical addressing with variable pointers, "
- "variables that allocate pointers must be in Function "
- "or Private storage classes")));
- }
- TEST_P(ValidateIdWithMessage, OpLoadGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpVariable %3 UniformConstant
- %6 = OpFunction %1 None %4
- %7 = OpLabel
- %8 = OpLoad %2 %5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // TODO: Add tests that exercise VariablePointersStorageBuffer instead of
- // VariablePointers.
- void createVariablePointerSpirvProgram(std::ostringstream* spirv,
- std::string result_strategy,
- bool use_varptr_cap,
- bool add_helper_function) {
- *spirv << "OpCapability Shader ";
- if (use_varptr_cap) {
- *spirv << "OpCapability VariablePointers ";
- *spirv << "OpExtension \"SPV_KHR_variable_pointers\" ";
- }
- *spirv << "OpExtension \"SPV_KHR_storage_buffer_storage_class\" ";
- *spirv << R"(
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- %void = OpTypeVoid
- %voidf = OpTypeFunction %void
- %bool = OpTypeBool
- %i32 = OpTypeInt 32 1
- %f32 = OpTypeFloat 32
- %f32ptr = OpTypePointer StorageBuffer %f32
- %i = OpConstant %i32 1
- %zero = OpConstant %i32 0
- %float_1 = OpConstant %f32 1.0
- %ptr1 = OpVariable %f32ptr StorageBuffer
- %ptr2 = OpVariable %f32ptr StorageBuffer
- )";
- if (add_helper_function) {
- *spirv << R"(
- ; ////////////////////////////////////////////////////////////
- ;;;; Function that returns a pointer
- ; ////////////////////////////////////////////////////////////
- %selector_func_type = OpTypeFunction %f32ptr %bool %f32ptr %f32ptr
- %choose_input_func = OpFunction %f32ptr None %selector_func_type
- %is_neg_param = OpFunctionParameter %bool
- %first_ptr_param = OpFunctionParameter %f32ptr
- %second_ptr_param = OpFunctionParameter %f32ptr
- %selector_func_begin = OpLabel
- %result_ptr = OpSelect %f32ptr %is_neg_param %first_ptr_param %second_ptr_param
- OpReturnValue %result_ptr
- OpFunctionEnd
- )";
- }
- *spirv << R"(
- %main = OpFunction %void None %voidf
- %label = OpLabel
- )";
- *spirv << result_strategy;
- *spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- }
- // With the VariablePointer Capability, OpLoad should allow loading a
- // VaiablePointer. In this test the variable pointer is obtained by an OpSelect
- TEST_P(ValidateIdWithMessage, OpLoadVarPtrOpSelectGood) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability? */,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Without the VariablePointers Capability, OpLoad will not allow loading
- // through a variable pointer.
- // Disabled since using OpSelect with pointers without VariablePointers will
- // fail LogicalsPass.
- TEST_P(ValidateIdWithMessage, DISABLED_OpLoadVarPtrOpSelectBad) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- false /* Add VariablePointers Capability?*/,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("is not a logical pointer.")));
- }
- // With the VariablePointer Capability, OpLoad should allow loading a
- // VaiablePointer. In this test the variable pointer is obtained by an OpPhi
- TEST_P(ValidateIdWithMessage, OpLoadVarPtrOpPhiGood) {
- std::string result_strategy = R"(
- %is_neg = OpSLessThan %bool %i %zero
- OpSelectionMerge %end_label None
- OpBranchConditional %is_neg %take_ptr_1 %take_ptr_2
- %take_ptr_1 = OpLabel
- OpBranch %end_label
- %take_ptr_2 = OpLabel
- OpBranch %end_label
- %end_label = OpLabel
- %varptr = OpPhi %f32ptr %ptr1 %take_ptr_1 %ptr2 %take_ptr_2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability?*/,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Without the VariablePointers Capability, OpPhi can have a pointer result
- // type.
- TEST_P(ValidateIdWithMessage, OpPhiBad) {
- std::string result_strategy = R"(
- %is_neg = OpSLessThan %bool %i %zero
- OpSelectionMerge %end_label None
- OpBranchConditional %is_neg %take_ptr_1 %take_ptr_2
- %take_ptr_1 = OpLabel
- OpBranch %end_label
- %take_ptr_2 = OpLabel
- OpBranch %end_label
- %end_label = OpLabel
- %varptr = OpPhi %f32ptr %ptr1 %take_ptr_1 %ptr2 %take_ptr_2
- %result = OpLoad %f32 %varptr
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- false /* Add VariablePointers Capability?*/,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Using pointers with OpPhi requires capability "
- "VariablePointers or VariablePointersStorageBuffer")));
- }
- // With the VariablePointer Capability, OpLoad should allow loading through a
- // VaiablePointer. In this test the variable pointer is obtained from an
- // OpFunctionCall (return value from a function)
- TEST_P(ValidateIdWithMessage, OpLoadVarPtrOpFunctionCallGood) {
- std::ostringstream spirv;
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpFunctionCall %f32ptr %choose_input_func %isneg %ptr1 %ptr2
- %result = OpLoad %f32 %varptr
- )";
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability?*/,
- true /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpLoadResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpVariable %3 UniformConstant
- %6 = OpFunction %1 None %4
- %7 = OpLabel
- %8 = OpLoad %3 %5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpLoad Result Type <id> "
- "'3[%_ptr_UniformConstant_uint]' does not match "
- "Pointer <id> '5[%5]'s type.")));
- }
- TEST_P(ValidateIdWithMessage, OpLoadPointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpFunction %1 None %4
- %6 = OpLabel
- %7 = OpLoad %2 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- // Prove that SSA checks trigger for a bad Id value.
- // The next test case show the not-a-logical-pointer case.
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '8[%8]' has not been "
- "defined")));
- }
- // Disabled as bitcasting type to object is now not valid.
- TEST_P(ValidateIdWithMessage, DISABLED_OpLoadLogicalPointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFloat 32
- %4 = OpTypePointer UniformConstant %2
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypeFunction %1
- %7 = OpFunction %1 None %6
- %8 = OpLabel
- %9 = OpBitcast %5 %4 ; Not valid in logical addressing
- %10 = OpLoad %3 %9 ; Should trigger message
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- // Once we start checking bitcasts, we might catch that
- // as the error first, instead of catching it here.
- // I don't know if it's possible to generate a bad case
- // if/when the validator is complete.
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpLoad Pointer <id> '9' is not a logical pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpStoreGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- OpStore %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpStorePointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %6 = OpVariable %3 UniformConstant
- %7 = OpConstant %2 0
- %8 = OpFunction %1 None %4
- %9 = OpLabel
- OpStore %7 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore Pointer <id> '7[%uint_0]' is not a logical "
- "pointer.")));
- }
- // Disabled as bitcasting type to object is now not valid.
- TEST_P(ValidateIdWithMessage, DISABLED_OpStoreLogicalPointerBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFloat 32
- %4 = OpTypePointer UniformConstant %2
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypeFunction %1
- %7 = OpConstantNull %5
- %8 = OpFunction %1 None %6
- %9 = OpLabel
- %10 = OpBitcast %5 %4 ; Not valid in logical addressing
- %11 = OpStore %10 %7 ; Should trigger message
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore Pointer <id> '10' is not a logical pointer.")));
- }
- // Without the VariablePointer Capability, OpStore should may not store
- // through a variable pointer.
- // Disabled since using OpSelect with pointers without VariablePointers will
- // fail LogicalsPass.
- TEST_P(ValidateIdWithMessage, DISABLED_OpStoreVarPtrBad) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- OpStore %varptr %float_1
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(
- &spirv, result_strategy, false /* Add VariablePointers Capability? */,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("is not a logical pointer.")));
- }
- // With the VariablePointer Capability, OpStore should allow storing through a
- // variable pointer.
- TEST_P(ValidateIdWithMessage, OpStoreVarPtrGood) {
- std::string result_strategy = R"(
- %isneg = OpSLessThan %bool %i %zero
- %varptr = OpSelect %f32ptr %isneg %ptr1 %ptr2
- OpStore %varptr %float_1
- )";
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv, result_strategy,
- true /* Add VariablePointers Capability? */,
- false /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpStoreObjectGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- %9 = OpFunctionCall %1 %10
- OpStore %6 %9
- OpReturn
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpStore Object <id> '9[%9]'s type is void.")));
- }
- TEST_P(ValidateIdWithMessage, OpStoreTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %9 = OpTypeFloat 32
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %9 3.14
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- OpStore %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore Pointer <id> '7[%7]'s type does not match "
- "Object <id> '6[%float_3_1400001]'s type.")));
- }
- // The next series of test check test a relaxation of the rules for stores to
- // structs. The first test checks that we get a failure when the option is not
- // set to relax the rule.
- // TODO: Add tests for layout compatible arrays and matricies when the validator
- // relaxes the rules for them as well. Also need test to check for layout
- // decorations specific to those types.
- TEST_P(ValidateIdWithMessage, OpStoreTypeBadStruct) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 4
- %3 = OpTypeVoid
- %4 = OpTypeFloat 32
- %1 = OpTypeStruct %4 %4
- %5 = OpTypePointer Uniform %1
- %2 = OpTypeStruct %4 %4
- %6 = OpTypeFunction %3
- %7 = OpConstant %4 3.14
- %8 = OpVariable %5 Uniform
- %9 = OpFunction %3 None %6
- %10 = OpLabel
- %11 = OpCompositeConstruct %2 %7 %7
- OpStore %8 %11
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore Pointer <id> '8[%8]'s type does not match "
- "Object <id> '11[%11]'s type.")));
- }
- // Same code as the last test. The difference is that we relax the rule.
- // Because the structs %3 and %5 are defined the same way.
- TEST_P(ValidateIdWithMessage, OpStoreTypeRelaxedStruct) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 4
- %3 = OpTypeVoid
- %4 = OpTypeFloat 32
- %1 = OpTypeStruct %4 %4
- %5 = OpTypePointer Uniform %1
- %2 = OpTypeStruct %4 %4
- %6 = OpTypeFunction %3
- %7 = OpConstant %4 3.14
- %8 = OpVariable %5 Uniform
- %9 = OpFunction %3 None %6
- %10 = OpLabel
- %11 = OpCompositeConstruct %2 %7 %7
- OpStore %8 %11
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Same code as the last test except for an extra decoration on one of the
- // members. With the relaxed rules, the code is still valid.
- TEST_P(ValidateIdWithMessage, OpStoreTypeRelaxedStructWithExtraDecoration) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %1 0 RelaxedPrecision
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 4
- %3 = OpTypeVoid
- %4 = OpTypeFloat 32
- %1 = OpTypeStruct %4 %4
- %5 = OpTypePointer Uniform %1
- %2 = OpTypeStruct %4 %4
- %6 = OpTypeFunction %3
- %7 = OpConstant %4 3.14
- %8 = OpVariable %5 Uniform
- %9 = OpFunction %3 None %6
- %10 = OpLabel
- %11 = OpCompositeConstruct %2 %7 %7
- OpStore %8 %11
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // This test check that we recursively traverse the struct to check if they are
- // interchangable.
- TEST_P(ValidateIdWithMessage, OpStoreTypeRelaxedNestedStruct) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 8
- OpMemberDecorate %3 0 Offset 0
- OpMemberDecorate %3 1 Offset 4
- OpMemberDecorate %4 0 Offset 0
- OpMemberDecorate %4 1 Offset 8
- %5 = OpTypeVoid
- %6 = OpTypeInt 32 0
- %7 = OpTypeFloat 32
- %1 = OpTypeStruct %7 %6
- %2 = OpTypeStruct %1 %1
- %8 = OpTypePointer Uniform %2
- %3 = OpTypeStruct %7 %6
- %4 = OpTypeStruct %3 %3
- %9 = OpTypeFunction %5
- %10 = OpConstant %6 7
- %11 = OpConstant %7 3.14
- %12 = OpConstantComposite %3 %11 %10
- %13 = OpVariable %8 Uniform
- %14 = OpFunction %5 None %9
- %15 = OpLabel
- %16 = OpCompositeConstruct %4 %12 %12
- OpStore %13 %16
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // This test check that the even with the relaxed rules an error is identified
- // if the members of the struct are in a different order.
- TEST_P(ValidateIdWithMessage, OpStoreTypeBadRelaxedStruct1) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 0
- OpMemberDecorate %1 1 Offset 4
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 8
- OpMemberDecorate %3 0 Offset 0
- OpMemberDecorate %3 1 Offset 4
- OpMemberDecorate %4 0 Offset 0
- OpMemberDecorate %4 1 Offset 8
- %5 = OpTypeVoid
- %6 = OpTypeInt 32 0
- %7 = OpTypeFloat 32
- %1 = OpTypeStruct %6 %7
- %2 = OpTypeStruct %1 %1
- %8 = OpTypePointer Uniform %2
- %3 = OpTypeStruct %7 %6
- %4 = OpTypeStruct %3 %3
- %9 = OpTypeFunction %5
- %10 = OpConstant %6 7
- %11 = OpConstant %7 3.14
- %12 = OpConstantComposite %3 %11 %10
- %13 = OpVariable %8 Uniform
- %14 = OpFunction %5 None %9
- %15 = OpLabel
- %16 = OpCompositeConstruct %4 %12 %12
- OpStore %13 %16
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore Pointer <id> '13[%13]'s layout does not match Object "
- "<id> '16[%16]'s layout.")));
- }
- // This test check that the even with the relaxed rules an error is identified
- // if the members of the struct are at different offsets.
- TEST_P(ValidateIdWithMessage, OpStoreTypeBadRelaxedStruct2) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpMemberDecorate %1 0 Offset 4
- OpMemberDecorate %1 1 Offset 0
- OpMemberDecorate %2 0 Offset 0
- OpMemberDecorate %2 1 Offset 8
- OpMemberDecorate %3 0 Offset 0
- OpMemberDecorate %3 1 Offset 4
- OpMemberDecorate %4 0 Offset 0
- OpMemberDecorate %4 1 Offset 8
- %5 = OpTypeVoid
- %6 = OpTypeInt 32 0
- %7 = OpTypeFloat 32
- %1 = OpTypeStruct %7 %6
- %2 = OpTypeStruct %1 %1
- %8 = OpTypePointer Uniform %2
- %3 = OpTypeStruct %7 %6
- %4 = OpTypeStruct %3 %3
- %9 = OpTypeFunction %5
- %10 = OpConstant %6 7
- %11 = OpConstant %7 3.14
- %12 = OpConstantComposite %3 %11 %10
- %13 = OpVariable %8 Uniform
- %14 = OpFunction %5 None %9
- %15 = OpLabel
- %16 = OpCompositeConstruct %4 %12 %12
- OpStore %13 %16
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxStoreStruct(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore Pointer <id> '13[%13]'s layout does not match Object "
- "<id> '16[%16]'s layout.")));
- }
- TEST_P(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerReturnPointer) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %1 = OpTypeInt 32 1
- %2 = OpTypePointer Function %1
- %3 = OpTypeFunction %2 %2
- %4 = OpFunction %2 None %3
- %5 = OpFunctionParameter %2
- %6 = OpLabel
- OpReturnValue %5
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerAllocPointer) {
- const std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 1
- %3 = OpTypeFunction %1 ; void(void)
- %4 = OpTypePointer Uniform %2 ; int*
- %5 = OpTypePointer Private %4 ; int** (Private)
- %6 = OpTypePointer Function %4 ; int** (Function)
- %7 = OpVariable %5 Private
- %8 = OpFunction %1 None %3
- %9 = OpLabel
- %10 = OpVariable %6 Function
- OpReturn
- OpFunctionEnd)";
- spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpStoreVoid) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- %9 = OpFunctionCall %1 %7
- OpStore %6 %9
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpStore Object <id> '8[%8]'s type is void.")));
- }
- TEST_P(ValidateIdWithMessage, OpStoreLabel) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1
- %6 = OpVariable %3 Uniform
- %7 = OpFunction %1 None %4
- %8 = OpLabel
- OpStore %6 %8
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '7[%7]' requires a type")));
- }
- // TODO: enable when this bug is fixed:
- // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
- TEST_P(ValidateIdWithMessage, DISABLED_OpStoreFunction) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypeFunction %2
- %5 = OpConstant %2 123
- %6 = OpVariable %3 UniformConstant
- %7 = OpFunction %2 None %4
- %8 = OpLabel
- OpStore %6 %7
- OpReturnValue %5
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpStoreBuiltin) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 450
- OpName %main "main"
- OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
- OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %v3uint = OpTypeVector %uint 3
- %_ptr_Input_v3uint = OpTypePointer Input %v3uint
- %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
- %zero = OpConstant %uint 0
- %v3uint_000 = OpConstantComposite %v3uint %zero %zero %zero
- %void = OpTypeVoid
- %voidfunc = OpTypeFunction %void
- %main = OpFunction %void None %voidfunc
- %lmain = OpLabel
- OpStore %gl_GlobalInvocationID %v3uint_000
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("storage class is read-only")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemoryGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpConstant %2 42
- %5 = OpVariable %3 UniformConstant %4
- %6 = OpTypePointer Function %2
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %6 Function
- OpCopyMemory %10 %5 None
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemoryNonPointerTarget) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1 %2 %3
- %5 = OpFunction %1 None %4
- %6 = OpFunctionParameter %2
- %7 = OpFunctionParameter %3
- %8 = OpLabel
- OpCopyMemory %6 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Target operand <id> '6[%6]' is not a pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemoryNonPointerSource) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpTypeFunction %1 %2 %3
- %5 = OpFunction %1 None %4
- %6 = OpFunctionParameter %2
- %7 = OpFunctionParameter %3
- %8 = OpLabel
- OpCopyMemory %7 %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Source operand <id> '6[%6]' is not a pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemoryBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpConstant %2 42
- %5 = OpVariable %3 UniformConstant %4
- %11 = OpTypeFloat 32
- %6 = OpTypePointer Function %11
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %6 Function
- OpCopyMemory %10 %5 None
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Target <id> '5[%5]'s type does not match "
- "Source <id> '2[%uint]'s type.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemoryVoidTarget) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFunction %1 %3 %4
- %6 = OpFunction %1 None %5
- %7 = OpFunctionParameter %3
- %8 = OpFunctionParameter %4
- %9 = OpLabel
- OpCopyMemory %7 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Target operand <id> '7[%7]' cannot be a void "
- "pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemoryVoidSource) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFunction %1 %3 %4
- %6 = OpFunction %1 None %5
- %7 = OpFunctionParameter %3
- %8 = OpFunctionParameter %4
- %9 = OpLabel
- OpCopyMemory %8 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Source operand <id> '7[%7]' cannot be a void "
- "pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %4 Function
- OpCopyMemorySized %10 %6 %5 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedTargetBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- OpCopyMemorySized %5 %5 %5 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Target operand <id> '5[%uint_4]' is not a pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSourceBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpTypeFunction %1
- %7 = OpFunction %1 None %6
- %8 = OpLabel
- %9 = OpVariable %4 Function
- OpCopyMemorySized %9 %5 %5 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Source operand <id> '5[%uint_4]' is not a pointer.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %4 Function
- OpCopyMemorySized %10 %6 %6 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Size operand <id> '6[%6]' must be a scalar integer type.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer UniformConstant %2
- %4 = OpTypePointer Function %2
- %5 = OpConstant %2 4
- %6 = OpVariable %3 UniformConstant %5
- %7 = OpTypeFunction %1
- %11 = OpTypeFloat 32
- %12 = OpConstant %11 1.0
- %8 = OpFunction %1 None %7
- %9 = OpLabel
- %10 = OpVariable %4 Function
- OpCopyMemorySized %10 %6 %12 None
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Size operand <id> '9[%float_1]' must be a scalar integer "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNull) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstantNull %2
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Size operand <id> '3[%3]' cannot be a constant "
- "zero.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantZero) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 0
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Size operand <id> '3[%uint_0]' cannot be a constant "
- "zero.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantZero64) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 64 0
- %3 = OpConstant %2 0
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Size operand <id> '3[%ulong_0]' cannot be a constant "
- "zero.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNegative) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 1
- %3 = OpConstant %2 -1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Size operand <id> '3[%int_n1]' cannot have the sign bit set "
- "to 1.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeConstantNegative64) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 64 1
- %3 = OpConstant %2 -1
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Size operand <id> '3[%long_n1]' cannot have the sign bit set "
- "to 1.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeUnsignedNegative) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 2147483648
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpCopyMemorySizedSizeUnsignedNegative64) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 64 0
- %3 = OpConstant %2 9223372036854775808
- %4 = OpTypePointer Uniform %2
- %5 = OpTypeFloat 32
- %6 = OpTypePointer UniformConstant %5
- %7 = OpTypeFunction %1 %4 %6
- %8 = OpFunction %1 None %7
- %9 = OpFunctionParameter %4
- %10 = OpFunctionParameter %6
- %11 = OpLabel
- OpCopyMemorySized %9 %10 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- const char kDeeplyNestedStructureSetup[] = R"(
- %void = OpTypeVoid
- %void_f = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %v3float = OpTypeVector %float 3
- %mat4x3 = OpTypeMatrix %v3float 4
- %_ptr_Private_mat4x3 = OpTypePointer Private %mat4x3
- %_ptr_Private_float = OpTypePointer Private %float
- %my_matrix = OpVariable %_ptr_Private_mat4x3 Private
- %my_float_var = OpVariable %_ptr_Private_float Private
- %_ptr_Function_float = OpTypePointer Function %float
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %int_2 = OpConstant %int 2
- %int_3 = OpConstant %int 3
- %int_5 = OpConstant %int 5
- ; Making the following nested structures.
- ;
- ; struct S {
- ; bool b;
- ; vec4 v[5];
- ; int i;
- ; mat4x3 m[5];
- ; }
- ; uniform blockName {
- ; S s;
- ; bool cond;
- ; RunTimeArray arr;
- ; }
- %f32arr = OpTypeRuntimeArray %float
- %v4float = OpTypeVector %float 4
- %array5_mat4x3 = OpTypeArray %mat4x3 %int_5
- %array5_vec4 = OpTypeArray %v4float %int_5
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_ptr_Function_vec4 = OpTypePointer Function %v4float
- %_ptr_Uniform_vec4 = OpTypePointer Uniform %v4float
- %struct_s = OpTypeStruct %int %array5_vec4 %int %array5_mat4x3
- %struct_blockName = OpTypeStruct %struct_s %int %f32arr
- %_ptr_Uniform_blockName = OpTypePointer Uniform %struct_blockName
- %_ptr_Uniform_struct_s = OpTypePointer Uniform %struct_s
- %_ptr_Uniform_array5_mat4x3 = OpTypePointer Uniform %array5_mat4x3
- %_ptr_Uniform_mat4x3 = OpTypePointer Uniform %mat4x3
- %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
- %blockName_var = OpVariable %_ptr_Uniform_blockName Uniform
- %spec_int = OpSpecConstant %int 2
- %float_0 = OpConstant %float 0
- %func = OpFunction %void None %void_f
- %my_label = OpLabel
- )";
- // In what follows, Access Chain Instruction refers to one of the following:
- // OpAccessChain, OpInBoundsAccessChain, OpPtrAccessChain, and
- // OpInBoundsPtrAccessChain
- using AccessChainInstructionTest = spvtest::ValidateBase<std::string>;
- // Determines whether the access chain instruction requires the 'element id'
- // argument.
- bool AccessChainRequiresElemId(const std::string& instr) {
- return (instr == "OpPtrAccessChain" || instr == "OpInBoundsPtrAccessChain");
- }
- // Valid: Access a float in a matrix using an access chain instruction.
- TEST_P(AccessChainInstructionTest, AccessChainGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup +
- "%float_entry = " + instr +
- R"( %_ptr_Private_float %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid. The result type of an access chain instruction must be a pointer.
- TEST_P(AccessChainInstructionTest, AccessChainResultTypeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %float_entry = )" +
- instr +
- R"( %float %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "The Result Type of " + instr +
- " <id> '36[%36]' must be "
- "OpTypePointer. Found OpTypeFloat.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid. The base type of an access chain instruction must be a pointer.
- TEST_P(AccessChainInstructionTest, AccessChainBaseTypeVoidBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %float_entry = )" +
- instr + " %_ptr_Private_float %void " + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand '1[%void]' cannot be a "
- "type"));
- }
- // Invalid. The base type of an access chain instruction must be a pointer.
- TEST_P(AccessChainInstructionTest, AccessChainBaseTypeNonPtrVariableBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %_ptr_Private_float )" +
- elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Operand '8[%_ptr_Private_float]' cannot be a type"));
- }
- // Invalid: The storage class of Base and Result do not match.
- TEST_P(AccessChainInstructionTest,
- AccessChainResultAndBaseStorageClassDoesntMatchBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Function_float %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- "The result pointer storage class and base pointer storage class in " +
- instr + " do not match.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid. The base type of an access chain instruction must point to a
- // composite object.
- TEST_P(AccessChainInstructionTest,
- AccessChainBasePtrNotPointingToCompositeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_float_var )" + elem +
- R"(%int_0
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " reached non-composite type while "
- "indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Valid. No Indexes were passed to the access chain instruction. The Result
- // Type is the same as the Base type.
- TEST_P(AccessChainInstructionTest, AccessChainNoIndexesGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_float_var )" + elem +
- R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid. No Indexes were passed to the access chain instruction, but the
- // Result Type is different from the Base type.
- TEST_P(AccessChainInstructionTest, AccessChainNoIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_mat4x3 %my_float_var )" + elem +
- R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("result type (OpTypeMatrix) does not match the type that "
- "results from indexing into the base <id> (OpTypeFloat)."));
- }
- // Valid: 255 indexes passed to the access chain instruction. Limit is 255.
- TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- const std::string arrayStride =
- " OpDecorate %_ptr_Uniform_deep_struct ArrayStride 8 ";
- int depth = 255;
- std::string header =
- kGLSL450MemoryModel + arrayStride + kDeeplyNestedStructureSetup;
- header.erase(header.find("%func"));
- std::ostringstream spirv;
- spirv << header << "\n";
- // Build nested structures. Struct 'i' contains struct 'i-1'
- spirv << "%s_depth_1 = OpTypeStruct %float\n";
- for (int i = 2; i <= depth; ++i) {
- spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n";
- }
- // Define Pointer and Variable to use for the AccessChain instruction.
- spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_"
- << depth << "\n";
- spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n";
- // Function Start
- spirv << R"(
- %func = OpFunction %void None %void_f
- %my_label = OpLabel
- )";
- // AccessChain with 'n' indexes (n = depth)
- spirv << "%entry = " << instr << " %_ptr_Uniform_float %deep_var" << elem;
- for (int i = 0; i < depth; ++i) {
- spirv << " %int_0";
- }
- // Function end
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: 256 indexes passed to the access chain instruction. Limit is 255.
- TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup;
- spirv << "%entry = " << instr << " %_ptr_Private_float %my_matrix" << elem;
- for (int i = 0; i < 256; ++i) {
- spirv << " %int_0";
- }
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "The number of indexes in " + instr +
- " may not exceed 255. Found 256 indexes.";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Valid: 10 indexes passed to the access chain instruction. (Custom limit: 10)
- TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- const std::string arrayStride =
- " OpDecorate %_ptr_Uniform_deep_struct ArrayStride 8 ";
- int depth = 10;
- std::string header =
- kGLSL450MemoryModel + arrayStride + kDeeplyNestedStructureSetup;
- header.erase(header.find("%func"));
- std::ostringstream spirv;
- spirv << header << "\n";
- // Build nested structures. Struct 'i' contains struct 'i-1'
- spirv << "%s_depth_1 = OpTypeStruct %float\n";
- for (int i = 2; i <= depth; ++i) {
- spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n";
- }
- // Define Pointer and Variable to use for the AccessChain instruction.
- spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_"
- << depth << "\n";
- spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n";
- // Function Start
- spirv << R"(
- %func = OpFunction %void None %void_f
- %my_label = OpLabel
- )";
- // AccessChain with 'n' indexes (n = depth)
- spirv << "%entry = " << instr << " %_ptr_Uniform_float %deep_var" << elem;
- for (int i = 0; i < depth; ++i) {
- spirv << " %int_0";
- }
- // Function end
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- spvValidatorOptionsSetUniversalLimit(
- options_, spv_validator_limit_max_access_chain_indexes, 10u);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: 11 indexes passed to the access chain instruction. Custom Limit:10
- TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : "";
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup;
- spirv << "%entry = " << instr << " %_ptr_Private_float %my_matrix" << elem;
- for (int i = 0; i < 11; ++i) {
- spirv << " %int_0";
- }
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "The number of indexes in " + instr +
- " may not exceed 10. Found 11 indexes.";
- spvValidatorOptionsSetUniversalLimit(
- options_, spv_validator_limit_max_access_chain_indexes, 10u);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Index passed to the access chain instruction is float (must be
- // integer).
- TEST_P(AccessChainInstructionTest, AccessChainUndefinedIndexBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_matrix )" + elem +
- R"(%float_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- "Indexes passed to " + instr + " must be of type integer.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: The index argument that indexes into a struct must be of type
- // OpConstant.
- TEST_P(AccessChainInstructionTest, AccessChainStructIndexNotConstantBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %f = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_0 %spec_int %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr("The <id> passed to " + instr));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("into a structure must be an OpConstant"));
- }
- // Invalid: Indexing up to a vec4 granularity, but result type expected float.
- TEST_P(AccessChainInstructionTest,
- AccessChainStructResultTypeDoesntMatchIndexedTypeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_0 %int_1 %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " result type (OpTypeFloat) does not match "
- "the type that results from indexing into "
- "the base <id> (OpTypeVector).";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Reach non-composite type (bool) when unused indexes remain.
- TEST_P(AccessChainInstructionTest, AccessChainStructTooManyIndexesBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_0 %int_2 %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " reached non-composite type while "
- "indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Trying to find index 3 of the struct that has only 3 members.
- TEST_P(AccessChainInstructionTest, AccessChainStructIndexOutOfBoundBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_3 %int_2 %int_2
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = "is out of bounds: " + instr +
- " cannot find index 3 into the structure "
- "<id> '25[%_struct_25]'. This structure "
- "has 3 members. Largest valid index is 2.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Valid: Tests that we can index into Struct, Array, Matrix, and Vector!
- TEST_P(AccessChainInstructionTest, AccessChainIndexIntoAllTypesGood) {
- // indexes that we are passing are: 0, 3, 1, 2, 0
- // 0 will select the struct_s within the base struct (blockName)
- // 3 will select the Array that contains 5 matrices
- // 1 will select the Matrix that is at index 1 of the array
- // 2 will select the column (which is a vector) within the matrix at index 2
- // 0 will select the element at the index 0 of the vector. (which is a float).
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- const std::string arrayStride =
- " OpDecorate %_ptr_Uniform_blockName ArrayStride 8 ";
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << arrayStride << kDeeplyNestedStructureSetup
- << std::endl;
- spirv << "%ss = " << instr << " %_ptr_Uniform_struct_s %blockName_var "
- << elem << "%int_0" << std::endl;
- spirv << "%sa = " << instr << " %_ptr_Uniform_array5_mat4x3 %blockName_var "
- << elem << "%int_0 %int_3" << std::endl;
- spirv << "%sm = " << instr << " %_ptr_Uniform_mat4x3 %blockName_var " << elem
- << "%int_0 %int_3 %int_1" << std::endl;
- spirv << "%sc = " << instr << " %_ptr_Uniform_v3float %blockName_var " << elem
- << "%int_0 %int_3 %int_1 %int_2" << std::endl;
- spirv << "%entry = " << instr << " %_ptr_Uniform_float %blockName_var "
- << elem << "%int_0 %int_3 %int_1 %int_2 %int_0" << std::endl;
- spirv << R"(
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Access an element of OpTypeRuntimeArray.
- TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayGood) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- const std::string arrayStride =
- " OpDecorate %_ptr_Uniform_blockName ArrayStride 8 ";
- std::string spirv = kGLSL450MemoryModel + arrayStride +
- kDeeplyNestedStructureSetup + R"(
- %runtime_arr_entry = )" + instr +
- R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_2 %int_0
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: Unused index when accessing OpTypeRuntimeArray.
- TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %runtime_arr_entry = )" +
- instr + R"( %_ptr_Uniform_float %blockName_var )" + elem +
- R"(%int_2 %int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err =
- instr +
- " reached non-composite type while indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: Reached scalar type before arguments to the access chain instruction
- // finished.
- TEST_P(AccessChainInstructionTest, AccessChainMatrixMoreArgsThanNeededBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_float %my_matrix )" + elem +
- R"(%int_0 %int_1 %int_0
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " reached non-composite type while "
- "indexes still remain to be traversed.";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Invalid: The result type and the type indexed into do not match.
- TEST_P(AccessChainInstructionTest,
- AccessChainResultTypeDoesntMatchIndexedTypeBad) {
- const std::string instr = GetParam();
- const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : "";
- std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"(
- %entry = )" +
- instr + R"( %_ptr_Private_mat4x3 %my_matrix )" + elem +
- R"(%int_0 %int_1
- OpReturn
- OpFunctionEnd
- )";
- const std::string expected_err = instr +
- " result type (OpTypeMatrix) does not match "
- "the type that results from indexing into "
- "the base <id> (OpTypeFloat).";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(), HasSubstr(expected_err));
- }
- // Run tests for Access Chain Instructions.
- INSTANTIATE_TEST_SUITE_P(
- CheckAccessChainInstructions, AccessChainInstructionTest,
- ::testing::Values("OpAccessChain", "OpInBoundsAccessChain",
- "OpPtrAccessChain", "OpInBoundsPtrAccessChain"));
- // TODO: OpArrayLength
- // TODO: OpImagePointer
- // TODO: OpGenericPtrMemSemantics
- TEST_P(ValidateIdWithMessage, OpFunctionGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2 %2
- %4 = OpFunction %1 None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpFunctionResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpConstant %2 42
- %4 = OpTypeFunction %1 %2 %2
- %5 = OpFunction %2 None %4
- %6 = OpLabel
- OpReturnValue %3
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpFunction Result Type <id> '2[%uint]' does not "
- "match the Function Type's return type <id> "
- "'1[%void]'.")));
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeInt 32 0
- %2 = OpTypeFloat 32
- %3 = OpConstant %2 0
- %4 = OpTypeFunction %1
- %5 = OpFunction %1 None %4
- %6 = OpLabel
- OpReturnValue %3
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpReturnValue Value <id> '3[%float_0]'s type does "
- "not match OpFunction's return type.")));
- }
- TEST_P(ValidateIdWithMessage, OpFunctionFunctionTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %4 = OpFunction %1 None %2
- %5 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpFunction Function Type <id> '2[%uint]' is not a function "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpFunctionUseBad) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeFloat 32
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- OpReturnValue %3
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Invalid use of function result id '3[%3]'.")));
- }
- TEST_P(ValidateIdWithMessage, OpFunctionParameterGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2
- %4 = OpFunction %1 None %3
- %5 = OpFunctionParameter %2
- %6 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpFunctionParameterMultipleGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2 %2
- %4 = OpFunction %1 None %3
- %5 = OpFunctionParameter %2
- %6 = OpFunctionParameter %2
- %7 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpFunctionParameterResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1 %2
- %4 = OpFunction %1 None %3
- %5 = OpFunctionParameter %1
- %6 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "OpFunctionParameter Result Type <id> '1[%void]' does not "
- "match the OpTypeFunction parameter type of the same index.")));
- }
- TEST_P(ValidateIdWithMessage, OpFunctionCallGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- OpReturnValue %7
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %2 %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpFunctionCallResultTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- %9 = OpIAdd %2 %7 %7
- OpReturnValue %9
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %1 %6 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpFunctionCall Result Type <id> '1[%void]'s type "
- "does not match Function <id> '2[%uint]'s return "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpFunctionCallFunctionBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %2 %5 %5
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpFunctionCall Function <id> '5[%uint_42]' is not a "
- "function.")));
- }
- TEST_P(ValidateIdWithMessage, OpFunctionCallArgumentTypeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42
- %13 = OpTypeFloat 32
- %14 = OpConstant %13 3.14
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- %9 = OpIAdd %2 %7 %7
- OpReturnValue %9
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- %12 = OpFunctionCall %2 %6 %14
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpFunctionCall Argument <id> '7[%float_3_1400001]'s "
- "type does not match Function <id> '2[%uint]'s "
- "parameter type.")));
- }
- // Valid: OpSampledImage result <id> is used in the same block by
- // OpImageSampleImplictLod
- TEST_P(ValidateIdWithMessage, OpSampledImageGood) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- %si_lod = OpImageSampleImplicitLod %v4float %smpld_img %const_vec_1_1
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Invalid: OpSampledImage result <id> is defined in one block and used in a
- // different block.
- TEST_P(ValidateIdWithMessage, OpSampledImageUsedInDifferentBlockBad) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- OpBranch %label_2
- %label_2 = OpLabel
- %si_lod = OpImageSampleImplicitLod %v4float %smpld_img %const_vec_1_1
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "All OpSampledImage instructions must be in the same block in "
- "which their Result <id> are consumed. OpSampledImage Result "
- "Type <id> '23[%23]' has a consumer in a different basic "
- "block. The consumer instruction <id> is '25[%25]'.")));
- }
- // Invalid: OpSampledImage result <id> is used by OpSelect
- // Note: According to the Spec, OpSelect parameters must be either a scalar or a
- // vector. Therefore, OpTypeSampledImage is an illegal parameter for OpSelect.
- // However, the OpSelect validation does not catch this today. Therefore, it is
- // caught by the OpSampledImage validation. If the OpSelect validation code is
- // updated, the error message for this test may change.
- //
- // Disabled since OpSelect catches this now.
- TEST_P(ValidateIdWithMessage, DISABLED_OpSampledImageUsedInOpSelectBad) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- %select_img = OpSelect %sampled_image_type %spec_true %smpld_img %smpld_img
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Result <id> from OpSampledImage instruction must not "
- "appear as operands of OpSelect. Found result <id> "
- "'23' as an operand of <id> '24'.")));
- }
- TEST_P(ValidateIdWithMessage, OpCopyObjectSampledImageGood) {
- std::string spirv = kGLSL450MemoryModel + sampledImageSetup + R"(
- %smpld_img = OpSampledImage %sampled_image_type %image_inst %sampler_inst
- %smpld_img2 = OpCopyObject %sampled_image_type %smpld_img
- %image_inst2 = OpCopyObject %image_type %image_inst
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Valid: Get a float in a matrix using CompositeExtract.
- // Valid: Insert float into a matrix using CompositeInsert.
- TEST_P(ValidateIdWithMessage, CompositeExtractInsertGood) {
- std::ostringstream spirv;
- spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup << std::endl;
- spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl;
- spirv << "%float_entry = OpCompositeExtract %float %matrix 0 1" << std::endl;
- // To test CompositeInsert, insert the object back in after extraction.
- spirv << "%new_composite = OpCompositeInsert %mat4x3 %float_entry %matrix 0 1"
- << std::endl;
- spirv << R"(OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- #if 0
- TEST_P(ValidateIdWithMessage, OpFunctionCallArgumentCountBar) {
- const char *spirv = R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2 %2
- %4 = OpTypeFunction %1
- %5 = OpConstant %2 42 ;21
- %6 = OpFunction %2 None %3
- %7 = OpFunctionParameter %2
- %8 = OpLabel
- %9 = OpLoad %2 %7
- OpReturnValue %9
- OpFunctionEnd
- %10 = OpFunction %1 None %4
- %11 = OpLabel
- OpReturn
- %12 = OpFunctionCall %2 %6 %5
- OpFunctionEnd)";
- CHECK(spirv, SPV_ERROR_INVALID_ID);
- }
- #endif
- // TODO: The many things that changed with how images are used.
- // TODO: OpTextureSample
- // TODO: OpTextureSampleDref
- // TODO: OpTextureSampleLod
- // TODO: OpTextureSampleProj
- // TODO: OpTextureSampleGrad
- // TODO: OpTextureSampleOffset
- // TODO: OpTextureSampleProjLod
- // TODO: OpTextureSampleProjGrad
- // TODO: OpTextureSampleLodOffset
- // TODO: OpTextureSampleProjOffset
- // TODO: OpTextureSampleGradOffset
- // TODO: OpTextureSampleProjLodOffset
- // TODO: OpTextureSampleProjGradOffset
- // TODO: OpTextureFetchTexelLod
- // TODO: OpTextureFetchTexelOffset
- // TODO: OpTextureFetchSample
- // TODO: OpTextureFetchTexel
- // TODO: OpTextureGather
- // TODO: OpTextureGatherOffset
- // TODO: OpTextureGatherOffsets
- // TODO: OpTextureQuerySizeLod
- // TODO: OpTextureQuerySize
- // TODO: OpTextureQueryLevels
- // TODO: OpTextureQuerySamples
- // TODO: OpConvertUToF
- // TODO: OpConvertFToS
- // TODO: OpConvertSToF
- // TODO: OpConvertUToF
- // TODO: OpUConvert
- // TODO: OpSConvert
- // TODO: OpFConvert
- // TODO: OpConvertPtrToU
- // TODO: OpConvertUToPtr
- // TODO: OpPtrCastToGeneric
- // TODO: OpGenericCastToPtr
- // TODO: OpBitcast
- // TODO: OpGenericCastToPtrExplicit
- // TODO: OpSatConvertSToU
- // TODO: OpSatConvertUToS
- // TODO: OpVectorExtractDynamic
- // TODO: OpVectorInsertDynamic
- TEST_P(ValidateIdWithMessage, OpVectorShuffleIntGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ivec4 = OpTypeVector %int 4
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %undef = OpUndef %ivec4
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpTypeFunction %ivec3
- %3 = OpFunction %ivec3 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %5 = OpLoad %ivec3 %var
- %6 = OpVectorShuffle %ivec3 %5 %undef 2 1 0
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleFloatGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec2 = OpTypePointer Function %vec2
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %vec2 %float_2 %float_1
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_vec2 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %vec2 %var
- %7 = OpLoad %vec3 %var2
- %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0xffffffff
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleScalarResultType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %ptr_vec2 = OpTypePointer Function %vec2
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %vec2 %float_2 %float_1
- %2 = OpTypeFunction %float
- %3 = OpFunction %float None %2
- %4 = OpLabel
- %var = OpVariable %ptr_vec2 Function %1
- %5 = OpLoad %vec2 %var
- %6 = OpVectorShuffle %float %5 %5 0
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Result Type of OpVectorShuffle must be OpTypeVector.")));
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleComponentCount) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpTypeFunction %ivec3
- %3 = OpFunction %ivec3 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %5 = OpLoad %ivec3 %var
- %6 = OpVectorShuffle %ivec3 %5 %5 0 1
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpVectorShuffle component literals count does not match "
- "Result Type <id> '2[%v3uint]'s vector component count.")));
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleVector1Type) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec2 = OpTypeVector %int 2
- %ptr_int = OpTypePointer Function %int
- %undef = OpUndef %ivec2
- %int_42 = OpConstant %int 42
- %2 = OpTypeFunction %ivec2
- %3 = OpFunction %ivec2 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_int Function %int_42
- %5 = OpLoad %int %var
- %6 = OpVectorShuffle %ivec2 %5 %undef 0 0
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("The type of Vector 1 must be OpTypeVector.")));
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleVector2Type) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec2 = OpTypeVector %int 2
- %ptr_ivec2 = OpTypePointer Function %ivec2
- %undef = OpUndef %int
- %int_42 = OpConstant %int 42
- %1 = OpConstantComposite %ivec2 %int_42 %int_42
- %2 = OpTypeFunction %ivec2
- %3 = OpFunction %ivec2 None %2
- %4 = OpLabel
- %var = OpVariable %ptr_ivec2 Function %1
- %5 = OpLoad %ivec2 %var
- %6 = OpVectorShuffle %ivec2 %5 %undef 0 1
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("The type of Vector 2 must be OpTypeVector.")));
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleVector1ComponentType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %ivec3 %var
- %7 = OpLoad %vec3 %var2
- %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "The Component Type of Vector 1 must be the same as "
- "ResultType.")));
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleVector2ComponentType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %int = OpTypeInt 32 0
- %ivec3 = OpTypeVector %int 3
- %ptr_ivec3 = OpTypePointer Function %ivec3
- %int_42 = OpConstant %int 42
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %float = OpTypeFloat 32
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %ivec3 %int_42 %int_0 %int_2
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_ivec3 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %vec3 %var2
- %7 = OpLoad %ivec3 %var
- %8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "The Component Type of Vector 2 must be the same as "
- "ResultType.")));
- }
- TEST_P(ValidateIdWithMessage, OpVectorShuffleLiterals) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %float = OpTypeFloat 32
- %vec2 = OpTypeVector %float 2
- %vec3 = OpTypeVector %float 3
- %vec4 = OpTypeVector %float 4
- %ptr_vec2 = OpTypePointer Function %vec2
- %ptr_vec3 = OpTypePointer Function %vec3
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %1 = OpConstantComposite %vec2 %float_2 %float_1
- %2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
- %3 = OpTypeFunction %vec4
- %4 = OpFunction %vec4 None %3
- %5 = OpLabel
- %var = OpVariable %ptr_vec2 Function %1
- %var2 = OpVariable %ptr_vec3 Function %2
- %6 = OpLoad %vec2 %var
- %7 = OpLoad %vec3 %var2
- %8 = OpVectorShuffle %vec4 %6 %7 0 8 2 6
- OpReturnValue %8
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Component index 8 is out of bounds for combined (Vector1 + Vector2) "
- "size of 5.")));
- }
- // TODO: OpCompositeConstruct
- // TODO: OpCompositeExtract
- // TODO: OpCompositeInsert
- // TODO: OpCopyObject
- // TODO: OpTranspose
- // TODO: OpSNegate
- // TODO: OpFNegate
- // TODO: OpNot
- // TODO: OpIAdd
- // TODO: OpFAdd
- // TODO: OpISub
- // TODO: OpFSub
- // TODO: OpIMul
- // TODO: OpFMul
- // TODO: OpUDiv
- // TODO: OpSDiv
- // TODO: OpFDiv
- // TODO: OpUMod
- // TODO: OpSRem
- // TODO: OpSMod
- // TODO: OpFRem
- // TODO: OpFMod
- // TODO: OpVectorTimesScalar
- // TODO: OpMatrixTimesScalar
- // TODO: OpVectorTimesMatrix
- // TODO: OpMatrixTimesVector
- // TODO: OpMatrixTimesMatrix
- // TODO: OpOuterProduct
- // TODO: OpDot
- // TODO: OpShiftRightLogical
- // TODO: OpShiftRightArithmetic
- // TODO: OpShiftLeftLogical
- // TODO: OpBitwiseOr
- // TODO: OpBitwiseXor
- // TODO: OpBitwiseAnd
- // TODO: OpAny
- // TODO: OpAll
- // TODO: OpIsNan
- // TODO: OpIsInf
- // TODO: OpIsFinite
- // TODO: OpIsNormal
- // TODO: OpSignBitSet
- // TODO: OpLessOrGreater
- // TODO: OpOrdered
- // TODO: OpUnordered
- // TODO: OpLogicalOr
- // TODO: OpLogicalXor
- // TODO: OpLogicalAnd
- // TODO: OpSelect
- // TODO: OpIEqual
- // TODO: OpFOrdEqual
- // TODO: OpFUnordEqual
- // TODO: OpINotEqual
- // TODO: OpFOrdNotEqual
- // TODO: OpFUnordNotEqual
- // TODO: OpULessThan
- // TODO: OpSLessThan
- // TODO: OpFOrdLessThan
- // TODO: OpFUnordLessThan
- // TODO: OpUGreaterThan
- // TODO: OpSGreaterThan
- // TODO: OpFOrdGreaterThan
- // TODO: OpFUnordGreaterThan
- // TODO: OpULessThanEqual
- // TODO: OpSLessThanEqual
- // TODO: OpFOrdLessThanEqual
- // TODO: OpFUnordLessThanEqual
- // TODO: OpUGreaterThanEqual
- // TODO: OpSGreaterThanEqual
- // TODO: OpFOrdGreaterThanEqual
- // TODO: OpFUnordGreaterThanEqual
- // TODO: OpDPdx
- // TODO: OpDPdy
- // TODO: OpFWidth
- // TODO: OpDPdxFine
- // TODO: OpDPdyFine
- // TODO: OpFwidthFine
- // TODO: OpDPdxCoarse
- // TODO: OpDPdyCoarse
- // TODO: OpFwidthCoarse
- // TODO: OpLoopMerge
- // TODO: OpSelectionMerge
- // TODO: OpBranch
- TEST_P(ValidateIdWithMessage, OpPhiNotAType) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %9 = OpPhi %3 %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '3[%true]' is not a type "
- "id")));
- }
- TEST_P(ValidateIdWithMessage, OpPhiSamePredecessor) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranchConditional %3 %8 %8
- %8 = OpLabel
- %9 = OpPhi %2 %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpPhiOddArgumentNumber) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %9 = OpPhi %2 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpPhi does not have an equal number of incoming "
- "values and basic blocks.")));
- }
- TEST_P(ValidateIdWithMessage, OpPhiTooFewPredecessors) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %9 = OpPhi %2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpPhi's number of incoming blocks (0) does not match "
- "block's predecessor count (1).")));
- }
- TEST_P(ValidateIdWithMessage, OpPhiTooManyPredecessors) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranch %8
- %9 = OpLabel
- OpReturn
- %8 = OpLabel
- %10 = OpPhi %2 %3 %7 %3 %9
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpPhi's number of incoming blocks (2) does not match "
- "block's predecessor count (1).")));
- }
- TEST_P(ValidateIdWithMessage, OpPhiMismatchedTypes) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeInt 32 0
- %6 = OpConstant %5 0
- %7 = OpTypeFunction %4
- %8 = OpFunction %4 None %7
- %9 = OpLabel
- OpBranchConditional %3 %10 %11
- %11 = OpLabel
- OpBranch %10
- %10 = OpLabel
- %12 = OpPhi %2 %3 %9 %6 %11
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpPhi's result type <id> '2[%bool]' does not match "
- "incoming value <id> '6[%uint_0]' type <id> "
- "'5[%uint]'.")));
- }
- TEST_P(ValidateIdWithMessage, OpPhiPredecessorNotABlock) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranchConditional %3 %8 %9
- %9 = OpLabel
- OpBranch %11
- %11 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %10 = OpPhi %2 %3 %7 %3 %3
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpPhi's incoming basic block <id> '3[%true]' is not an "
- "OpLabel.")));
- }
- TEST_P(ValidateIdWithMessage, OpPhiNotAPredecessor) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- %2 = OpTypeBool
- %3 = OpConstantTrue %2
- %4 = OpTypeVoid
- %5 = OpTypeFunction %4
- %6 = OpFunction %4 None %5
- %7 = OpLabel
- OpBranchConditional %3 %8 %9
- %9 = OpLabel
- OpBranch %11
- %11 = OpLabel
- OpBranch %8
- %8 = OpLabel
- %10 = OpPhi %2 %3 %7 %3 %9
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpPhi's incoming basic block <id> '9[%9]' is not a "
- "predecessor of <id> '8[%8]'.")));
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditionalGood) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditionalWithWeightsGood) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f 1 1
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditional_CondIsScalarInt) {
- std::string spirv = BranchConditionalSetup + R"(
- OpSelectionMerge %end None
- OpBranchConditional %i0 %target_t %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Condition operand for OpBranchConditional must "
- "be of boolean type")));
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditional_TrueTargetIsNotLabel) {
- std::string spirv = BranchConditionalSetup + R"(
- OpSelectionMerge %end None
- OpBranchConditional %true %i0 %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "The 'True Label' operand for OpBranchConditional must "
- "be the ID of an OpLabel instruction")));
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditional_FalseTargetIsNotLabel) {
- std::string spirv = BranchConditionalSetup + R"(
- OpSelectionMerge %end None
- OpBranchConditional %true %target_t %i0
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "The 'False Label' operand for OpBranchConditional "
- "must be the ID of an OpLabel instruction")));
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditional_NotEnoughWeights) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f 1
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpBranchConditional requires either 3 or 5 parameters")));
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditional_TooManyWeights) {
- std::string spirv = BranchConditionalSetup + R"(
- %branch_cond = OpINotEqual %bool %i0 %i1
- OpSelectionMerge %end None
- OpBranchConditional %branch_cond %target_t %target_f 1 2 3
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpBranchConditional requires either 3 or 5 parameters")));
- }
- TEST_P(ValidateIdWithMessage, OpBranchConditional_ConditionIsAType) {
- std::string spirv = BranchConditionalSetup + R"(
- OpBranchConditional %bool %target_t %target_f
- )" + BranchConditionalTail;
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '3[%bool]' cannot be a "
- "type")));
- }
- // TODO: OpSwitch
- TEST_P(ValidateIdWithMessage, OpReturnValueConstantGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %4 = OpConstant %2 42
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %4
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueVariableGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0 ;10
- %3 = OpTypeFunction %2
- %8 = OpTypePointer Function %2 ;18
- %4 = OpConstant %2 42 ;22
- %5 = OpFunction %2 None %3 ;27
- %6 = OpLabel ;29
- %7 = OpVariable %8 Function %4 ;34
- %9 = OpLoad %2 %7
- OpReturnValue %9 ;36
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueExpressionGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %4 = OpConstant %2 42
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- %7 = OpIAdd %2 %4 %4
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueIsType) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %1
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '1[%void]' cannot be a "
- "type")));
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueIsLabel) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %6
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '5[%5]' requires a type")));
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueIsVoid) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %1
- %5 = OpFunction %1 None %3
- %6 = OpLabel
- %7 = OpFunctionCall %1 %5
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpReturnValue value's type <id> '1[%void]' is missing or "
- "void.")));
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueIsVariableInPhysical) {
- // It's valid to return a pointer in a physical addressing model.
- std::string spirv = kOpCapabilitySetup + R"(
- OpMemoryModel Physical32 OpenCL
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Function %2
- %4 = OpTypeFunction %3
- %5 = OpFunction %3 None %4
- %6 = OpLabel
- %7 = OpVariable %3 Function
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpReturnValueIsVariableInLogical) {
- // It's invalid to return a pointer in a physical addressing model.
- std::string spirv = kOpCapabilitySetup + R"(
- OpMemoryModel Logical GLSL450
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Function %2
- %4 = OpTypeFunction %3
- %5 = OpFunction %3 None %4
- %6 = OpLabel
- %7 = OpVariable %3 Function
- OpReturnValue %7
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("OpReturnValue value's type <id> "
- "'3[%_ptr_Function_uint]' is a pointer, which is "
- "invalid in the Logical addressing model.")));
- }
- // With the VariablePointer Capability, the return value of a function is
- // allowed to be a pointer.
- TEST_P(ValidateIdWithMessage, OpReturnValueVarPtrGood) {
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv,
- "" /* Instructions to add to "main" */,
- true /* Add VariablePointers Capability?*/,
- true /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- // Without the VariablePointer Capability, the return value of a function is
- // *not* allowed to be a pointer.
- // Disabled since using OpSelect with pointers without VariablePointers will
- // fail LogicalsPass.
- TEST_P(ValidateIdWithMessage, DISABLED_OpReturnValueVarPtrBad) {
- std::ostringstream spirv;
- createVariablePointerSpirvProgram(&spirv,
- "" /* Instructions to add to "main" */,
- false /* Add VariablePointers Capability?*/,
- true /* Use Helper Function? */);
- CompileSuccessfully(spirv.str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpReturnValue value's type <id> '7' is a pointer, "
- "which is invalid in the Logical addressing model.")));
- }
- // TODO: enable when this bug is fixed:
- // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
- TEST_P(ValidateIdWithMessage, DISABLED_OpReturnValueIsFunction) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypeFunction %2
- %5 = OpFunction %2 None %3
- %6 = OpLabel
- OpReturnValue %5
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, UndefinedTypeId) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %s = OpTypeStruct %i32
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Operand '2[%2]' requires a previous definition")));
- }
- TEST_P(ValidateIdWithMessage, UndefinedIdScope) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %u32 = OpTypeInt 32 0
- %memsem = OpConstant %u32 0
- %void = OpTypeVoid
- %void_f = OpTypeFunction %void
- %f = OpFunction %void None %void_f
- %l = OpLabel
- OpMemoryBarrier %undef %memsem
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '7[%7]' has not been "
- "defined")));
- }
- TEST_P(ValidateIdWithMessage, UndefinedIdMemSem) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %u32 = OpTypeInt 32 0
- %scope = OpConstant %u32 0
- %void = OpTypeVoid
- %void_f = OpTypeFunction %void
- %f = OpFunction %void None %void_f
- %l = OpLabel
- OpMemoryBarrier %scope %undef
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '7[%7]' has not been "
- "defined")));
- }
- TEST_P(ValidateIdWithMessage,
- KernelOpEntryPointAndOpInBoundsPtrAccessChainGood) {
- std::string spirv = kOpenCLMemoryModel32 + R"(
- OpEntryPoint Kernel %2 "simple_kernel"
- OpSource OpenCL_C 200000
- OpDecorate %3 BuiltIn GlobalInvocationId
- OpDecorate %3 Constant
- OpDecorate %4 FuncParamAttr NoCapture
- OpDecorate %3 LinkageAttributes "__spirv_GlobalInvocationId" Import
- %5 = OpTypeInt 32 0
- %6 = OpTypeVector %5 3
- %7 = OpTypePointer UniformConstant %6
- %3 = OpVariable %7 UniformConstant
- %8 = OpTypeVoid
- %9 = OpTypeStruct %5
- %10 = OpTypePointer CrossWorkgroup %9
- %11 = OpTypeFunction %8 %10
- %12 = OpConstant %5 0
- %13 = OpTypePointer CrossWorkgroup %5
- %14 = OpConstant %5 42
- %2 = OpFunction %8 None %11
- %4 = OpFunctionParameter %10
- %15 = OpLabel
- %16 = OpLoad %6 %3 Aligned 1
- %17 = OpCompositeExtract %5 %16 0
- %18 = OpInBoundsPtrAccessChain %13 %4 %17 %12
- OpStore %18 %14 Aligned 4
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpPtrAccessChainGood) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- OpEntryPoint Kernel %2 "another_kernel"
- OpSource OpenCL_C 200000
- OpDecorate %3 BuiltIn GlobalInvocationId
- OpDecorate %3 Constant
- OpDecorate %4 FuncParamAttr NoCapture
- OpDecorate %3 LinkageAttributes "__spirv_GlobalInvocationId" Import
- %5 = OpTypeInt 64 0
- %6 = OpTypeVector %5 3
- %7 = OpTypePointer UniformConstant %6
- %3 = OpVariable %7 UniformConstant
- %8 = OpTypeVoid
- %9 = OpTypeInt 32 0
- %10 = OpTypeStruct %9
- %11 = OpTypePointer CrossWorkgroup %10
- %12 = OpTypeFunction %8 %11
- %13 = OpConstant %5 4294967295
- %14 = OpConstant %9 0
- %15 = OpTypePointer CrossWorkgroup %9
- %16 = OpConstant %9 42
- %2 = OpFunction %8 None %12
- %4 = OpFunctionParameter %11
- %17 = OpLabel
- %18 = OpLoad %6 %3 Aligned 1
- %19 = OpCompositeExtract %5 %18 0
- %20 = OpBitwiseAnd %5 %19 %13
- %21 = OpPtrAccessChain %15 %4 %20 %14
- OpStore %21 %16 Aligned 4
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, StgBufOpPtrAccessChainGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VariablePointersStorageBuffer
- OpExtension "SPV_KHR_variable_pointers"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %3 ""
- OpDecorate %ptr ArrayStride 8
- %int = OpTypeInt 32 0
- %int_2 = OpConstant %int 2
- %int_4 = OpConstant %int 4
- %struct = OpTypeStruct %int
- %array = OpTypeArray %struct %int_4
- %ptr = OpTypePointer StorageBuffer %array
- %var = OpVariable %ptr StorageBuffer
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpFunction %1 None %2
- %4 = OpLabel
- %5 = OpPtrAccessChain %ptr %var %int_2
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpLoadBitcastPointerGood) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypePointer UniformConstant %4
- %7 = OpVariable %5 UniformConstant
- %8 = OpTypeFunction %2
- %9 = OpFunction %2 None %8
- %10 = OpLabel
- %11 = OpBitcast %6 %7
- %12 = OpLoad %4 %11
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpLoadBitcastNonPointerBad) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer UniformConstant %3
- %6 = OpTypeFunction %2
- %7 = OpVariable %5 UniformConstant
- %8 = OpFunction %2 None %6
- %9 = OpLabel
- %10 = OpLoad %3 %7
- %11 = OpBitcast %4 %10
- %12 = OpLoad %3 %11
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpLoad type for pointer <id> '11[%11]' is not a pointer "
- "type.")));
- }
- TEST_P(ValidateIdWithMessage, OpStoreBitcastPointerGood) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer Function %3
- %6 = OpTypePointer Function %4
- %7 = OpTypeFunction %2
- %8 = OpConstant %3 42
- %9 = OpFunction %2 None %7
- %10 = OpLabel
- %11 = OpVariable %6 Function
- %12 = OpBitcast %5 %11
- OpStore %12 %8
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
- }
- TEST_P(ValidateIdWithMessage, OpStoreBitcastNonPointerBad) {
- std::string spirv = kOpenCLMemoryModel64 + R"(
- %2 = OpTypeVoid
- %3 = OpTypeInt 32 0
- %4 = OpTypeFloat 32
- %5 = OpTypePointer Function %4
- %6 = OpTypeFunction %2
- %7 = OpConstant %4 42
- %8 = OpFunction %2 None %6
- %9 = OpLabel
- %10 = OpVariable %5 Function
- %11 = OpBitcast %3 %7
- OpStore %11 %7
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "OpStore type for pointer <id> '11[%11]' is not a pointer "
- "type.")));
- }
- // Result <id> resulting from an instruction within a function may not be used
- // outside that function.
- TEST_P(ValidateIdWithMessage, ResultIdUsedOutsideOfFunctionBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeInt 32 0
- %4 = OpTypePointer Function %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- %7 = OpVariable %4 Function
- OpReturn
- OpFunctionEnd
- %8 = OpFunction %1 None %2
- %9 = OpLabel
- %10 = OpLoad %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '7[%7]' defined in block '6[%6]' does "
- "not dominate its use in block "
- "'9[%9]'")));
- }
- TEST_P(ValidateIdWithMessage, SpecIdTargetNotSpecializationConstant) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 SpecId 200
- %void = OpTypeVoid
- %2 = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %1 = OpConstant %int 3
- %main = OpFunction %void None %2
- %4 = OpLabel
- OpReturnValue %1
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("SpecId decoration on target <id> "
- "'1[%uint_3]' must be a scalar specialization "
- "constant")));
- }
- TEST_P(ValidateIdWithMessage, SpecIdTargetOpSpecConstantOpBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 SpecId 200
- %void = OpTypeVoid
- %2 = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %3 = OpConstant %int 1
- %4 = OpConstant %int 2
- %1 = OpSpecConstantOp %int IAdd %3 %4
- %main = OpFunction %void None %2
- %6 = OpLabel
- OpReturnValue %3
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("SpecId decoration on target <id> '1[%1]' "
- "must be a scalar specialization constant")));
- }
- TEST_P(ValidateIdWithMessage, SpecIdTargetOpSpecConstantCompositeBad) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %1 SpecId 200
- %void = OpTypeVoid
- %2 = OpTypeFunction %void
- %int = OpTypeInt 32 0
- %3 = OpConstant %int 1
- %1 = OpSpecConstantComposite %int
- %main = OpFunction %void None %2
- %4 = OpLabel
- OpReturnValue %3
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("SpecId decoration on target <id> '1[%1]' "
- "must be a scalar specialization constant")));
- }
- TEST_P(ValidateIdWithMessage, SpecIdTargetGood) {
- std::string spirv = kGLSL450MemoryModel + R"(
- OpDecorate %3 SpecId 200
- OpDecorate %4 SpecId 201
- OpDecorate %5 SpecId 202
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %int = OpTypeInt 32 0
- %bool = OpTypeBool
- %3 = OpSpecConstant %int 3
- %4 = OpSpecConstantTrue %bool
- %5 = OpSpecConstantFalse %bool
- %main = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState());
- }
- TEST_P(ValidateIdWithMessage, CorrectErrorForShuffle) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %v2float = OpTypeVector %float 2
- %void = OpTypeVoid
- %548 = OpTypeFunction %void
- %CS = OpFunction %void None %548
- %550 = OpLabel
- %6275 = OpUndef %v2float
- %6280 = OpUndef %v2float
- %6282 = OpVectorShuffle %v4float %6275 %6280 0 1 4 5
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv.c_str());
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "Component index 4 is out of bounds for combined (Vector1 + Vector2) "
- "size of 4.")));
- EXPECT_EQ(25, getErrorPosition().index);
- }
- TEST_P(ValidateIdWithMessage, VoidStructMember) {
- const std::string spirv = kGLSL450MemoryModel + R"(
- %void = OpTypeVoid
- %struct = OpTypeStruct %void
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Structures cannot contain a void type.")));
- }
- TEST_P(ValidateIdWithMessage, TypeFunctionBadUse) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypePointer Function %2
- %4 = OpFunction %1 None %2
- %5 = OpLabel
- OpReturn
- OpFunctionEnd)";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Invalid use of function type result id '2[%2]'.")));
- }
- TEST_P(ValidateIdWithMessage, BadTypeId) {
- std::string spirv = kGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpConstant %3 0
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- %7 = OpUndef %4
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '4[%float_0]' is not a type "
- "id")));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelLoadMakePointerVisibleGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 NonPrivatePointerKHR|MakePointerVisibleKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelLoadMakePointerVisibleMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 MakePointerVisibleKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("NonPrivatePointerKHR must be specified if "
- "MakePointerVisibleKHR is specified.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelLoadNonPrivatePointerBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Private %2
- %4 = OpVariable %3 Private
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelLoadMakePointerAvailableCannotBeUsed) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 2
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- %9 = OpLoad %2 %4 NonPrivatePointerKHR|MakePointerAvailableKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "MakePointerAvailableKHR cannot be used with OpLoad")));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelStoreMakePointerAvailableGood) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpVariable %3 Uniform
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelStoreMakePointerAvailableMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpVariable %3 Uniform
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 MakePointerAvailableKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("NonPrivatePointerKHR must be specified if "
- "MakePointerAvailableKHR is specified.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelStoreNonPrivatePointerBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Output %2
- %4 = OpVariable %3 Output
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelStoreMakePointerVisibleCannotBeUsed) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability VulkanMemoryModelKHR
- OpCapability Linkage
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Uniform %2
- %4 = OpVariable %3 Uniform
- %5 = OpTypeFunction %1
- %6 = OpConstant %2 5
- %7 = OpFunction %1 None %5
- %8 = OpLabel
- OpStore %4 %6 NonPrivatePointerKHR|MakePointerVisibleKHR %6
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "MakePointerVisibleKHR cannot be used with OpStore.")));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryAvailable) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelCopyMemoryAvailableAndVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR|MakePointerAvailableKHR|MakePointerVisibleKHR %7 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryAvailableMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("NonPrivatePointerKHR must be specified if "
- "MakePointerAvailableKHR is specified.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryVisibleMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("NonPrivatePointerKHR must be specified if "
- "MakePointerVisibleKHR is specified.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryAvailableBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Output %2
- %4 = OpVariable %3 Output
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemoryVisibleBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Input %2
- %6 = OpVariable %5 Input
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemory %4 %6 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes.")));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelCopyMemorySizedAvailable) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %9 = OpTypeFunction %1
- %12 = OpConstant %2 4
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 NonPrivatePointerKHR|MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage, VulkanMemoryModelCopyMemorySizedVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %12 = OpConstant %2 4
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 NonPrivatePointerKHR|MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedAvailableAndVisible) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %12 = OpConstant %2 4
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 NonPrivatePointerKHR|MakePointerAvailableKHR|MakePointerVisibleKHR %7 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedAvailableMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %12 = OpConstant %2 4
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 MakePointerAvailableKHR %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("NonPrivatePointerKHR must be specified if "
- "MakePointerAvailableKHR is specified.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedVisibleMissingNonPrivatePointer) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %12 = OpConstant %2 4
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 MakePointerVisibleKHR %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("NonPrivatePointerKHR must be specified if "
- "MakePointerVisibleKHR is specified.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedAvailableBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Output %2
- %4 = OpVariable %3 Output
- %5 = OpTypePointer Uniform %2
- %6 = OpVariable %5 Uniform
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %12 = OpConstant %2 4
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes.")));
- }
- TEST_P(ValidateIdWithMessage,
- VulkanMemoryModelCopyMemorySizedVisibleBadStorageClass) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability Linkage
- OpCapability Addresses
- OpCapability VulkanMemoryModelKHR
- OpExtension "SPV_KHR_vulkan_memory_model"
- OpMemoryModel Logical VulkanKHR
- %1 = OpTypeVoid
- %2 = OpTypeInt 32 0
- %3 = OpTypePointer Workgroup %2
- %4 = OpVariable %3 Workgroup
- %5 = OpTypePointer Input %2
- %6 = OpVariable %5 Input
- %7 = OpConstant %2 2
- %8 = OpConstant %2 5
- %12 = OpConstant %2 4
- %9 = OpTypeFunction %1
- %10 = OpFunction %1 None %9
- %11 = OpLabel
- OpCopyMemorySized %4 %6 %12 NonPrivatePointerKHR
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "NonPrivatePointerKHR requires a pointer in Uniform, "
- "Workgroup, CrossWorkgroup, Generic, Image or "
- "StorageBuffer storage classes.")));
- }
- TEST_P(ValidateIdWithMessage, IdDefInUnreachableBlock1) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpFunctionCall %3 %9
- OpUnreachable
- OpFunctionEnd
- %9 = OpFunction %3 None %4
- %10 = OpLabel
- OpReturnValue %8
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "ID '8[%8]' defined in block '7[%7]' does not dominate its "
- "use in block '10[%10]'\n %10 = OpLabel")));
- }
- TEST_P(ValidateIdWithMessage, IdDefInUnreachableBlock2) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpFunctionCall %3 %9
- OpUnreachable
- OpFunctionEnd
- %9 = OpFunction %3 None %4
- %10 = OpLabel
- OpReturnValue %8
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "ID '8[%8]' defined in block '7[%7]' does not dominate its "
- "use in block '10[%10]'\n %10 = OpLabel")));
- }
- TEST_P(ValidateIdWithMessage, IdDefInUnreachableBlock3) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpFunctionCall %3 %9
- OpReturn
- OpFunctionEnd
- %9 = OpFunction %3 None %4
- %10 = OpLabel
- OpReturnValue %8
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "ID '8[%8]' defined in block '7[%7]' does not dominate its "
- "use in block '10[%10]'\n %10 = OpLabel")));
- }
- TEST_P(ValidateIdWithMessage, IdDefInUnreachableBlock4) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpUndef %3
- %9 = OpCopyObject %3 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage, IdDefInUnreachableBlock5) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpReturn
- %7 = OpLabel
- %8 = OpUndef %3
- OpBranch %9
- %9 = OpLabel
- %10 = OpCopyObject %3 %8
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage, IdDefInUnreachableBlock6) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- OpBranch %7
- %8 = OpLabel
- %9 = OpUndef %3
- OpBranch %7
- %7 = OpLabel
- %10 = OpCopyObject %3 %9
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "ID '9[%9]' defined in block '8[%8]' does not dominate its "
- "use in block '7[%7]'\n %7 = OpLabel")));
- }
- TEST_P(ValidateIdWithMessage, ReachableDefUnreachableUse) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %1 = OpTypeVoid
- %2 = OpTypeFunction %1
- %3 = OpTypeFloat 32
- %4 = OpTypeFunction %3
- %5 = OpFunction %1 None %2
- %6 = OpLabel
- %7 = OpUndef %3
- OpReturn
- %8 = OpLabel
- %9 = OpCopyObject %3 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage, UnreachableDefUsedInPhi) {
- const std::string spirv = kNoKernelGLSL450MemoryModel + R"(
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %bool = OpTypeBool
- %6 = OpTypeFunction %float
- %1 = OpFunction %void None %3
- %7 = OpLabel
- %8 = OpUndef %bool
- OpSelectionMerge %9 None
- OpBranchConditional %8 %10 %9
- %10 = OpLabel
- %11 = OpUndef %float
- OpBranch %9
- %12 = OpLabel
- %13 = OpUndef %float
- OpUnreachable
- %9 = OpLabel
- %14 = OpPhi %float %11 %10 %13 %7
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message(
- "In OpPhi instruction '14[%14]', ID '13[%13]' definition does not "
- "dominate its parent '7[%7]'\n %14 = OpPhi %float %11 %10 %13 "
- "%7")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeForwardPointerNotAPointerType) {
- std::string spirv = R"(
- OpCapability GenericPointer
- OpCapability VariablePointersStorageBuffer
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginLowerLeft
- OpTypeForwardPointer %2 CrossWorkgroup
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %1 = OpFunction %2 DontInline %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Pointer type in OpTypeForwardPointer is not a pointer "
- "type.\n OpTypeForwardPointer %void CrossWorkgroup")));
- }
- TEST_P(ValidateIdWithMessage, OpTypeForwardPointerWrongStorageClass) {
- std::string spirv = R"(
- OpCapability GenericPointer
- OpCapability VariablePointersStorageBuffer
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginLowerLeft
- OpTypeForwardPointer %2 CrossWorkgroup
- %int = OpTypeInt 32 1
- %2 = OpTypePointer Function %int
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %1 = OpFunction %void None %3
- %4 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message(
- "Storage class in OpTypeForwardPointer does not match the "
- "pointer definition.\n OpTypeForwardPointer "
- "%_ptr_Function_int CrossWorkgroup")));
- }
- TEST_P(ValidateIdWithMessage, MissingForwardPointer) {
- const std::string spirv = R"(
- OpCapability Linkage
- OpCapability Shader
- OpMemoryModel Logical Simple
- %float = OpTypeFloat 32
- %_struct_9 = OpTypeStruct %float %_ptr_Uniform__struct_9
- %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
- %1278 = OpVariable %_ptr_Uniform__struct_9 Uniform
- )";
- CompileSuccessfully(spirv);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("Operand '3[%_ptr_Uniform__struct_2]' "
- "requires a previous definition")));
- }
- TEST_P(ValidateIdWithMessage, NVBindlessSamplerInStruct) {
- std::string spirv = R"(
- OpCapability Shader
- OpCapability BindlessTextureNV
- OpExtension "SPV_NV_bindless_texture"
- OpMemoryModel Logical GLSL450
- OpSamplerImageAddressingModeNV 64
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %8 = OpTypeSampledImage %7
- %9 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
- %10 = OpTypeSampler
- %UBO = OpTypeStruct %8 %9 %10
- %_ptr_Uniform_UBO = OpTypePointer Uniform %UBO
- %_ = OpVariable %_ptr_Uniform_UBO Uniform
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
- }
- TEST_P(ValidateIdWithMessage,
- OpExtInstWithForwardRefsKHRDisallowedNoForwardRef) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_non_semantic_info"
- OpExtension "SPV_KHR_relaxed_extended_instruction"
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %main_type = OpTypeFunction %void
- %4 = OpExtInstWithForwardRefsKHR %void %1 DebugInfoNone
- %main = OpFunction %void None %main_type
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_6);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr(make_message("Opcode OpExtInstWithForwardRefsKHR must have at "
- "least one forward declared ID.")));
- }
- TEST_P(ValidateIdWithMessage, OpExtInstNoForwardRef) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_non_semantic_info"
- OpExtension "SPV_KHR_relaxed_extended_instruction"
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- %void = OpTypeVoid
- %main_type = OpTypeFunction %void
- %4 = OpExtInst %void %1 DebugInfoNone
- %main = OpFunction %void None %main_type
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_6);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
- }
- TEST_P(ValidateIdWithMessage,
- OpExtInstWithForwardRefsKHRAllowedForwardReferenceInNonSemantic) {
- std::string spirv = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_non_semantic_info"
- OpExtension "SPV_KHR_relaxed_extended_instruction"
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %2 "main"
- OpExecutionMode %2 LocalSize 1 1 1
- %3 = OpString "sample"
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %7 = OpTypeFunction %void
- %8 = OpExtInst %void %1 DebugSource %3 %3
- %9 = OpExtInst %void %1 DebugCompilationUnit %uint_0 %uint_0 %8 %uint_0
- %10 = OpExtInstWithForwardRefsKHR %void %1 DebugTypeFunction %uint_0 %11
- %12 = OpExtInstWithForwardRefsKHR %void %1 DebugFunction %3 %10 %8 %uint_0 %uint_0 %11 %3 %uint_0 %uint_0
- %11 = OpExtInst %void %1 DebugTypeComposite %3 %uint_0 %8 %uint_0 %uint_0 %9 %3 %uint_0 %uint_0 %12
- %2 = OpFunction %void None %7
- %13 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_6);
- EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
- }
- TEST_P(ValidateIdWithMessage, OpExtInstNoForwardDeclAllowed) {
- std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %2 "main"
- OpExecutionMode %2 LocalSize 1 1 1
- %3 = OpString "sample"
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %7 = OpTypeFunction %void
- %8 = OpExtInst %void %1 DebugSource %3 %3
- %9 = OpExtInst %void %1 DebugCompilationUnit %uint_0 %uint_0 %8 %uint_0
- %10 = OpExtInst %void %1 DebugTypeFunction %uint_0 %11
- %12 = OpExtInst %void %1 DebugFunction %3 %10 %8 %uint_0 %uint_0 %11 %3 %uint_0 %uint_0
- %11 = OpExtInst %void %1 DebugTypeComposite %3 %uint_0 %8 %uint_0 %uint_0 %9 %3 %uint_0 %uint_0 %12
- %2 = OpFunction %void None %7
- %13 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_6);
- EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr(make_message("ID '11[%11]' has not been defined")));
- }
- INSTANTIATE_TEST_SUITE_P(, ValidateIdWithMessage, ::testing::Bool());
- } // namespace
- } // namespace val
- } // namespace spvtools
|